예제 #1
0
        /// <summary>Возвращает информацию по ячейке</summary>
        void GetCell(Point pos, out MFWorker worker, out DateTime?t)
        {
            worker = null;
            t      = null;
            if (rectGrid == Rect.Empty)
            {
                return;
            }

            var workers = MFPlannerManager.GetWorkers(IsShowEndWorkWokers);
            var index   = 0;

            for (; index < workers.Count; index++)
            {
                var rectTmp = new Rect(0, rectGrid.Y + rowHeight * index, rectGrid.Right, rowHeight);
                if (rectTmp.Contains(pos))
                {
                    worker = workers[index];
                }
            }

            var d = TimeStart;

            var cellWidth = rectGrid.Width / (TimeEnd - TimeStart).TotalDays;

            index = 0;
            while (d < TimeEnd)
            {
                var rectTmp = new Rect(rectGrid.X + index * cellWidth, rectGrid.Top - rowMonthAndDay, cellWidth, rectGrid.Height + rowMonthAndDay);
                if (rectTmp.Contains(pos))
                {
                    t = d;
                    return;
                }

                d = d.AddDays(1);
                index++;
            }
        }
 // Изменились работники
 void MFPlannerManager_WorkersChanged(object sender, EventArgs e)
 {
     listWorkers.ItemsSource = null;
     listWorkers.ItemsSource = MFPlannerManager.GetWorkers(true);
 }
예제 #3
0
        // Размеры
        protected override Size MeasureOverride(Size constraint)
        {
            var workers = MFPlannerManager.GetWorkers(IsShowEndWorkWokers);

            return(new Size(constraint.Width, workers.Count * rowHeight + rowMonthAndDay * 3));
        }
예제 #4
0
        void Rendraw(DrawingContext dc)
        {
            if (double.IsNaN(ActualWidth) || double.IsNaN(ActualHeight))
            {
                return;
            }

            var t0 = DateTime.Now;

            FormattedText txt      = null;
            int           index    = 0;
            var           posMouse = Mouse.GetPosition(this);

            rectGrid = new Rect(0, (rowMonthAndDay * 2 + 3), ActualWidth, ActualHeight - (rowMonthAndDay * 2 + 3));
            Rect rectTmp = Rect.Empty;

            // фон
            dc.DrawRectangle(Brushes.White, penGrid, new Rect(0, 0, ActualWidth, ActualHeight));

            #region  рисуем шкалу человеков
            var    workers        = MFPlannerManager.GetWorkers(IsShowEndWorkWokers);
            double colWorkerWidth = 100;
            for (index = 0; index < workers.Count; index++)
            {
                var name = string.Format("{0} {1} [{2}]", workers[index].SecondName, workers[index].Name, workers[index].Post);

                // Если уволенный
                if (workers[index].EndWorkTime.HasValue)
                {
                    dc.DrawRectangle(brushEndWork, null, new Rect(0, rectGrid.Y + rowHeight * index, rectGrid.Right, rowHeight));
                    name += string.Format("\n(уволен)");
                }

                txt = new FormattedText(name, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, 14, Brushes.Black);

                if (colWorkerWidth < txt.Width + 10)
                {
                    colWorkerWidth = txt.Width + 10;
                }

                var nameHeight = txt.Height + 2;

                // фамиля + имя
                dc.DrawText(txt, new Point(5, rectGrid.Y + rowHeight * index + (rowHeight - nameHeight) / 2));

                //name = string.Format("пост: {0}", workers[index].Post);
                //txt = new FormattedText(name, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, 11, Brushes.Gray);
                //dc.DrawText(txt, new Point((colWorkerWidth - txt.Width) / 2, rectGrid.Y + rowHeight * index + (rowHeight - nameHeight) / 2 + nameHeight));

                dc.DrawLine(penGrid, new Point(0, rectGrid.Y + rowHeight * index), new Point(rectGrid.Right, rectGrid.Y + rowHeight * index));

                // Выделение для мыши
                rectTmp = new Rect(0, rectGrid.Y + rowHeight * index, rectGrid.Right, rowHeight);
                if (rectTmp.Contains(posMouse))
                {
                    dc.DrawRectangle(brushSelection, null, rectTmp);
                }
            }

            dc.DrawLine(penGrid, new Point(0, rectGrid.Y + rowHeight * (index)), new Point(rectGrid.Right, rectGrid.Y + rowHeight * (index)));
            #endregion

            // максимальное имя
            rectGrid.X      = colWorkerWidth;
            rectGrid.Width -= colWorkerWidth;
            rectGrid.Height = 50 * workers.Count;

            var cellWidth = rectGrid.Width / (TimeEnd - TimeStart).TotalDays;

            #region  исуем шкалу дат
            DateTime?datePrev = null;
            var      d        = TimeStart;
            var      now      = DateTime.Now.Date;

            index = 0;
            while (d < TimeEnd)
            {
                // если у нас выходные
                if (d.DayOfWeek == DayOfWeek.Saturday || d.DayOfWeek == DayOfWeek.Sunday)
                {
                    rectTmp = new Rect(rectGrid.X + index * cellWidth, rectGrid.Top - rowMonthAndDay, cellWidth, rectGrid.Height + rowMonthAndDay);
                    dc.DrawRectangle(brushSaturdaySunday, null, rectTmp);
                }

                // текущий день
                if (d.Date == now)
                {
                    rectTmp = new Rect(rectGrid.X + index * cellWidth, rectGrid.Top - rowMonthAndDay, cellWidth, rectGrid.Height + rowMonthAndDay);
                    dc.DrawRectangle(brushNow, null, rectTmp);
                }

                // месяц изменился полная линия
                if (!datePrev.HasValue || (datePrev.Value.Month != d.Month))
                {
                    txt = new FormattedText(d.ToString("MMMM"), CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, 15, Brushes.Black);
                    dc.DrawText(txt, new Point(rectGrid.X + index * cellWidth + 5, 2));

                    dc.DrawLine(penGrid, new Point(rectGrid.X + index * cellWidth, 0), new Point(rectGrid.X + index * cellWidth, rectGrid.Bottom));
                }
                else // обычная линия
                {
                    dc.DrawLine(penGrid, new Point(rectGrid.X + index * cellWidth, rectGrid.Y - rowMonthAndDay), new Point(rectGrid.X + index * cellWidth, rectGrid.Bottom));
                }

                // рисуем день
                txt = new FormattedText(d.ToString("dd"), CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, 11, Brushes.Black);
                if (cellWidth >= txt.Width)
                {
                    dc.DrawText(txt, new Point(rectGrid.X + index * cellWidth + (cellWidth - txt.Width) / 2, rowMonthAndDay + 6));
                }



                // Выделение для мыши
                rectTmp = new Rect(rectGrid.X + index * cellWidth, rectGrid.Top - rowMonthAndDay, cellWidth, rectGrid.Height + rowMonthAndDay);
                if (rectTmp.Contains(posMouse))
                {
                    dc.DrawRectangle(brushSelection, null, rectTmp);

                    // отрисовываем дату шкалы
                    txt = new FormattedText(d.ToString("dd MMMM yyyy"), CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, 15, Brushes.Black);

                    rectTmp = new Rect(rectGrid.X + index * cellWidth, rectGrid.Bottom, txt.Width + 10, rowMonthAndDay);
                    dc.DrawRectangle(brushSelection, null, rectTmp);

                    dc.DrawText(txt, new Point(rectTmp.Left + 5, rectTmp.Top));
                }

                datePrev = d;
                d        = d.AddDays(1);
                index++;
            }

            // Горизонтальная линия
            // дата
            dc.DrawLine(penGrid, new Point(rectGrid.Left, rowMonthAndDay + 3), new Point(rectGrid.Right, rowMonthAndDay + 3));
            //dc.DrawLine(penGrid, new Point(0, rowMonthAndDay * 2 + 3), new Point(rect.Right, rowMonthAndDay * 2 + 3));
            #endregion

            // Добавляем проекты
            if (isDirty)
            {
                var dictionary = new Dictionary <int, List <ActionTemp> >();
                List <MFPlannerAction> actions = MFPlannerManager.GetActions();
                foreach (MFPlannerAction action in actions)
                {
                    if (!dictionary.ContainsKey(action.WorkerId))
                    {
                        dictionary[action.WorkerId] = new List <ActionTemp>();
                    }

                    //if ((a.TimeBegin.Date >= TimeStart && a.TimeBegin.Date <= TimeEnd)
                    //    || (a.TimeEnd.Date >= TimeStart && a.TimeEnd.Date <= TimeEnd))
                    {
                        for (int indexWorker = 0; indexWorker < workers.Count; indexWorker++)
                        {
                            if (workers[indexWorker].Id == action.WorkerId)
                            {
                                double sIndex = (int)(action.TimeBegin.Date - TimeStart).TotalDays,
                                       eIndex = (int)(action.TimeEnd.Date - TimeStart).TotalDays;

                                double x = Math.Max(rectGrid.X, rectGrid.X + sIndex * cellWidth),
                                       w = (eIndex - Math.Max(0, sIndex) + 1) * cellWidth;
                                if (w > 0 && x < rectGrid.Right)
                                {
                                    rectTmp = new Rect(x, rectGrid.Y + rowHeight * indexWorker, w, rowHeight);
                                    rectTmp.Inflate(0, -1);
                                }
                                else
                                {
                                    rectTmp = Rect.Empty;
                                }

                                dictionary[action.WorkerId].Add(new ActionTemp {
                                    Action = action, Rect = rectTmp
                                });
                            }
                        }
                    }
                }

                // выравниваем
                foreach (var kv in dictionary)
                {
                    foreach (var a in kv.Value)
                    {
                        var intersectItems = kv.Value.Where(x => x != a && x.Rect.IntersectsWith(a.Rect) && x.Rect != Rect.Empty);
                        rectTmp = a.Rect;
                        double y     = rectTmp.Y,
                               count = intersectItems.Count();
                        if (count > 0)
                        {
                            rectTmp.Height = rectTmp.Height / (count + 1);
                            rectTmp.Y      = y;

                            y     += rectTmp.Height + 0.5;
                            a.Rect = rectTmp;
                        }

                        foreach (var item in intersectItems)
                        {
                            rectTmp        = item.Rect;
                            rectTmp.Height = rectTmp.Height / (count + 1);
                            rectTmp.Y      = y;

                            item.Rect = rectTmp;
                            y        += rectTmp.Height + 0.5;
                        }
                    }
                }

                foreach (var v in dictionary)
                {
                    // Анализируем положения
                    foreach (var a in v.Value)
                    {
                        MFPlannerProjectControl cProject = null;

                        if (!controlsCache.ContainsKey(a.Action.Id))
                        {
                            cProject = new MFPlannerProjectControl {
                                Tag = a.Action, Width = a.Rect.Width, Height = a.Rect.Height
                            };
                            cProject.InitContextMenu();

                            controlsCache[a.Action.Id] = cProject;
                            Children.Add(cProject);
                        }
                        else
                        {
                            cProject = controlsCache[a.Action.Id];
                        }

                        // видимость
                        //cProject.Visibility = rectGrid.IntersectsWith(a.Rect) ? Visibility.Visible : Visibility.Collapsed;
                        if (a.Rect == Rect.Empty)
                        {
                            cProject.Visibility = Visibility.Collapsed;
                            continue;
                        }

                        cProject.Visibility = Visibility.Visible;

                        var h = a.Rect.Height;
                        //// уменьшаем
                        //var count = v.Value.Count(x => x != a && x.Rect.IntersectsWith(a.Rect));
                        //if (count >= 1)
                        //{
                        //    h = h / (count + 1);
                        //}

                        cProject.Width  = a.Rect.Width;
                        cProject.Height = h;
                        Canvas.SetLeft(cProject, a.Rect.Left);
                        Canvas.SetTop(cProject, a.Rect.Top);
                        cProject.InvalidateVisual();
                    }
                }


                isDirty = false;
            }

            //var res = (DateTime.Now - t0).TotalMilliseconds;
            //txt = new FormattedText(res.ToString(), CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, 15, Brushes.Black);
            //dc.DrawText(txt, new Point(0, 0));
        }