/// <summary> /// Draw stop element which has specific color that is passed a parameter. /// </summary> /// <param name="color">Color.</param> /// <param name="context">Context.</param> /// <remarks> /// This methods is used when it is necessary to draw stop without any stop specifics. Just colored /// rectangle. /// </remarks> public static void DrawStop(System.Drawing.Color color, GanttItemElementDrawingContext context) { Color wpfColor = Color.FromRgb(color.R, color.G, color.B); SolidColorBrush brush = new SolidColorBrush(wpfColor); _DrawRectangle(brush, context); }
/// <summary> /// Draws transparent element with container's width in default. If element is dragged over highlights Time windows of dregged order. /// </summary> /// <param name="context">Drawing context.</param> public void Draw(GanttItemElementDrawingContext context) { Rect elementSize = new Rect(context.DrawingArea.X, context.DrawingArea.Top, context.DrawingArea.Width, context.DrawingArea.Height); SolidColorBrush fillBrush = new SolidColorBrush(Colors.Transparent); Pen drawPen = GanttControlHelper.GetPen(); // Draw element. context.DrawingContext.DrawRectangle(fillBrush, drawPen, elementSize); // Draw dragged over element. if (context.DrawDraggedOver) { Debug.Assert(ParentGanttItem.Tag != null); Brush draggedOverBrush = GanttControlHelper.GetEmptyElementDragOverFillBrush(((Route)ParentGanttItem.Tag).Color); Pen pen = new Pen(fillBrush, 0); pen.Freeze(); // Define collection of highlighted rectangles. Collection <Rect> highlightedRects = _GetHighlightedRects(context); if (highlightedRects == null) { return; } // Draw dragged over areas. foreach (Rect rect in highlightedRects) { context.DrawingContext.DrawRoundedRectangle(draggedOverBrush, pen, rect, ROUND_RADIUS, ROUND_RADIUS); } } }
/// <summary> /// Defines brush to draw drivetime element. /// </summary> /// <param name="context">Drawing context.</param> /// <returns></returns> private Brush _GetFillBrush(GanttItemElementDrawingContext context) { Debug.Assert(_stop != null); Debug.Assert(_route != null); Debug.Assert(context != null); // Define selected color. if (context.DrawSelected) { return(GanttControlHelper.GetSelectedBrush()); } // Define dragged over color. if (context.DrawDraggedOver) { return(GanttControlHelper.GetDragOverBrush()); } // Define locked color. if (_stop.IsLocked || _route.IsLocked) { return(GanttControlHelper.GetLockedBrush(_route.Color)); } // If stop is Order, not locked, not selected and not dragged over - return normal fill color. return(GanttControlHelper.GetFillBrush(_route.Color)); }
/// <summary> /// Defines brush to draw stop element. /// </summary> /// <param name="stop">Stop.</param> /// <param name="context">Drawing context.</param> /// <returns></returns> private static Brush _GetFillBrush(StopInfo stopInfo, GanttItemElementDrawingContext context) { Debug.Assert(context != null); // Define selected color. if (context.DrawSelected) { return(GanttControlHelper.GetSelectedBrush()); } // Define location color. if (stopInfo.Stop.StopType == StopType.Location) { return(GanttControlHelper.GetLocationBrush()); } // Define Break color. if (stopInfo.Stop.StopType == StopType.Lunch) { return(GanttControlHelper.GetBreakBrush()); } // Define locked color. if (stopInfo.Stop.IsLocked || (stopInfo.Route != null && stopInfo.Route.IsLocked)) { return(GanttControlHelper.GetLockedBrush(stopInfo.Route.Color)); } // If stop is Order, not locked, not selected and not dragged over - return normal fill color. return(GanttControlHelper.GetFillBrush(stopInfo.Route.Color)); }
/// <summary> /// Goes through all the visuals and draw ones which require redraw. /// </summary> private void _DrawVisuals() { foreach (GanttItemElementDrawingVisual visual in _children) { if (visual.RedrawRequired) { GanttItemElementDrawingContext context = new GanttItemElementDrawingContext(); // Calculate drawing rect for the element. context.DrawingArea = _GetChildDrawingArea(visual.GanttItemElement, context); // Set selected if necessary. context.DrawSelected = (_selectedElements.ContainsValue(visual.GanttItemElement)); // Set dragged over if necessay. context.DrawDraggedOver = (_draggedOverVisual != null && _draggedOverVisual == visual); // Set glyph panel. context.GlyphPanel = _glyphPanel; // Set dragged data. if (context.DrawDraggedOver) { context.DraggedData = _draggedData; } visual.Draw(context); } } }
/// <summary> /// Draws dragged over glyph. /// </summary> /// <param name="stop">Bound stop.</param> /// <param name="context">DrawingContext.</param> private void _DrawDraggedOverGlyph(Stop stop, GanttItemElementDrawingContext context) { if (context.GlyphPanel == null) { return; } Rect elementRect = StopDrawer.GetElementRect(context); bool isStopFirst = false; if (stop.SequenceNumber == 1) { isStopFirst = true; } if (context.DrawDraggedOver && !context.DrawSelected && !_route.IsLocked) { context.GlyphPanel.AddGlyph(this, new StopDragOverGlyph(elementRect, isStopFirst)); } else { context.GlyphPanel.RemoveGlyphByKey(this); } }
/// <summary> /// Draws internal gradient effect. /// </summary> /// <param name="context">Drawing context.</param> private static void _DrawGradientEffect(GanttItemElementDrawingContext context) { Rect elementRect = _GetGradientRect(context); Brush gradientBrush = GanttControlHelper.GetGradientEffectBrush(); Pen drawPen = GanttControlHelper.GetPen(); context.DrawingContext.DrawRoundedRectangle(gradientBrush, drawPen, elementRect, ROUND_RADIUS, ROUND_RADIUS); }
/// <summary> /// Returns element drawing rectangle. /// </summary> /// <param name="context">Context.</param> /// <returns>Drawing rectangle.</returns> private static Rect _GetElementRect(GanttItemElementDrawingContext context) { // Add gap bentween gantt rows. double yPos = context.DrawingArea.Top + GAP_SIZE; double height = context.DrawingArea.Height - GAP_SIZE; // Define element size. return(new Rect(context.DrawingArea.X, yPos, context.DrawingArea.Width, height)); }
/// <summary> /// Returns element gradient drawing rectangle. /// </summary> /// <param name="context">Context.</param> /// <returns>Drawing rectangle.</returns> private static Rect _GetGradientRect(GanttItemElementDrawingContext context) { // Add gap bentween base elemnt and gradient. double xPos = context.DrawingArea.X + GRADIENT_GAP_SIZE; double yPos = context.DrawingArea.Top + GAP_SIZE + GRADIENT_GAP_SIZE; double height = context.DrawingArea.Height - GAP_SIZE - GRADIENT_GAP_SIZE * 2; double width = Math.Max(context.DrawingArea.Width - GRADIENT_GAP_SIZE * 2, 0); // Define gradient size. return(new Rect(xPos, yPos, width, height)); }
/// <summary> /// Method draws element. /// </summary> /// <param name="context">Drawing context where element shoul be drawn.</param> public void Draw(GanttItemElementDrawingContext context) { Debug.Assert(_route != null); StopDrawer.StopInfo stopInfo = new StopDrawer.StopInfo(); stopInfo.Stop = _stop; stopInfo.Route = _route; StopDrawer.DrawStop(stopInfo, context); // Draw glyph over stop element. _DrawDraggedOverGlyph(_stop, context); }
/// <summary> /// Returns element shadow drawing rectangle. /// </summary> /// <param name="context">Context.</param> /// <returns>Drawing rectangle.</returns> private static Rect _GetShadowRect(GanttItemElementDrawingContext context) { double gapSize = Math.Min(context.DrawingArea.Width, GAP_SIZE); // Add gap bentween base elemnt and shadow. double xPos = context.DrawingArea.X + gapSize; double yPos = context.DrawingArea.Top + gapSize + gapSize / 2; double height = context.DrawingArea.Height - gapSize; double width = Math.Max(context.DrawingArea.Width - gapSize / 2, 0); // Define shadow size. return(new Rect(xPos, yPos, width, height)); }
/// <summary> /// Draw visual content. /// </summary> /// <param name="drawingContext">Drawing context.</param> public void Draw(GanttItemElementDrawingContext drawingContext) { // Open drawing context. drawingContext.DrawingContext = this.RenderOpen(); GanttItemElement.Draw(drawingContext); // Close drawing context to null. drawingContext.DrawingContext.Close(); drawingContext.DrawingContext = null; RedrawRequired = false; }
/// <summary> /// Draws gantt item element. /// </summary> /// <param name="fillBrush">Filling brush.</param> /// <param name="context">Context.</param> private static void _DrawRectangle(Brush fillBrush, GanttItemElementDrawingContext context) { // Draw shadow effect. _DrawShadowEffect(context); Rect elementRect = _GetElementRect(context); Pen drawPen = GanttControlHelper.GetPen(); // Draw rectangle. context.DrawingContext.DrawRoundedRectangle(fillBrush, drawPen, elementRect, ROUND_RADIUS, ROUND_RADIUS); // Draw top gradient effect. _DrawGradientEffect(context); }
/// <summary> /// Returns collection of rectangles which should be highlighted. /// </summary> /// <param name="context">Drawing context.</param> /// <returns>Collection of rectangles.</returns> private Collection <Rect> _GetHighlightedRects(GanttItemElementDrawingContext context) { DragAndDropHelper helper = new DragAndDropHelper(); // Define collection of dragged orders. Collection <Order> orders = helper.GetDraggingOrders(context.DraggedData); // If more than one order is dragged - we don't need to highlight anything. Just return. if (orders.Count > 1) { return(null); } // Define default values for dates. DateTime startTime = DateTime.MinValue; DateTime endTime = DateTime.MaxValue; // Create result collection. Collection <Rect> rectResults = new Collection <Rect>(); Order order = orders[0]; Debug.Assert(order != null); // If both indows are wideopen - define wideopen time span - from MinDate to MaxDate. if (order.TimeWindow.IsWideOpen && order.TimeWindow2.IsWideOpen) { rectResults.Add(new Rect(context.DrawingArea.X, context.DrawingArea.Top, context.DrawingArea.Width, context.DrawingArea.Height + ANTI_ALIASING_GAP)); } // If first time window is not wideopen - define first time span. if (!order.TimeWindow.IsWideOpen) { startTime = new DateTime(order.TimeWindow.EffectiveFrom.Ticks); endTime = new DateTime(order.TimeWindow.EffectiveTo.Ticks); rectResults.Add(_GetRect(startTime, endTime, context)); } // If second time window is not wideopen - define second time span. if (!order.TimeWindow2.IsWideOpen) { startTime = new DateTime(order.TimeWindow2.EffectiveFrom.Ticks); endTime = new DateTime(order.TimeWindow2.EffectiveTo.Ticks); rectResults.Add(_GetRect(startTime, endTime, context)); } return(rectResults); }
/// <summary> /// Returns rect area by input parameters. /// </summary> /// <param name="startTime">Start area time.</param> /// <param name="endTime">End area time.</param> /// <param name="context">Drawing context.</param> /// <returns>Rect area.</returns> private Rect _GetRect(DateTime startTime, DateTime endTime, GanttItemElementDrawingContext context) { // Define count of pixels in minimal time span. double pixelsPerTick = context.DrawingArea.Width / (context.EndTime.TimeOfDay - context.StartTime.TimeOfDay).Ticks; // Define vertical dimensions. double yPos = context.DrawingArea.Top; double height = context.DrawingArea.Height; // Define horisontal dimensions. double xPos = (startTime.TimeOfDay - context.StartTime.TimeOfDay).Ticks * pixelsPerTick; double width = Math.Abs((endTime.TimeOfDay - startTime.TimeOfDay).Ticks * pixelsPerTick); // Return element size. return(new Rect(xPos, yPos, width, height + ANTI_ALIASING_GAP)); }
public void Draw(GanttItemElementDrawingContext context) { Debug.Assert(_stop != null); Debug.Assert(_route != null); // Define element size. double yPos = context.DrawingArea.Top + context.DrawingArea.Height / HEIGHT_INDEX; double height = context.DrawingArea.Height / HEIGHT_INDEX; Rect elementSize = new Rect(context.DrawingArea.X, yPos, context.DrawingArea.Width, height); Brush fillBrush = _GetFillBrush(context); Pen drawPen = GanttControlHelper.GetPen(); // Draw element. context.DrawingContext.DrawRoundedRectangle(fillBrush, drawPen, elementSize, ROUND_RADIUS, ROUND_RADIUS); }
/// <summary> /// Calculates drawing area for necessary visual children. /// </summary> /// <param name="element">Element for which bounds should be calculated.</param> /// <returns>New drawing area in relative coordinates.</returns> private Rect _GetChildDrawingArea(IGanttItemElement element, GanttItemElementDrawingContext context) { Debug.Assert(element != null); Debug.Assert(element.ParentGanttItem != null); // Define Y position of element. double yPos = _ganttItems.IndexOf(element.ParentGanttItem) * _rowHeight; // Copy start and end time from element to context. context.StartTime = element.StartTime; context.EndTime = element.EndTime; // If elemnts start time or end time is out of if (element.StartTime < _startTime) { context.StartTime = _startTime; } if (element.EndTime > _endTime) { context.EndTime = _endTime; } // Define element duration in time units. TimeSpan elementDuration = context.EndTime - context.StartTime; // Define element shift from left container border. We are always make a gap with width = 1 for correctly show elements styles. double xPos = Math.Max(1, (context.StartTime - _startTime).Ticks * _pixelsPerTick); // Define element duration in pixels. double elementWidth = Math.Max(0, Math.Abs(elementDuration.Ticks) * _pixelsPerTick); if (elementWidth == 0) { elementWidth = DEFAULT_ELEMENT_WIDTH; } // Define element height - it's the same for all elements and equals row height. double elementHeight = _rowHeight; return(new Rect(xPos, yPos, elementWidth, elementHeight)); }
/// <summary> /// Draws stop. /// </summary> /// <param name="stopInfo">Information about stop. Used for optimizing performance.</param> /// <param name="context">DrawingContext.</param> /// <remarks> /// Getting some relation properties (like Route, AssociatedObject) from stop takes some time /// due to the data layer implementation specifics. To improve perofmrance on rendering of /// large amount of stops use this method passing cached value of stop's properties. /// </remarks> public static void DrawStop(StopInfo stopInfo, GanttItemElementDrawingContext context) { Debug.Assert(stopInfo.Stop != null); Debug.Assert(stopInfo.Route != null); Debug.Assert(context != null); Brush fillBrush = _GetFillBrush(stopInfo, context); // Draw element. _DrawRectangle(fillBrush, context); // Draw violated icon. if (stopInfo.Stop.IsViolated) { Rect elementRect = _GetElementRect(context); Rect violatedIconRect = new Rect(elementRect.Left + GAP_SIZE, elementRect.Top + GAP_SIZE, ICON_SIZE, ICON_SIZE); violatedIconRect.Width = (violatedIconRect.Width > elementRect.Width) ? elementRect.Width : violatedIconRect.Width; ImageBrush brush = GanttControlHelper.GetViolatedBrush(); context.DrawingContext.DrawImage(brush.ImageSource, violatedIconRect); } }
/// <summary> /// Returns element gradient drawing rectangle. /// </summary> /// <param name="context">Context.</param> /// <returns>Drawing rectangle.</returns> private static Rect _GetGradientRect(GanttItemElementDrawingContext context) { // Add gap bentween base elemnt and gradient. double xPos = context.DrawingArea.X + GRADIENT_GAP_SIZE; double yPos = context.DrawingArea.Top + GAP_SIZE + GRADIENT_GAP_SIZE; double height = context.DrawingArea.Height - GAP_SIZE - GRADIENT_GAP_SIZE*2; double width = Math.Max(context.DrawingArea.Width - GRADIENT_GAP_SIZE*2, 0); // Define gradient size. return new Rect(xPos, yPos, width, height); }
/// <summary> /// Defines brush to draw stop element. /// </summary> /// <param name="stop">Stop.</param> /// <param name="context">Drawing context.</param> /// <returns></returns> private static Brush _GetFillBrush(StopInfo stopInfo, GanttItemElementDrawingContext context) { Debug.Assert(context != null); // Define selected color. if (context.DrawSelected) return GanttControlHelper.GetSelectedBrush(); // Define location color. if (stopInfo.Stop.StopType == StopType.Location) return GanttControlHelper.GetLocationBrush(); // Define Break color. if (stopInfo.Stop.StopType == StopType.Lunch) return GanttControlHelper.GetBreakBrush(); // Define locked color. if (stopInfo.Stop.IsLocked || (stopInfo.Route != null && stopInfo.Route.IsLocked)) return GanttControlHelper.GetLockedBrush(stopInfo.Route.Color); // If stop is Order, not locked, not selected and not dragged over - return normal fill color. return GanttControlHelper.GetFillBrush(stopInfo.Route.Color); }
/// <summary> /// Goes through all the visuals and draw ones which require redraw. /// </summary> private void _DrawVisuals() { foreach (GanttItemElementDrawingVisual visual in _children) { if (visual.RedrawRequired) { GanttItemElementDrawingContext context = new GanttItemElementDrawingContext(); // Calculate drawing rect for the element. context.DrawingArea = _GetChildDrawingArea(visual.GanttItemElement, context); // Set selected if necessary. context.DrawSelected = (_selectedElements.ContainsValue(visual.GanttItemElement)); // Set dragged over if necessay. context.DrawDraggedOver = (_draggedOverVisual != null && _draggedOverVisual == visual); // Set glyph panel. context.GlyphPanel = _glyphPanel; // Set dragged data. if (context.DrawDraggedOver) context.DraggedData = _draggedData; visual.Draw(context); } } }
/// <summary> /// Returns elemnet rect. /// </summary> /// <param name="context">Drawing context.</param> /// <returns>Element's rect bounds.</returns> public static Rect GetElementRect(GanttItemElementDrawingContext context) { return _GetElementRect(context); }
/// <summary> /// Returns elemnet rect. /// </summary> /// <param name="context">Drawing context.</param> /// <returns>Element's rect bounds.</returns> public static Rect GetElementRect(GanttItemElementDrawingContext context) { return(_GetElementRect(context)); }
/// <summary> /// Calculates drawing area for necessary visual children. /// </summary> /// <param name="element">Element for which bounds should be calculated.</param> /// <returns>New drawing area in relative coordinates.</returns> private Rect _GetChildDrawingArea(IGanttItemElement element, GanttItemElementDrawingContext context) { Debug.Assert(element != null); Debug.Assert(element.ParentGanttItem != null); // Define Y position of element. double yPos = _ganttItems.IndexOf(element.ParentGanttItem) * _rowHeight; // Copy start and end time from element to context. context.StartTime = element.StartTime; context.EndTime = element.EndTime; // If elemnts start time or end time is out of if (element.StartTime < _startTime) context.StartTime = _startTime; if (element.EndTime > _endTime) context.EndTime = _endTime; // Define element duration in time units. TimeSpan elementDuration = context.EndTime - context.StartTime; // Define element shift from left container border. We are always make a gap with width = 1 for correctly show elements styles. double xPos = Math.Max(1, (context.StartTime - _startTime).Ticks * _pixelsPerTick); // Define element duration in pixels. double elementWidth = Math.Max(0, Math.Abs(elementDuration.Ticks) * _pixelsPerTick); if (elementWidth == 0) elementWidth = DEFAULT_ELEMENT_WIDTH; // Define element height - it's the same for all elements and equals row height. double elementHeight = _rowHeight; return new Rect(xPos, yPos, elementWidth, elementHeight); }
/// <summary> /// Draws drop shadow effect. /// </summary> /// <param name="context">Drawing context.</param> private static void _DrawShadowEffect(GanttItemElementDrawingContext context) { Rect elementRect = _GetShadowRect(context); Brush effectBrush = GanttControlHelper.GetShadowEffectBrush(); Pen drawPen = GanttControlHelper.GetPen(); context.DrawingContext.DrawRoundedRectangle(effectBrush, drawPen, elementRect, ROUND_RADIUS, ROUND_RADIUS); }
/// <summary> /// Returns element shadow drawing rectangle. /// </summary> /// <param name="context">Context.</param> /// <returns>Drawing rectangle.</returns> private static Rect _GetShadowRect(GanttItemElementDrawingContext context) { double gapSize = Math.Min(context.DrawingArea.Width, GAP_SIZE); // Add gap bentween base elemnt and shadow. double xPos = context.DrawingArea.X + gapSize; double yPos = context.DrawingArea.Top + gapSize + gapSize/2; double height = context.DrawingArea.Height - gapSize; double width = Math.Max(context.DrawingArea.Width - gapSize/2, 0); // Define shadow size. return new Rect(xPos, yPos, width, height); }
/// <summary> /// Returns element drawing rectangle. /// </summary> /// <param name="context">Context.</param> /// <returns>Drawing rectangle.</returns> private static Rect _GetElementRect(GanttItemElementDrawingContext context) { // Add gap bentween gantt rows. double yPos = context.DrawingArea.Top + GAP_SIZE; double height = context.DrawingArea.Height - GAP_SIZE; // Define element size. return new Rect(context.DrawingArea.X, yPos, context.DrawingArea.Width, height); }
/// <summary> /// Draws dragged over glyph. /// </summary> /// <param name="stop">Bound stop.</param> /// <param name="context">DrawingContext.</param> private void _DrawDraggedOverGlyph(Stop stop, GanttItemElementDrawingContext context) { if (context.GlyphPanel == null) return; Rect elementRect = StopDrawer.GetElementRect(context); bool isStopFirst = false; if (stop.SequenceNumber == 1) isStopFirst = true; if (context.DrawDraggedOver && !context.DrawSelected && !_route.IsLocked) context.GlyphPanel.AddGlyph(this, new StopDragOverGlyph(elementRect, isStopFirst)); else context.GlyphPanel.RemoveGlyphByKey(this); }
/// <summary> /// Defines brush to draw drivetime element. /// </summary> /// <param name="context">Drawing context.</param> /// <returns></returns> private Brush _GetFillBrush(GanttItemElementDrawingContext context) { Debug.Assert(_stop != null); Debug.Assert(_route != null); Debug.Assert(context != null); // Define selected color. if (context.DrawSelected) return GanttControlHelper.GetSelectedBrush(); // Define dragged over color. if (context.DrawDraggedOver) return GanttControlHelper.GetDragOverBrush(); // Define locked color. if (_stop.IsLocked || _route.IsLocked) return GanttControlHelper.GetLockedBrush(_route.Color); // If stop is Order, not locked, not selected and not dragged over - return normal fill color. return GanttControlHelper.GetFillBrush(_route.Color); }
/// <summary> /// Creates visuals to represent the stop. /// </summary> private void _CreateVisuals() { // Create visual. DrawingVisual visual = new DrawingVisual(); // Prepare context. GanttItemElementDrawingContext drawingContext = new GanttItemElementDrawingContext(); drawingContext.DrawingContext = visual.RenderOpen(); drawingContext.DrawDraggedOver = false; drawingContext.DrawSelected = false; drawingContext.DrawingArea = new Rect(0, 0, GANTT_ELEMENT_WIDTH, GanttControlHelper.ItemHeight); Debug.Assert(_stop != null && !_color.HasValue || _stop == null && _color.HasValue); // Draw visual either by stop or by color. if (_stop != null) StopDrawer.DrawStop(_stop.Route.Color, drawingContext); else StopDrawer.DrawStop(_color.Value, drawingContext); drawingContext.DrawingContext.Close(); // Add visual. _children.Add(visual); }