// Create the pen and triangle in a static constructor and freeze them to improve performance. static InsertionAdorner() { pen = new Pen { Brush = Brushes.Gray, Thickness = 2 }; pen.Freeze(); LineSegment firstLine = new LineSegment(new Point(0, -5), false); firstLine.Freeze(); LineSegment secondLine = new LineSegment(new Point(0, 5), false); secondLine.Freeze(); PathFigure figure = new PathFigure { StartPoint = new Point(5, 0) }; figure.Segments.Add(firstLine); figure.Segments.Add(secondLine); figure.Freeze(); triangle = new PathGeometry(); triangle.Figures.Add(figure); triangle.Freeze(); }
PathGeometry CreateSplineSegment(PointCollection points) { if (points == null || points.Count < 1) return null; PathGeometry pathGeometry = new PathGeometry(); PathFigure pathFigure = new PathFigure(); PolyLineSegment polyLineSegment = new PolyLineSegment(); pathFigure.IsClosed = false; pathFigure.IsFilled = false; pathFigure.StartPoint = points[0]; for (int i = 1; i < points.Count; i++) { polyLineSegment.Points.Add(points[i]); } pathFigure.Segments.Add(polyLineSegment); pathGeometry.Figures.Add(pathFigure); // pathFigure.Freeze(); // return pathGeometry; }
/// <summary> /// 得到圆弧的几何图形; /// </summary> /// <param name="center"></param> /// <param name="screenRadius"></param> /// <param name="beginAngle"></param> /// <param name="angle"></param> /// <param name="smallAngle"></param> /// <returns></returns> private static SystemMedia.PathGeometry GetArcGeometry(Point startScreenPoint, Point endScreenPoint, double screenRadius, bool smallAngle, SystemMedia.SweepDirection sweepDirection) { var arcSegment = new SystemMedia.ArcSegment(endScreenPoint, new System.Windows.Size(screenRadius, screenRadius), 0D, !smallAngle, sweepDirection, true); var segments = new SystemMedia.PathSegment[] { arcSegment }; var pathFigure = new SystemMedia.PathFigure(startScreenPoint, segments, false); var figures = new SystemMedia.PathFigure[] { pathFigure }; arcSegment.Freeze(); pathFigure.Freeze(); return(new SystemMedia.PathGeometry(figures, SystemMedia.FillRule.EvenOdd, null)); }
/// <summary> /// Create the pen and triangle in a static constructor and freeze them to improve performance. /// </summary> static InsertionAdorner() { Pen = new Pen { Brush = Brushes.SkyBlue, Thickness = LineThickness }; Pen.Freeze(); var firstLine = new LineSegment(new Point(0, -TriangleWidth), false); firstLine.Freeze(); var secondLine = new LineSegment(new Point(0, TriangleWidth), false); secondLine.Freeze(); var figure = new PathFigure {StartPoint = new Point(TriangleWidth, 0)}; figure.Segments.Add(firstLine); figure.Segments.Add(secondLine); figure.Freeze(); Triangle = new PathGeometry(); Triangle.Figures.Add(figure); Triangle.Freeze(); }
static InsertionAdorner() { InsertionAdorner.pen.Freeze(); LineSegment lineSegment1 = new LineSegment(new Point(0.0, -5.0), false); lineSegment1.Freeze(); LineSegment lineSegment2 = new LineSegment(new Point(0.0, 5.0), false); lineSegment2.Freeze(); PathFigure pathFigure = new PathFigure() { StartPoint = new Point(5.0, 0.0) }; pathFigure.Segments.Add((PathSegment) lineSegment1); pathFigure.Segments.Add((PathSegment) lineSegment2); pathFigure.Freeze(); InsertionAdorner.triangle = new PathGeometry(); InsertionAdorner.triangle.Figures.Add(pathFigure); InsertionAdorner.triangle.Freeze(); }
/// <summary> /// Initializes static members of the <see cref="InsertionAdorner" /> class. /// </summary> static InsertionAdorner() { // Create the pen and triangle in a static constructor and freeze them to improve performance. Pen = new Pen { Brush = Brushes.Gray, Thickness = 2 }; Pen.Freeze(); var firstLine = new LineSegment(new Point(0, -5), false); firstLine.Freeze(); var secondLine = new LineSegment(new Point(0, 5), false); secondLine.Freeze(); var figure = new PathFigure { StartPoint = new Point(5, 0) }; figure.Segments.Add(firstLine); figure.Segments.Add(secondLine); figure.Freeze(); Triangle = new PathGeometry(); Triangle.Figures.Add(figure); Triangle.Freeze(); }
static InsertionAdorner() { Pen = new Pen { Brush = new SolidColorBrush(Color.FromRgb(48, 48, 48)), Thickness = 2 }; Pen.Freeze(); var firstLine = new LineSegment(new Point(0, -5), false); firstLine.Freeze(); var secondLine = new LineSegment(new Point(0, 5), false); secondLine.Freeze(); var figure = new PathFigure { StartPoint = new Point(5, 0) }; figure.Segments.Add(firstLine); figure.Segments.Add(secondLine); figure.Freeze(); Triangle = new PathGeometry(); Triangle.Figures.Add(figure); Triangle.Freeze(); }
static DropTargetInsertionAdorner() { // Create the pen and triangle in a static constructor and freeze them to improve performance. const int triangleSize = 3; m_Pen = new Pen(Brushes.Gray, 2); m_Pen.Freeze(); LineSegment firstLine = new LineSegment(new Point(0, -triangleSize), false); firstLine.Freeze(); LineSegment secondLine = new LineSegment(new Point(0, triangleSize), false); secondLine.Freeze(); PathFigure figure = new PathFigure { StartPoint = new Point(triangleSize, 0) }; figure.Segments.Add(firstLine); figure.Segments.Add(secondLine); figure.Freeze(); m_Triangle = new PathGeometry(); m_Triangle.Figures.Add(figure); m_Triangle.Freeze(); }
static DropTargetMetroInsertionAdorner() { // Create the pen and triangle in a static constructor and freeze them to improve performance. const int triangleSize = 5; var color = (Color) ThemeManager.DetectAppStyle(Application.Current).Item2.Resources["AccentColor"]; m_Pen = new Pen(new SolidColorBrush(color), 2); m_Pen.Freeze(); var firstLine = new LineSegment(new Point(0, -triangleSize), false); firstLine.Freeze(); var secondLine = new LineSegment(new Point(0, triangleSize), false); secondLine.Freeze(); var figure = new PathFigure {StartPoint = new Point(triangleSize, 0)}; figure.Segments.Add(firstLine); figure.Segments.Add(secondLine); figure.Freeze(); m_Triangle = new PathGeometry(); m_Triangle.Figures.Add(figure); m_Triangle.Freeze(); }
private void RenderTheme(DrawingContext dc) { Size size = RenderSize; bool isClickable = IsClickable && IsEnabled; bool isPressed = isClickable && IsPressed; ListSortDirection? sortDirection = SortDirection; bool isSorted = sortDirection != null; bool horizontal = Orientation == Orientation.Horizontal; Brush background = EnsureControlBrush(); Brush light = SystemColors.ControlLightBrush; Brush dark = SystemColors.ControlDarkBrush; bool shouldDrawRight = true; bool shouldDrawBottom = true; bool usingSeparatorBrush = false; Brush darkDarkRight = null; if (!horizontal) { if (SeparatorVisibility == Visibility.Visible && SeparatorBrush != null) { darkDarkRight = SeparatorBrush; usingSeparatorBrush = true; } else { shouldDrawRight = false; } } else { darkDarkRight = SystemColors.ControlDarkDarkBrush; } Brush darkDarkBottom = null; if (horizontal) { if (SeparatorVisibility == Visibility.Visible && SeparatorBrush != null) { darkDarkBottom = SeparatorBrush; usingSeparatorBrush = true; } else { shouldDrawBottom = false; } } else { darkDarkBottom = SystemColors.ControlDarkDarkBrush; } EnsureCache((int)ClassicFreezables.NumFreezables); // Draw the background dc.DrawRectangle(background, null, new Rect(0.0, 0.0, size.Width, size.Height)); if ((size.Width > 3.0) && (size.Height > 3.0)) { // Draw the border if (isPressed) { dc.DrawRectangle(dark, null, new Rect(0.0, 0.0, size.Width, 1.0)); dc.DrawRectangle(dark, null, new Rect(0.0, 0.0, 1.0, size.Height)); dc.DrawRectangle(dark, null, new Rect(0.0, Max0(size.Height - 1.0), size.Width, 1.0)); dc.DrawRectangle(dark, null, new Rect(Max0(size.Width - 1.0), 0.0, 1.0, size.Height)); } else { dc.DrawRectangle(light, null, new Rect(0.0, 0.0, 1.0, Max0(size.Height - 1.0))); dc.DrawRectangle(light, null, new Rect(0.0, 0.0, Max0(size.Width - 1.0), 1.0)); if (shouldDrawRight) { if (!usingSeparatorBrush) { dc.DrawRectangle(dark, null, new Rect(Max0(size.Width - 2.0), 1.0, 1.0, Max0(size.Height - 2.0))); } dc.DrawRectangle(darkDarkRight, null, new Rect(Max0(size.Width - 1.0), 0.0, 1.0, size.Height)); } if (shouldDrawBottom) { if (!usingSeparatorBrush) { dc.DrawRectangle(dark, null, new Rect(1.0, Max0(size.Height - 2.0), Max0(size.Width - 2.0), 1.0)); } dc.DrawRectangle(darkDarkBottom, null, new Rect(0.0, Max0(size.Height - 1.0), size.Width, 1.0)); } } } if (isSorted && (size.Width > 14.0) && (size.Height > 10.0)) { // If sorted, draw an arrow on the right TranslateTransform positionTransform = new TranslateTransform(size.Width - 15.0, (size.Height - 5.0) * 0.5); positionTransform.Freeze(); dc.PushTransform(positionTransform); bool ascending = (sortDirection == ListSortDirection.Ascending); PathGeometry arrowGeometry = (PathGeometry)GetCachedFreezable(ascending ? (int)ClassicFreezables.ArrowUpGeometry : (int)ClassicFreezables.ArrowDownGeometry); if (arrowGeometry == null) { arrowGeometry = new PathGeometry(); PathFigure arrowFigure = new PathFigure(); if (ascending) { arrowFigure.StartPoint = new Point(0.0, 5.0); LineSegment line = new LineSegment(new Point(5.0, 0.0), false); line.Freeze(); arrowFigure.Segments.Add(line); line = new LineSegment(new Point(10.0, 5.0), false); line.Freeze(); arrowFigure.Segments.Add(line); } else { arrowFigure.StartPoint = new Point(0.0, 0.0); LineSegment line = new LineSegment(new Point(10.0, 0.0), false); line.Freeze(); arrowFigure.Segments.Add(line); line = new LineSegment(new Point(5.0, 5.0), false); line.Freeze(); arrowFigure.Segments.Add(line); } arrowFigure.IsClosed = true; arrowFigure.Freeze(); arrowGeometry.Figures.Add(arrowFigure); arrowGeometry.Freeze(); CacheFreezable(arrowGeometry, ascending ? (int)ClassicFreezables.ArrowUpGeometry : (int)ClassicFreezables.ArrowDownGeometry); } dc.DrawGeometry(SystemColors.GrayTextBrush, null, arrowGeometry); dc.Pop(); // Position Transform } }
// Creates a rectangle figure private static PathFigure GenerateRectFigure(Rect rect) { PathFigure figure = new PathFigure(); figure.StartPoint = rect.TopLeft; figure.Segments.Add(new LineSegment(rect.TopRight, true)); figure.Segments.Add(new LineSegment(rect.BottomRight, true)); figure.Segments.Add(new LineSegment(rect.BottomLeft, true)); figure.IsClosed = true; figure.Freeze(); return figure; }
// The shadow geometry is the right borders with top rounded corner private Geometry GenerateTabTopShadowGeometry(Rect bounds, bool outerBorder) { double outerRadius = outerBorder ? 3.0 : 2.0; double innerRadius = outerRadius - 1.0; Size outerCorner = new Size(outerRadius, outerRadius), innerCorner = new Size(innerRadius, innerRadius); double right = bounds.Right, top = bounds.Top, bottom = bounds.Bottom - 1.0; PathFigure figure = new PathFigure(); //Start at bottom left, tracing the outside clockwise figure.StartPoint = new Point(right - 1.0, bottom); figure.Segments.Add(new LineSegment(new Point(right - 1.0, top + outerRadius), true)); //left side figure.Segments.Add(new ArcSegment(new Point(right - 1.0 - innerRadius * 0.293, top + 1.0 + innerRadius * 0.293), innerCorner, 0.0, false, SweepDirection.Counterclockwise, true)); //inner left rounded corner figure.Segments.Add(new LineSegment(new Point(right - outerRadius * 0.293, top + outerRadius * 0.293), true)); //top right corner figure.Segments.Add(new ArcSegment(new Point(right, top + outerRadius), outerCorner, 0.0, false, SweepDirection.Clockwise, true)); //top right corner figure.Segments.Add(new LineSegment(new Point(right, bottom), true)); //right side figure.IsClosed = true; //bottom side figure.Freeze(); PathGeometry geometry = new PathGeometry(); geometry.Figures.Add(figure); geometry.Freeze(); return geometry; }
/// <summary/> private void _renderShadow(DrawingContext dc, Size bounds) { var D = 7.5 - Softness*5.0; var W = bounds.Width; var H = bounds.Height; if (W <= 0.0 || H <= 0.0) return; var X0 = Depth/2; var Y0 = Depth/2; var X1 = W + Depth; var Y1 = H + Depth; double R0 = Math.Min(W / 2.0, H / 2.0); var TL = Math.Min(CornerRadius.TopLeft, R0) + D; var TR = Math.Min(CornerRadius.TopRight, R0) + D; var BL = Math.Min(CornerRadius.BottomLeft, R0) + D; var BR = Math.Min(CornerRadius.BottomRight, R0) + D; double[] GX = new double[] { X0 + D, X0 + TL, X1 - TR, X0 + BL, X1 - BR, X1 - D }; double[] GY = new double[] { Y0 + D, Y0 + TL, Y0 + TR, Y1 - BL, Y1 - BR, Y1 - D }; dc.PushGuidelineSet(new GuidelineSet(GX, GY)); // draw corners and edge var brushes = _getBrushes(Color, CornerRadius); dc.DrawRectangle(brushes[0], null, new Rect(X0, Y0, TL, TL)); // top-left corner dc.DrawRectangle(brushes[2], null, new Rect(GX[2], Y0, TR, TR)); // top-right corner dc.DrawRectangle(brushes[6], null, new Rect(X0, GY[3], BL, BL)); // bottom-left corner dc.DrawRectangle(brushes[8], null, new Rect(GX[4], GY[4], BR, BR)); // bottom-right corner if (GX[2] > GX[1]) { dc.DrawRectangle(brushes[1], null, new Rect(GX[1], Y0, GX[2] - GX[1], D)); // top edge } if (GY[3] > GY[1]) { dc.DrawRectangle(brushes[3], null, new Rect(X0, GY[1], D, GY[3] - GY[1])); // left edge } if (GY[4] > GY[2]) { dc.DrawRectangle(brushes[5], null, new Rect(GX[5], GY[2], D, GY[4] - GY[2])); // right edge } if (GX[4] > GX[3]) { dc.DrawRectangle(brushes[7], null, new Rect(GX[3], GY[5], GX[4] - GX[3], D)); // bottom edge } // draw center box if (TL == D && TR == D && BL == D && BR == D) { if (W > 2*D && H > 2*D) { var box = new Rect(GX[0], GY[0], W-2*D, H-2*D); dc.DrawRectangle(brushes[4], null, box); } } else { var fig = new PathFigure(); if (TL > D) { fig.StartPoint = new Point(GX[1], GY[0]); fig.Segments.Add(new LineSegment(new Point(GX[1], GY[1]), true)); fig.Segments.Add(new LineSegment(new Point(GX[0], GY[1]), true)); } else { fig.StartPoint = new Point(GX[0], GY[0]); } if (BL > D) { fig.Segments.Add(new LineSegment(new Point(GX[0], GY[3]), true)); fig.Segments.Add(new LineSegment(new Point(GX[3], GY[3]), true)); fig.Segments.Add(new LineSegment(new Point(GX[3], GY[5]), true)); } else { fig.Segments.Add(new LineSegment(new Point(GX[0], GY[5]), true)); } if (BR > D) { fig.Segments.Add(new LineSegment(new Point(GX[4], GY[5]), true)); fig.Segments.Add(new LineSegment(new Point(GX[4], GY[4]), true)); fig.Segments.Add(new LineSegment(new Point(GX[5], GY[4]), true)); } else { fig.Segments.Add(new LineSegment(new Point(GX[5], GY[5]), true)); } if (TR > D) { fig.Segments.Add(new LineSegment(new Point(GX[5], GY[2]), true)); fig.Segments.Add(new LineSegment(new Point(GX[2], GY[2]), true)); fig.Segments.Add(new LineSegment(new Point(GX[2], GY[0]), true)); } else { fig.Segments.Add(new LineSegment(new Point(GX[5], GY[0]), true)); } fig.IsClosed = true; fig.Freeze(); PathGeometry geometry = new PathGeometry{ Figures = { fig } }; geometry.Freeze(); dc.DrawGeometry(brushes[4], null, geometry); } dc.Pop(); }
//----------------------------------------------------------------------------- // Construction / rendering //----------------------------------------------------------------------------- PathGeometry CreateSpline(PointCollection controlPointsIn, double tension, DoubleCollection tensions, bool isClosed, bool isFilled, double tolerance) { if (controlPointsIn == null || controlPointsIn.Count < 1) return null; PathGeometry pathGeometry = new PathGeometry(); PathFigure pathFigure = new PathFigure(); PolyLineSegment polyLineSegment = new PolyLineSegment(); int count = controlPointsIn.Count; if (this.IgnoreLastPoint) count--; this.mpiControliOut = new int[controlPointsIn.Count]; this.ControlPoints = controlPointsIn; this.outputPoints = polyLineSegment.Points; pathFigure.IsClosed = isClosed; pathFigure.IsFilled = isFilled; pathFigure.StartPoint = ControlPoints[0]; RecordPointMapping(0); if (count < 2) { // Nothing to do: the spline is effectively *empty* } else if (count == 2) { if (!isClosed) { CreateSplineSegment(0, 0, 1, 1, tension, tension, tolerance); RecordPointMapping(1); } else { CreateSplineSegment(1, 0, 1, 0, tension, tension, tolerance); RecordPointMapping(1); // CreateSplineSegment(0, 1, 0, 1, tension, tension, tolerance); // closing arc } } else { bool useTensionCollection = (tensions != null && tensions.Count > 0); for (int i = 0; i < count; i++) { double T1 = useTensionCollection ? tensions[i % tensions.Count] : tension; double T2 = useTensionCollection ? tensions[(i + 1) % tensions.Count] : tension; if (i == 0) { CreateSplineSegment((isClosed ? count - 1 : 0), 0, 1, 2, T1, T2, tolerance); RecordPointMapping(1); } else if (i == count - 2) { CreateSplineSegment(i - 1, i, i + 1, (isClosed ? 0 : i + 1), T1, T2, tolerance); RecordPointMapping(i+1); } else if (i == count - 1) { if (isClosed) { CreateSplineSegment(i - 1, i, 0, 1, T1, T2, tolerance); // closing arc } } else { CreateSplineSegment(i - 1, i, i + 1, i + 2, T1, T2, tolerance); RecordPointMapping(i+1); } } } // // Deal with the fact that some control points might have been so close together // so as to not introduce any new output points. So far as our record keeping // is concerned, we'll just say that it shares an output point with its predecessor. // Debug.Assert(mpiControliOut[0]==0); if (this.IsClosed && this.IgnoreLastPoint) { RecordPointMapping(mpiControliOut.Length-1); } for (int iControl = 1; iControl < this.mpiControliOut.Length; iControl++) { if (this.mpiControliOut[iControl] == 0) this.mpiControliOut[iControl] = this.mpiControliOut[iControl-1]; } pathFigure.Segments.Add(polyLineSegment); pathGeometry.Figures.Add(pathFigure); // pathFigure.Freeze(); // return pathGeometry; }
/// <summary> /// Draw the hatches and the transparent area where isn't covering the elements. /// </summary> /// <param name="drawingContext"></param> private void DrawBackgound(DrawingContext drawingContext) { PathGeometry hatchGeometry = null; Geometry rectGeometry = null; int count = _elementsBounds.Count; if ( count != 0 ) { // Create a union collection of the element regions. for ( int i = 0; i < count; i++ ) { Rect hatchRect = _elementsBounds[i]; if ( hatchRect.IsEmpty ) { continue; } hatchRect.Inflate(HatchBorderMargin / 2, HatchBorderMargin / 2); if ( hatchGeometry == null ) { PathFigure path = new PathFigure(); path.StartPoint = new Point(hatchRect.Left, hatchRect.Top); PathSegmentCollection segments = new PathSegmentCollection(); PathSegment line = new LineSegment(new Point(hatchRect.Right, hatchRect.Top), true); line.Freeze(); segments.Add(line); line = new LineSegment(new Point(hatchRect.Right, hatchRect.Bottom), true); line.Freeze(); segments.Add(line); line = new LineSegment(new Point(hatchRect.Left, hatchRect.Bottom), true); line.Freeze(); segments.Add(line); line = new LineSegment(new Point(hatchRect.Left, hatchRect.Top), true); line.Freeze(); segments.Add(line); segments.Freeze(); path.Segments = segments; path.IsClosed = true; path.Freeze(); hatchGeometry = new PathGeometry(); hatchGeometry.Figures.Add(path); } else { rectGeometry = new RectangleGeometry(hatchRect); rectGeometry.Freeze(); hatchGeometry = Geometry.Combine(hatchGeometry, rectGeometry, GeometryCombineMode.Union, null); } } } // Then, create a region which equals to "SelectionFrame - element1 bounds - element2 bounds - ..." GeometryGroup backgroundGeometry = new GeometryGroup( ); GeometryCollection geometryCollection = new GeometryCollection(); // Add the entile rectanlge to the group. rectGeometry = new RectangleGeometry(new Rect(0, 0, RenderSize.Width, RenderSize.Height)); rectGeometry.Freeze(); geometryCollection.Add(rectGeometry); // Add the union of the element rectangles. Then the group will do oddeven operation. Geometry outlineGeometry = null; if ( hatchGeometry != null ) { hatchGeometry.Freeze(); outlineGeometry = hatchGeometry.GetOutlinedPathGeometry(); outlineGeometry.Freeze(); if ( count == 1 && ((InkCanvasInnerCanvas)AdornedElement).InkCanvas.GetSelectedStrokes().Count == 0 ) { geometryCollection.Add(outlineGeometry); } } geometryCollection.Freeze(); backgroundGeometry.Children = geometryCollection; backgroundGeometry.Freeze(); // Then, draw the region which may contain holes so that the elements cannot be covered. // After that, the underneath elements can receive the messages. #if DEBUG_OUTPUT // Draw the debug feedback drawingContext.DrawGeometry(new SolidColorBrush(Color.FromArgb(128, 255, 255, 0)), null, backgroundGeometry); #else drawingContext.DrawGeometry(Brushes.Transparent, null, backgroundGeometry); #endif // At last, draw the hatch borders if ( outlineGeometry != null ) { drawingContext.DrawGeometry(null, _hatchPen, outlineGeometry); } }
/// <summary> /// 描画処理のオーバーライド /// </summary> /// <param name="drawingContext">描画先のコンテキスト</param> protected override void OnRender(DrawingContext drawingContext) { #if DEBUG Debug.WriteLine("[{0}] OnRender[{1}]", this._measureCounter, this.RenderSize); #endif if (this.IsDesignMode) { // 背景色 drawingContext.DrawRectangle(new SolidColorBrush(Colors.AntiqueWhite), null, new Rect(this.RenderSize)); } var borderBrush = this.BorderBrush ?? new SolidColorBrush(this.IsDesignMode ? Colors.Black : (Color)this.FindResource("GraphBorderColor")); var tickBorderBrush = this.TickBorderBrush ?? borderBrush; var stroke = this.Stroke ?? borderBrush; // グラフ外枠円 var radius = this._mainboardSize.Width / 2.0 - this.GraphMargin; drawingContext.DrawEllipse(this.Background, new Pen(borderBrush, this.BorderThickness), this._mainboardCenter, radius, radius); // 角度 var angle = 360.0 / this.InternalChildren.Count; #region 基準軸の描画 for (var i = 0; i < this.InternalChildren.Count; i++) { var pt = this._mainboardCenter; pt.Offset(0.0, -radius); drawingContext.DrawLine(new Pen(tickBorderBrush, this.TickBorderThickness), this._mainboardCenter, pt.Rotate(i * angle, this._mainboardCenter)); // 目盛 if (this.Ticks > 0) { var div = radius / this.Ticks; for (var j = 1; j < this.Ticks; j++) { var pt1 = this._mainboardCenter; pt1.Offset(0.0, -j * div); var pt2 = pt1; pt1.Offset(-this.TickWidth / 2.0, 0.0); pt2.Offset(this.TickWidth / 2.0, 0.0); drawingContext.DrawLine(new Pen(tickBorderBrush, this.TickBorderThickness), pt1.Rotate(i * angle, this._mainboardCenter), pt2.Rotate(i * angle, this._mainboardCenter)); } } } #endregion 基準軸の描画 #region データ領域の描画 if (this.Values != null) { var values = this.InternalChildren.Count - this.Values.Count() >= 0 ? this.Values.Concat(Enumerable.Range(0, this.InternalChildren.Count - this.Values.Count()).Select(x => 0.0)) : this.Values.Take(this.InternalChildren.Count); var points = values.Select((x, i) => { var pt = this._mainboardCenter; pt.Offset(0.0, -radius * x / this.Maximum); return pt.Rotate(i * angle, this._mainboardCenter); }); var figure = new PathFigure() { IsClosed = true }; foreach (var item in points.Select((x, i) => new { Point = x, IsFirst = i == 0 })) { // 線の描画の準備 if (item.IsFirst) { figure.StartPoint = item.Point; } else { figure.Segments.Add(new LineSegment(item.Point, true)); } } if (figure.IsFrozen) { figure.Freeze(); } var geometry = new PathGeometry(); geometry.Figures.Add(figure); drawingContext.DrawGeometry(this.Fill, new Pen(stroke, this.StrokeThickness), geometry); if (this.PointElement != null) { this.PointElement.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); var visualBrush = new VisualBrush(this.PointElement); foreach (var pt in points) { var point = pt; point.Offset(-this.PointElement.DesiredSize.Width / 2.0, -this.PointElement.DesiredSize.Height / 2.0); // 点の描画 drawingContext.DrawRectangle(visualBrush, null, new Rect(point, this.PointElement.DesiredSize)); } } } #endregion データ領域の描画 }
/// <summary> /// Custom StrokeEraser Drawing /// </summary> /// <returns></returns> private static Drawing CreateStrokeEraserDrawing() { DrawingGroup drawingGroup = new DrawingGroup(); DrawingContext dc = null; try { dc = drawingGroup.Open(); LinearGradientBrush brush1 = new LinearGradientBrush( Color.FromRgb(240, 242, 255), // Start Color Color.FromRgb(180, 207, 248), // End Color 45f // Angle ); brush1.Freeze(); SolidColorBrush brush2 = new SolidColorBrush(Color.FromRgb(180, 207, 248)); brush2.Freeze(); Pen pen1 = new Pen(Brushes.Gray, 0.7); pen1.Freeze(); PathGeometry pathGeometry = new PathGeometry(); PathFigure path = new PathFigure(); path.StartPoint = new Point(5, 5); LineSegment segment = new LineSegment(new Point(16, 5), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(26, 15), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(15, 15), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(5, 5), true); segment.Freeze(); path.Segments.Add(segment); path.IsClosed = true; path.Freeze(); pathGeometry.Figures.Add(path); path = new PathFigure(); path.StartPoint = new Point(5, 5); segment = new LineSegment(new Point(5, 10), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(15, 19), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(15, 15), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(5, 5), true); segment.Freeze(); path.Segments.Add(segment); path.IsClosed = true; path.Freeze(); pathGeometry.Figures.Add(path); pathGeometry.Freeze(); PathGeometry pathGeometry1 = new PathGeometry(); path = new PathFigure(); path.StartPoint = new Point(15, 15); segment = new LineSegment(new Point(15, 19), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(26, 19), true); segment.Freeze(); path.Segments.Add(segment); segment = new LineSegment(new Point(26, 15), true); segment.Freeze(); path.Segments.Add(segment); segment.Freeze(); segment = new LineSegment(new Point(15, 15), true); path.Segments.Add(segment); path.IsClosed = true; path.Freeze(); pathGeometry1.Figures.Add(path); pathGeometry1.Freeze(); dc.DrawGeometry(brush1, pen1, pathGeometry); dc.DrawGeometry(brush2, pen1, pathGeometry1); dc.DrawLine(pen1, new Point(5, 5), new Point(5, 0)); dc.DrawLine(pen1, new Point(5, 5), new Point(0, 5)); dc.DrawLine(pen1, new Point(5, 5), new Point(2, 2)); dc.DrawLine(pen1, new Point(5, 5), new Point(8, 2)); dc.DrawLine(pen1, new Point(5, 5), new Point(2, 8)); } finally { if ( dc != null ) { dc.Close(); } } return drawingGroup; }
/// <summary> /// Renders the control. /// </summary> /// <param name="drawingContext"></param> protected override void OnRender(DrawingContext drawingContext) { System.Windows.CornerRadius cornerRadius = this.CornerRadius; Rect rect = new Rect(new Point(5.0, 5.0), new Size(base.RenderSize.Width, base.RenderSize.Height)); System.Windows.Media.Color c = this.Color; if (((rect.Width > 0.0) && (rect.Height > 0.0)) && (c.A > 0)) { double width = (rect.Right - rect.Left) - 10.0; double height = (rect.Bottom - rect.Top) - 10.0; double num3 = Math.Min((double)(width * 0.5), (double)(height * 0.5)); cornerRadius.TopLeft = Math.Min(cornerRadius.TopLeft, num3); cornerRadius.TopRight = Math.Min(cornerRadius.TopRight, num3); cornerRadius.BottomLeft = Math.Min(cornerRadius.BottomLeft, num3); cornerRadius.BottomRight = Math.Min(cornerRadius.BottomRight, num3); Brush[] brushes = this.GetBrushes(c, cornerRadius); double num4 = rect.Top + 5.0; double num5 = rect.Left + 5.0; double num6 = rect.Right - 5.0; double num7 = rect.Bottom - 5.0; double[] guidelinesX = new double[] { num5, num5 + cornerRadius.TopLeft, num6 - cornerRadius.TopRight, num5 + cornerRadius.BottomLeft, num6 - cornerRadius.BottomRight, num6 }; double[] guidelinesY = new double[] { num4, num4 + cornerRadius.TopLeft, num4 + cornerRadius.TopRight, num7 - cornerRadius.BottomLeft, num7 - cornerRadius.BottomRight, num7 }; drawingContext.PushGuidelineSet(new GuidelineSet(guidelinesX, guidelinesY)); cornerRadius.TopLeft += 5.0; cornerRadius.TopRight += 5.0; cornerRadius.BottomLeft += 5.0; cornerRadius.BottomRight += 5.0; Rect rectangle = new Rect(rect.Left, rect.Top, cornerRadius.TopLeft, cornerRadius.TopLeft); drawingContext.DrawRectangle(brushes[0], null, rectangle); double num8 = guidelinesX[2] - guidelinesX[1]; if (num8 > 0.0) { Rect rect3 = new Rect(guidelinesX[1], rect.Top, num8, 5.0); drawingContext.DrawRectangle(brushes[1], null, rect3); } Rect rect4 = new Rect(guidelinesX[2], rect.Top, cornerRadius.TopRight, cornerRadius.TopRight); drawingContext.DrawRectangle(brushes[2], null, rect4); double num9 = guidelinesY[3] - guidelinesY[1]; if (num9 > 0.0) { Rect rect5 = new Rect(rect.Left, guidelinesY[1], 5.0, num9); drawingContext.DrawRectangle(brushes[3], null, rect5); } double num10 = guidelinesY[4] - guidelinesY[2]; if (num10 > 0.0) { Rect rect6 = new Rect(guidelinesX[5], guidelinesY[2], 5.0, num10); drawingContext.DrawRectangle(brushes[5], null, rect6); } Rect rect7 = new Rect(rect.Left, guidelinesY[3], cornerRadius.BottomLeft, cornerRadius.BottomLeft); drawingContext.DrawRectangle(brushes[6], null, rect7); double num11 = guidelinesX[4] - guidelinesX[3]; if (num11 > 0.0) { Rect rect8 = new Rect(guidelinesX[3], guidelinesY[5], num11, 5.0); drawingContext.DrawRectangle(brushes[7], null, rect8); } Rect rect9 = new Rect(guidelinesX[4], guidelinesY[4], cornerRadius.BottomRight, cornerRadius.BottomRight); drawingContext.DrawRectangle(brushes[8], null, rect9); if (((cornerRadius.TopLeft == 5.0) && (cornerRadius.TopLeft == cornerRadius.TopRight)) && ((cornerRadius.TopLeft == cornerRadius.BottomLeft) && (cornerRadius.TopLeft == cornerRadius.BottomRight))) { Rect rect10 = new Rect(guidelinesX[0], guidelinesY[0], width, height); drawingContext.DrawRectangle(brushes[4], null, rect10); } else { PathFigure figure = new PathFigure(); if (cornerRadius.TopLeft > 5.0) { figure.StartPoint = new Point(guidelinesX[1], guidelinesY[0]); figure.Segments.Add(new LineSegment(new Point(guidelinesX[1], guidelinesY[1]), true)); figure.Segments.Add(new LineSegment(new Point(guidelinesX[0], guidelinesY[1]), true)); } else { figure.StartPoint = new Point(guidelinesX[0], guidelinesY[0]); } if (cornerRadius.BottomLeft > 5.0) { figure.Segments.Add(new LineSegment(new Point(guidelinesX[0], guidelinesY[3]), true)); figure.Segments.Add(new LineSegment(new Point(guidelinesX[3], guidelinesY[3]), true)); figure.Segments.Add(new LineSegment(new Point(guidelinesX[3], guidelinesY[5]), true)); } else { figure.Segments.Add(new LineSegment(new Point(guidelinesX[0], guidelinesY[5]), true)); } if (cornerRadius.BottomRight > 5.0) { figure.Segments.Add(new LineSegment(new Point(guidelinesX[4], guidelinesY[5]), true)); figure.Segments.Add(new LineSegment(new Point(guidelinesX[4], guidelinesY[4]), true)); figure.Segments.Add(new LineSegment(new Point(guidelinesX[5], guidelinesY[4]), true)); } else { figure.Segments.Add(new LineSegment(new Point(guidelinesX[5], guidelinesY[5]), true)); } if (cornerRadius.TopRight > 5.0) { figure.Segments.Add(new LineSegment(new Point(guidelinesX[5], guidelinesY[2]), true)); figure.Segments.Add(new LineSegment(new Point(guidelinesX[2], guidelinesY[2]), true)); figure.Segments.Add(new LineSegment(new Point(guidelinesX[2], guidelinesY[0]), true)); } else { figure.Segments.Add(new LineSegment(new Point(guidelinesX[5], guidelinesY[0]), true)); } figure.IsClosed = true; figure.Freeze(); PathGeometry geometry = new PathGeometry { Figures = { figure } }; geometry.Freeze(); drawingContext.DrawGeometry(brushes[4], null, geometry); } drawingContext.Pop(); } }
/// <summary> /// 描画処理をおこないます。 /// </summary> /// <param name="dc">描画するコンテキスト</param> protected override void OnRender(DrawingContext dc) { //base.OnRender(dc); if (XAxisData == null) { IsDataEnabled = false; return; } if (YAxisData == null) { IsDataEnabled = false; return; } var xArray = XAxisData.OfType<double>().ToArray(); var yArray = YAxisData.OfType<double>().ToArray(); var length = xArray.Length < yArray.Length ? xArray.Length : yArray.Length; Point? pt0 = null; var isLineFirst = true; var pathfigure = new PathFigure(); var pen = new Pen(this.Color != null ? new SolidColorBrush(this.Color.Value) : this.Stroke, this.Thickness); pen.Freeze(); Pen markerPen = null; if (this.MarkerPen != null) { markerPen = this.Color != null ? new Pen(new SolidColorBrush(this.Color.Value), this.MarkerPen.Thickness) : this.MarkerPen; markerPen.Freeze(); } var markerFill = this.Color != null ? new SolidColorBrush(this.Color.Value) : this.Fill; if (markerFill != null) markerFill.Freeze(); for (var i = 0; i < length; i++) { if (IsStrokeEnabled) { #region 線の描画 if (pt0 != null) { if ((pt0.Value.Y >= this.YMax) && (yArray[i] >= this.YMax)) { // 絶対に線の描画があり得ないパターン } else if ((pt0.Value.Y <= this.YMin) && (yArray[i] <= this.YMin)) { // 絶対に線の描画があり得ないパターン } else { Point? ptLine0 = null; Point? ptLine1 = null; // 以前の点が右端より左側にあって // 今回の点が左端より右側にある場合のみ // 線を描画する可能性がある if ((pt0.Value.X < this.XMax) && (xArray[i] > this.XMin)) { // 以前の点が範囲内ならこれを左端の点とする if ((this.XMin <= pt0.Value.X) && (pt0.Value.X <= this.XMax) && (this.YMin <= pt0.Value.Y) && (pt0.Value.Y <= this.YMax)) { ptLine0 = GetControlPointFromGraphPoint(pt0.Value); } // 今回の点が範囲内ならこれを右端の点とする if ((this.XMin <= xArray[i]) && (xArray[i] <= this.XMax) && (this.YMin <= yArray[i]) && (yArray[i] <= this.YMax)) { ptLine1 = GetControlPointFromGraphPoint(xArray[i], yArray[i]); } // 左端または右端の点が確定していない場合はグラフ表示範囲の境界線との交点を調べる if ((ptLine0 == null) || (ptLine1 == null)) { // y = ax + b // 傾き double? a = xArray[i] != pt0.Value.X ? (yArray[i] - pt0.Value.Y) / (xArray[i] - pt0.Value.X) : (double?)null; if (a != null) { // 切片 double b = pt0.Value.Y - a.Value * pt0.Value.X; // 左端縦軸との交点 var yLeft = a.Value * this.XMin + b; // 右端縦軸との交点 var yRight = a.Value * this.XMax + b; // 上端横軸との交点 var xTop = (this.YMax - b) / a.Value; // 下端横軸との交点 var xBottom = (this.YMin - b) / a.Value; #region 左端の点を確定する if (ptLine0 == null) { // 左端縦軸交点の確認 if ((this.YMin <= yLeft) && (yLeft <= this.YMax)) { ptLine0 = GetControlPointFromGraphPoint(this.XMin, yLeft); } else { // 下から上への線の場合 if (pt0.Value.Y < yArray[i]) { // 交わり得るのは下端横軸交点 if ((this.XMin <= xBottom) && (xBottom <= this.XMax)) { ptLine0 = GetControlPointFromGraphPoint(xBottom, this.YMin); } } else { // 上から下への線の場合は // 交わり得るのは上端横軸交点 if ((this.XMin <= xTop) && (xTop <= this.XMax)) { ptLine0 = GetControlPointFromGraphPoint(xTop, this.YMax); } } } if (ptLine0 != null) { pathfigure.Segments.Add(new LineSegment(ptLine0.Value, false)); } } #endregion 左端の点を確定する #region 右端の点を確定する if (ptLine1 == null) { // 右端縦軸交点の確認 if ((this.YMin <= yRight) && (yRight <= this.YMax)) { ptLine1 = GetControlPointFromGraphPoint(this.XMax, yRight); } else { // 下から上への線の場合 if (pt0.Value.Y < yArray[i]) { // 交わり得るのは上端横軸交点 if ((this.XMin <= xTop) && (xTop <= this.XMax)) { ptLine1 = GetControlPointFromGraphPoint(xTop, this.YMax); } } else { // 上から下への線の場合は // 交わり得るのは下端横軸交点 if ((this.XMin <= xBottom) && (xBottom <= this.XMax)) { ptLine1 = GetControlPointFromGraphPoint(xBottom, this.YMin); } } } } #endregion 右端の点を確定する } } // 線の開始点を確定する if (isLineFirst && ptLine0 != null) { pathfigure.StartPoint = ptLine0.Value; isLineFirst = false; } // 右端の点が確定したら線を結ぶ if ((ptLine0 != null) && (ptLine1 != null)) { pathfigure.Segments.Add(new LineSegment(ptLine1.Value, true)); } } } } #endregion 線の描画 } if (this.IsMarkerEnabled) { #region データ点の描画 if (pt0 != null) { // 線の上にデータ点を描画するために // ひとつ前のデータ点を描画する DrawingDataPoint(dc, markerFill, MarkerPen, pt0.Value); } if (i == length - 1) { // ひとつ前のデータ点を描画していたので // 最後のデータ点をここで描画する DrawingDataPoint(dc, markerFill, MarkerPen, new Point(xArray[i], yArray[i])); } #endregion データ点の描画 } // 以前の点として保持 pt0 = new Point(xArray[i], yArray[i]); } if (!pathfigure.IsFrozen) pathfigure.Freeze(); var geometry = new PathGeometry(); geometry.Figures.Add(pathfigure); geometry.Freeze(); dc.DrawGeometry(null, pen, geometry); // 強調表示するデータ点 if (this.HighlightPoint != null) { DrawingDataPoint(dc, markerFill, MarkerPen, this.HighlightPoint.Value, true); } // データ表示確認 IsDataEnabled = length > 0; }
internal unsafe void AddFigureToList(bool isFilled, bool isClosed, MilPoint2F* pPoints, UInt32 pointCount, byte* pSegTypes, UInt32 segmentCount) { if (pointCount >=1 && segmentCount >= 1) { PathFigure figure = new PathFigure(); figure.IsFilled = isFilled; figure.StartPoint = new Point(pPoints->X, pPoints->Y); int pointIndex = 1; int sameSegCount = 0; for (int segIndex=0; segIndex<segmentCount; segIndex += sameSegCount) { byte segType = (byte)(pSegTypes[segIndex] & (byte)MILCoreSegFlags.SegTypeMask); sameSegCount = 1; // Look for a run of same-type segments for a PolyXXXSegment. while (((segIndex + sameSegCount) < segmentCount) && (pSegTypes[segIndex] == pSegTypes[segIndex+sameSegCount])) { sameSegCount++; } bool fStroked = (pSegTypes[segIndex] & (byte)MILCoreSegFlags.SegIsAGap) == (byte)0; bool fSmooth = (pSegTypes[segIndex] & (byte)MILCoreSegFlags.SegSmoothJoin) != (byte)0; if (segType == (byte)MILCoreSegFlags.SegTypeLine) { if (pointIndex+sameSegCount > pointCount) { throw new System.InvalidOperationException(SR.Get(SRID.PathGeometry_InternalReadBackError)); } if (sameSegCount>1) { PointCollection ptCollection = new PointCollection(); for (int i=0; i<sameSegCount; i++) { ptCollection.Add(new Point(pPoints[pointIndex+i].X, pPoints[pointIndex+i].Y)); } ptCollection.Freeze(); PolyLineSegment polySeg = new PolyLineSegment(ptCollection, fStroked, fSmooth); polySeg.Freeze(); figure.Segments.Add(polySeg); } else { Debug.Assert(sameSegCount == 1); figure.Segments.Add(new LineSegment(new Point(pPoints[pointIndex].X, pPoints[pointIndex].Y), fStroked, fSmooth)); } pointIndex += sameSegCount; } else if (segType == (byte)MILCoreSegFlags.SegTypeBezier) { int pointBezierCount = sameSegCount*3; if (pointIndex+pointBezierCount > pointCount) { throw new System.InvalidOperationException(SR.Get(SRID.PathGeometry_InternalReadBackError)); } if (sameSegCount>1) { PointCollection ptCollection = new PointCollection(); for (int i=0; i<pointBezierCount; i++) { ptCollection.Add(new Point(pPoints[pointIndex+i].X, pPoints[pointIndex+i].Y)); } ptCollection.Freeze(); PolyBezierSegment polySeg = new PolyBezierSegment(ptCollection, fStroked, fSmooth); polySeg.Freeze(); figure.Segments.Add(polySeg); } else { Debug.Assert(sameSegCount == 1); figure.Segments.Add(new BezierSegment( new Point(pPoints[pointIndex].X, pPoints[pointIndex].Y), new Point(pPoints[pointIndex+1].X, pPoints[pointIndex+1].Y), new Point(pPoints[pointIndex+2].X, pPoints[pointIndex+2].Y), fStroked, fSmooth)); } pointIndex += pointBezierCount; } else { throw new System.InvalidOperationException(SR.Get(SRID.PathGeometry_InternalReadBackError)); } } if (isClosed) { figure.IsClosed = true; } figure.Freeze(); Figures.Add(figure); // Do not bother adding empty figures. } }
/// <summary> /// Render callback. /// </summary> protected override void OnRender(DrawingContext drawingContext) { CornerRadius cornerRadius = CornerRadius; Rect shadowBounds = new Rect(new Point(ShadowDepth, ShadowDepth), new Size(RenderSize.Width, RenderSize.Height)); Color color = Color; if (shadowBounds.Width > 0 && shadowBounds.Height > 0 && color.A > 0) { // The shadow is drawn with a dark center the size of the shadow bounds // deflated by shadow depth on each side. double centerWidth = shadowBounds.Right - shadowBounds.Left - 2 * ShadowDepth; double centerHeight = shadowBounds.Bottom - shadowBounds.Top - 2 * ShadowDepth; // Clamp corner radii to be less than 1/2 the side of the inner shadow bounds double maxRadius = Math.Min(centerWidth * 0.5, centerHeight * 0.5); cornerRadius.TopLeft = Math.Min(cornerRadius.TopLeft, maxRadius); cornerRadius.TopRight = Math.Min(cornerRadius.TopRight, maxRadius); cornerRadius.BottomLeft = Math.Min(cornerRadius.BottomLeft, maxRadius); cornerRadius.BottomRight = Math.Min(cornerRadius.BottomRight, maxRadius); // Get the brushes for the 9 regions Brush[] brushes = GetBrushes(color, cornerRadius); // Snap grid to device pixels double centerTop = shadowBounds.Top + ShadowDepth; double centerLeft = shadowBounds.Left + ShadowDepth; double centerRight = shadowBounds.Right - ShadowDepth; double centerBottom = shadowBounds.Bottom - ShadowDepth; // Because of different corner radii there are 6 potential x (or y) lines to snap to double[] guidelineSetX = new double[] { centerLeft, centerLeft + cornerRadius.TopLeft, centerRight - cornerRadius.TopRight, centerLeft + cornerRadius.BottomLeft, centerRight - cornerRadius.BottomRight, centerRight}; double[] guidelineSetY = new double[] { centerTop, centerTop + cornerRadius.TopLeft, centerTop + cornerRadius.TopRight, centerBottom - cornerRadius.BottomLeft, centerBottom - cornerRadius.BottomRight, centerBottom}; drawingContext.PushGuidelineSet(new GuidelineSet(guidelineSetX, guidelineSetY)); // The corner rectangles are drawn drawn ShadowDepth pixels bigger to // account for the blur cornerRadius.TopLeft = cornerRadius.TopLeft + ShadowDepth; cornerRadius.TopRight = cornerRadius.TopRight + ShadowDepth; cornerRadius.BottomLeft = cornerRadius.BottomLeft + ShadowDepth; cornerRadius.BottomRight = cornerRadius.BottomRight + ShadowDepth; // Draw Top row Rect topLeft = new Rect(shadowBounds.Left, shadowBounds.Top, cornerRadius.TopLeft, cornerRadius.TopLeft); drawingContext.DrawRectangle(brushes[TopLeft], null, topLeft); double topWidth = guidelineSetX[2] - guidelineSetX[1]; if (topWidth > 0) { Rect top = new Rect(guidelineSetX[1], shadowBounds.Top, topWidth, ShadowDepth); drawingContext.DrawRectangle(brushes[Top], null, top); } Rect topRight = new Rect(guidelineSetX[2], shadowBounds.Top, cornerRadius.TopRight, cornerRadius.TopRight); drawingContext.DrawRectangle(brushes[TopRight], null, topRight); // Middle row double leftHeight = guidelineSetY[3] - guidelineSetY[1]; if (leftHeight > 0) { Rect left = new Rect(shadowBounds.Left, guidelineSetY[1], ShadowDepth, leftHeight); drawingContext.DrawRectangle(brushes[Left], null, left); } double rightHeight = guidelineSetY[4] - guidelineSetY[2]; if (rightHeight > 0) { Rect right = new Rect(guidelineSetX[5], guidelineSetY[2], ShadowDepth, rightHeight); drawingContext.DrawRectangle(brushes[Right], null, right); } // Bottom row Rect bottomLeft = new Rect(shadowBounds.Left, guidelineSetY[3], cornerRadius.BottomLeft, cornerRadius.BottomLeft); drawingContext.DrawRectangle(brushes[BottomLeft], null, bottomLeft); double bottomWidth = guidelineSetX[4] - guidelineSetX[3]; if (bottomWidth > 0) { Rect bottom = new Rect(guidelineSetX[3], guidelineSetY[5], bottomWidth, ShadowDepth); drawingContext.DrawRectangle(brushes[Bottom], null, bottom); } Rect bottomRight = new Rect(guidelineSetX[4], guidelineSetY[4], cornerRadius.BottomRight, cornerRadius.BottomRight); drawingContext.DrawRectangle(brushes[BottomRight], null, bottomRight); // Fill Center // Because the heights of the top/bottom rects and widths of the left/right rects are fixed // and the corner rects are drawn with the size of the corner, the center // may not be a square. In this case, create a path to fill the area // When the target object's corner radius is 0, only need to draw one rect if (cornerRadius.TopLeft == ShadowDepth && cornerRadius.TopLeft == cornerRadius.TopRight && cornerRadius.TopLeft == cornerRadius.BottomLeft && cornerRadius.TopLeft == cornerRadius.BottomRight) { // All corners of target are 0, render one large rectangle Rect center = new Rect(guidelineSetX[0], guidelineSetY[0], centerWidth, centerHeight); drawingContext.DrawRectangle(brushes[Center], null, center); } else { // If the corner radius is TL=2, TR=1, BL=0, BR=2 the following shows the shape that needs to be created. // _________________ // | |_ // _ _| | // | | // | _ _| // | | // |___________________| // The missing corners of the shape are filled with the radial gradients drawn above // Define shape counter clockwise PathFigure figure = new PathFigure(); if (cornerRadius.TopLeft > ShadowDepth) { figure.StartPoint = new Point(guidelineSetX[1], guidelineSetY[0]); figure.Segments.Add(new LineSegment(new Point(guidelineSetX[1], guidelineSetY[1]), true)); figure.Segments.Add(new LineSegment(new Point(guidelineSetX[0], guidelineSetY[1]), true)); } else { figure.StartPoint = new Point(guidelineSetX[0], guidelineSetY[0]); } if (cornerRadius.BottomLeft > ShadowDepth) { figure.Segments.Add(new LineSegment(new Point(guidelineSetX[0], guidelineSetY[3]), true)); figure.Segments.Add(new LineSegment(new Point(guidelineSetX[3], guidelineSetY[3]), true)); figure.Segments.Add(new LineSegment(new Point(guidelineSetX[3], guidelineSetY[5]), true)); } else { figure.Segments.Add(new LineSegment(new Point(guidelineSetX[0], guidelineSetY[5]), true)); } if (cornerRadius.BottomRight > ShadowDepth) { figure.Segments.Add(new LineSegment(new Point(guidelineSetX[4], guidelineSetY[5]), true)); figure.Segments.Add(new LineSegment(new Point(guidelineSetX[4], guidelineSetY[4]), true)); figure.Segments.Add(new LineSegment(new Point(guidelineSetX[5], guidelineSetY[4]), true)); } else { figure.Segments.Add(new LineSegment(new Point(guidelineSetX[5], guidelineSetY[5]), true)); } if (cornerRadius.TopRight > ShadowDepth) { figure.Segments.Add(new LineSegment(new Point(guidelineSetX[5], guidelineSetY[2]), true)); figure.Segments.Add(new LineSegment(new Point(guidelineSetX[2], guidelineSetY[2]), true)); figure.Segments.Add(new LineSegment(new Point(guidelineSetX[2], guidelineSetY[0]), true)); } else { figure.Segments.Add(new LineSegment(new Point(guidelineSetX[5], guidelineSetY[0]), true)); } figure.IsClosed = true; figure.Freeze(); PathGeometry geometry = new PathGeometry(); geometry.Figures.Add(figure); geometry.Freeze(); drawingContext.DrawGeometry(brushes[Center], null, geometry); } drawingContext.Pop(); } }
private void RenderAeroNormalColor(DrawingContext dc) { Size size = RenderSize; bool horizontal = Orientation == Orientation.Horizontal; bool isClickable = IsClickable && IsEnabled; bool isHovered = isClickable && IsHovered; bool isPressed = isClickable && IsPressed; ListSortDirection? sortDirection = SortDirection; bool isSorted = sortDirection != null; bool isSelected = IsSelected; bool hasBevel = (!isHovered && !isPressed && !isSorted && !isSelected); EnsureCache((int)AeroFreezables.NumFreezables); if (horizontal) { // When horizontal, rotate the rendering by -90 degrees Matrix m1 = new Matrix(); m1.RotateAt(-90.0, 0.0, 0.0); Matrix m2 = new Matrix(); m2.Translate(0.0, size.Height); MatrixTransform horizontalRotate = new MatrixTransform(m1 * m2); horizontalRotate.Freeze(); dc.PushTransform(horizontalRotate); double temp = size.Width; size.Width = size.Height; size.Height = temp; } if (hasBevel) { // This is a highlight that can be drawn by just filling the background with the color. // It will be seen through the gab between the border and the background. LinearGradientBrush bevel = (LinearGradientBrush)GetCachedFreezable((int)AeroFreezables.NormalBevel); if (bevel == null) { bevel = new LinearGradientBrush(); bevel.StartPoint = new Point(); bevel.EndPoint = new Point(0.0, 1.0); bevel.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF), 0.0)); bevel.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF), 0.4)); bevel.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xFC, 0xFC, 0xFD), 0.4)); bevel.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xFB, 0xFC, 0xFC), 1.0)); bevel.Freeze(); CacheFreezable(bevel, (int)AeroFreezables.NormalBevel); } dc.DrawRectangle(bevel, null, new Rect(0.0, 0.0, size.Width, size.Height)); } // Fill the background AeroFreezables backgroundType = AeroFreezables.NormalBackground; if (isPressed) { backgroundType = AeroFreezables.PressedBackground; } else if (isHovered) { backgroundType = AeroFreezables.HoveredBackground; } else if (isSorted || isSelected) { backgroundType = AeroFreezables.SortedBackground; } LinearGradientBrush background = (LinearGradientBrush)GetCachedFreezable((int)backgroundType); if (background == null) { background = new LinearGradientBrush(); background.StartPoint = new Point(); background.EndPoint = new Point(0.0, 1.0); switch (backgroundType) { case AeroFreezables.NormalBackground: background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF), 0.0)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF), 0.4)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xF7, 0xF8, 0xFA), 0.4)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xF1, 0xF2, 0xF4), 1.0)); break; case AeroFreezables.PressedBackground: background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xBC, 0xE4, 0xF9), 0.0)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xBC, 0xE4, 0xF9), 0.4)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x8D, 0xD6, 0xF7), 0.4)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x8A, 0xD1, 0xF5), 1.0)); break; case AeroFreezables.HoveredBackground: background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xE3, 0xF7, 0xFF), 0.0)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xE3, 0xF7, 0xFF), 0.4)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xBD, 0xED, 0xFF), 0.4)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xB7, 0xE7, 0xFB), 1.0)); break; case AeroFreezables.SortedBackground: background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xF2, 0xF9, 0xFC), 0.0)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xF2, 0xF9, 0xFC), 0.4)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xE1, 0xF1, 0xF9), 0.4)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xD8, 0xEC, 0xF6), 1.0)); break; } background.Freeze(); CacheFreezable(background, (int)backgroundType); } dc.DrawRectangle(background, null, new Rect(0.0, 0.0, size.Width, size.Height)); if (size.Width >= 2.0) { // Draw the borders on the sides AeroFreezables sideType = AeroFreezables.NormalSides; if (isPressed) { sideType = AeroFreezables.PressedSides; } else if (isHovered) { sideType = AeroFreezables.HoveredSides; } else if (isSorted || isSelected) { sideType = AeroFreezables.SortedSides; } if (SeparatorVisibility == Visibility.Visible) { Brush sideBrush; if (SeparatorBrush != null) { sideBrush = SeparatorBrush; } else { sideBrush = (Brush)GetCachedFreezable((int)sideType); if (sideBrush == null) { LinearGradientBrush lgBrush = null; if (sideType != AeroFreezables.SortedSides) { lgBrush = new LinearGradientBrush(); lgBrush.StartPoint = new Point(); lgBrush.EndPoint = new Point(0.0, 1.0); sideBrush = lgBrush; } switch (sideType) { case AeroFreezables.NormalSides: lgBrush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xF2, 0xF2, 0xF2), 0.0)); lgBrush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xEF, 0xEF, 0xEF), 0.4)); lgBrush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xE7, 0xE8, 0xEA), 0.4)); lgBrush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xDE, 0xDF, 0xE1), 1.0)); break; case AeroFreezables.PressedSides: lgBrush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x7A, 0x9E, 0xB1), 0.0)); lgBrush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x7A, 0x9E, 0xB1), 0.4)); lgBrush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x50, 0x91, 0xAF), 0.4)); lgBrush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x4D, 0x8D, 0xAD), 1.0)); break; case AeroFreezables.HoveredSides: lgBrush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x88, 0xCB, 0xEB), 0.0)); lgBrush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x88, 0xCB, 0xEB), 0.4)); lgBrush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x69, 0xBB, 0xE3), 0.4)); lgBrush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x69, 0xBB, 0xE3), 1.0)); break; case AeroFreezables.SortedSides: sideBrush = new SolidColorBrush(Color.FromArgb(0xFF, 0x96, 0xD9, 0xF9)); break; } sideBrush.Freeze(); CacheFreezable(sideBrush, (int)sideType); } } dc.DrawRectangle(sideBrush, null, new Rect(0.0, 0.0, 1.0, Max0(size.Height - 0.95))); dc.DrawRectangle(sideBrush, null, new Rect(size.Width - 1.0, 0.0, 1.0, Max0(size.Height - 0.95))); } } if (isPressed && (size.Width >= 4.0) && (size.Height >= 4.0)) { // When pressed, there are added borders on the left and top LinearGradientBrush topBrush = (LinearGradientBrush)GetCachedFreezable((int)AeroFreezables.PressedTop); if (topBrush == null) { topBrush = new LinearGradientBrush(); topBrush.StartPoint = new Point(); topBrush.EndPoint = new Point(0.0, 1.0); topBrush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x86, 0xA3, 0xB2), 0.0)); topBrush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x86, 0xA3, 0xB2), 0.1)); topBrush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xAA, 0xCE, 0xE1), 0.9)); topBrush.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xAA, 0xCE, 0xE1), 1.0)); topBrush.Freeze(); CacheFreezable(topBrush, (int)AeroFreezables.PressedTop); } dc.DrawRectangle(topBrush, null, new Rect(0.0, 0.0, size.Width, 2.0)); LinearGradientBrush pressedBevel = (LinearGradientBrush)GetCachedFreezable((int)AeroFreezables.PressedBevel); if (pressedBevel == null) { pressedBevel = new LinearGradientBrush(); pressedBevel.StartPoint = new Point(); pressedBevel.EndPoint = new Point(0.0, 1.0); pressedBevel.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xA2, 0xCB, 0xE0), 0.0)); pressedBevel.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xA2, 0xCB, 0xE0), 0.4)); pressedBevel.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x72, 0xBC, 0xDF), 0.4)); pressedBevel.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x6E, 0xB8, 0xDC), 1.0)); pressedBevel.Freeze(); CacheFreezable(pressedBevel, (int)AeroFreezables.PressedBevel); } dc.DrawRectangle(pressedBevel, null, new Rect(1.0, 0.0, 1.0, size.Height - 0.95)); dc.DrawRectangle(pressedBevel, null, new Rect(size.Width - 2.0, 0.0, 1.0, size.Height - 0.95)); } if (size.Height >= 2.0) { // Draw the bottom border AeroFreezables bottomType = AeroFreezables.NormalBottom; if (isPressed) { bottomType = AeroFreezables.PressedOrHoveredBottom; } else if (isHovered) { bottomType = AeroFreezables.PressedOrHoveredBottom; } else if (isSorted || isSelected) { bottomType = AeroFreezables.SortedBottom; } SolidColorBrush bottomBrush = (SolidColorBrush)GetCachedFreezable((int)bottomType); if (bottomBrush == null) { switch (bottomType) { case AeroFreezables.NormalBottom: bottomBrush = new SolidColorBrush(Color.FromArgb(0xFF, 0xD5, 0xD5, 0xD5)); break; case AeroFreezables.PressedOrHoveredBottom: bottomBrush = new SolidColorBrush(Color.FromArgb(0xFF, 0x93, 0xC9, 0xE3)); break; case AeroFreezables.SortedBottom: bottomBrush = new SolidColorBrush(Color.FromArgb(0xFF, 0x96, 0xD9, 0xF9)); break; } bottomBrush.Freeze(); CacheFreezable(bottomBrush, (int)bottomType); } dc.DrawRectangle(bottomBrush, null, new Rect(0.0, size.Height - 1.0, size.Width, 1.0)); } if (isSorted && (size.Width > 14.0) && (size.Height > 10.0)) { // Draw the sort arrow TranslateTransform positionTransform = new TranslateTransform((size.Width - 8.0) * 0.5, 1.0); positionTransform.Freeze(); dc.PushTransform(positionTransform); bool ascending = (sortDirection == ListSortDirection.Ascending); PathGeometry arrowGeometry = (PathGeometry)GetCachedFreezable(ascending ? (int)AeroFreezables.ArrowUpGeometry : (int)AeroFreezables.ArrowDownGeometry); if (arrowGeometry == null) { arrowGeometry = new PathGeometry(); PathFigure arrowFigure = new PathFigure(); if (ascending) { arrowFigure.StartPoint = new Point(0.0, 4.0); LineSegment line = new LineSegment(new Point(4.0, 0.0), false); line.Freeze(); arrowFigure.Segments.Add(line); line = new LineSegment(new Point(8.0, 4.0), false); line.Freeze(); arrowFigure.Segments.Add(line); } else { arrowFigure.StartPoint = new Point(0.0, 0.0); LineSegment line = new LineSegment(new Point(8.0, 0.0), false); line.Freeze(); arrowFigure.Segments.Add(line); line = new LineSegment(new Point(4.0, 4.0), false); line.Freeze(); arrowFigure.Segments.Add(line); } arrowFigure.IsClosed = true; arrowFigure.Freeze(); arrowGeometry.Figures.Add(arrowFigure); arrowGeometry.Freeze(); CacheFreezable(arrowGeometry, ascending ? (int)AeroFreezables.ArrowUpGeometry : (int)AeroFreezables.ArrowDownGeometry); } // Draw two arrows, one inset in the other. This is to achieve a double gradient over both the border and the fill. LinearGradientBrush arrowBorder = (LinearGradientBrush)GetCachedFreezable((int)AeroFreezables.ArrowBorder); if (arrowBorder == null) { arrowBorder = new LinearGradientBrush(); arrowBorder.StartPoint = new Point(); arrowBorder.EndPoint = new Point(1.0, 1.0); arrowBorder.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x3C, 0x5E, 0x72), 0.0)); arrowBorder.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x3C, 0x5E, 0x72), 0.1)); arrowBorder.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xC3, 0xE4, 0xF5), 1.0)); arrowBorder.Freeze(); CacheFreezable(arrowBorder, (int)AeroFreezables.ArrowBorder); } dc.DrawGeometry(arrowBorder, null, arrowGeometry); LinearGradientBrush arrowFill = (LinearGradientBrush)GetCachedFreezable((int)AeroFreezables.ArrowFill); if (arrowFill == null) { arrowFill = new LinearGradientBrush(); arrowFill.StartPoint = new Point(); arrowFill.EndPoint = new Point(1.0, 1.0); arrowFill.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x61, 0x96, 0xB6), 0.0)); arrowFill.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0x61, 0x96, 0xB6), 0.1)); arrowFill.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xCA, 0xE6, 0xF5), 1.0)); arrowFill.Freeze(); CacheFreezable(arrowFill, (int)AeroFreezables.ArrowFill); } // Inset the fill arrow inside the border arrow ScaleTransform arrowScale = (ScaleTransform)GetCachedFreezable((int)AeroFreezables.ArrowFillScale); if (arrowScale == null) { arrowScale = new ScaleTransform(0.75, 0.75, 3.5, 4.0); arrowScale.Freeze(); CacheFreezable(arrowScale, (int)AeroFreezables.ArrowFillScale); } dc.PushTransform(arrowScale); dc.DrawGeometry(arrowFill, null, arrowGeometry); dc.Pop(); // Scale Transform dc.Pop(); // Position Transform } if (horizontal) { dc.Pop(); // Horizontal Rotate } }
internal unsafe void AddFigureToList(bool isFilled, bool isClosed, MilPoint2F *pPoints, UInt32 pointCount, byte *pSegTypes, UInt32 segmentCount) { if (pointCount >= 1 && segmentCount >= 1) { PathFigure figure = new PathFigure(); figure.IsFilled = isFilled; figure.StartPoint = new Point(pPoints->X, pPoints->Y); int pointIndex = 1; int sameSegCount = 0; for (int segIndex = 0; segIndex < segmentCount; segIndex += sameSegCount) { byte segType = (byte)(pSegTypes[segIndex] & (byte)MILCoreSegFlags.SegTypeMask); sameSegCount = 1; // Look for a run of same-type segments for a PolyXXXSegment. while (((segIndex + sameSegCount) < segmentCount) && (pSegTypes[segIndex] == pSegTypes[segIndex + sameSegCount])) { sameSegCount++; } bool fStroked = (pSegTypes[segIndex] & (byte)MILCoreSegFlags.SegIsAGap) == (byte)0; bool fSmooth = (pSegTypes[segIndex] & (byte)MILCoreSegFlags.SegSmoothJoin) != (byte)0; if (segType == (byte)MILCoreSegFlags.SegTypeLine) { if (pointIndex + sameSegCount > pointCount) { throw new System.InvalidOperationException(SR.Get(SRID.PathGeometry_InternalReadBackError)); } if (sameSegCount > 1) { PointCollection ptCollection = new PointCollection(); for (int i = 0; i < sameSegCount; i++) { ptCollection.Add(new Point(pPoints[pointIndex + i].X, pPoints[pointIndex + i].Y)); } ptCollection.Freeze(); PolyLineSegment polySeg = new PolyLineSegment(ptCollection, fStroked, fSmooth); polySeg.Freeze(); figure.Segments.Add(polySeg); } else { Debug.Assert(sameSegCount == 1); figure.Segments.Add(new LineSegment(new Point(pPoints[pointIndex].X, pPoints[pointIndex].Y), fStroked, fSmooth)); } pointIndex += sameSegCount; } else if (segType == (byte)MILCoreSegFlags.SegTypeBezier) { int pointBezierCount = sameSegCount * 3; if (pointIndex + pointBezierCount > pointCount) { throw new System.InvalidOperationException(SR.Get(SRID.PathGeometry_InternalReadBackError)); } if (sameSegCount > 1) { PointCollection ptCollection = new PointCollection(); for (int i = 0; i < pointBezierCount; i++) { ptCollection.Add(new Point(pPoints[pointIndex + i].X, pPoints[pointIndex + i].Y)); } ptCollection.Freeze(); PolyBezierSegment polySeg = new PolyBezierSegment(ptCollection, fStroked, fSmooth); polySeg.Freeze(); figure.Segments.Add(polySeg); } else { Debug.Assert(sameSegCount == 1); figure.Segments.Add(new BezierSegment( new Point(pPoints[pointIndex].X, pPoints[pointIndex].Y), new Point(pPoints[pointIndex + 1].X, pPoints[pointIndex + 1].Y), new Point(pPoints[pointIndex + 2].X, pPoints[pointIndex + 2].Y), fStroked, fSmooth)); } pointIndex += pointBezierCount; } else { throw new System.InvalidOperationException(SR.Get(SRID.PathGeometry_InternalReadBackError)); } } if (isClosed) { figure.IsClosed = true; } figure.Freeze(); Figures.Add(figure); // Do not bother adding empty figures. } }
private void RenderTheme(DrawingContext dc) { Size size = RenderSize; bool horizontal = Orientation == Orientation.Horizontal; bool isClickable = IsClickable && IsEnabled; bool isHovered = isClickable && IsHovered; bool isPressed = isClickable && IsPressed; ListSortDirection? sortDirection = SortDirection; bool isSorted = sortDirection != null; bool isSelected = IsSelected; EnsureCache((int)RoyaleFreezables.NumFreezables); if (horizontal) { // When horizontal, rotate the rendering by -90 degrees Matrix m1 = new Matrix(); m1.RotateAt(-90.0, 0.0, 0.0); Matrix m2 = new Matrix(); m2.Translate(0.0, size.Height); MatrixTransform horizontalRotate = new MatrixTransform(m1 * m2); horizontalRotate.Freeze(); dc.PushTransform(horizontalRotate); double temp = size.Width; size.Width = size.Height; size.Height = temp; } // Draw the background RoyaleFreezables backgroundType = isPressed ? RoyaleFreezables.PressedBackground : isHovered ? RoyaleFreezables.HoveredBackground : RoyaleFreezables.NormalBackground; LinearGradientBrush background = (LinearGradientBrush)GetCachedFreezable((int)backgroundType); if (background == null) { background = new LinearGradientBrush(); background.StartPoint = new Point(); background.EndPoint = new Point(0.0, 1.0); if (isPressed) { background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xB9, 0xB9, 0xC8), 0.0)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xEC, 0xEC, 0xF3), 0.1)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xEC, 0xEC, 0xF3), 1.0)); } else if (isHovered || isSelected) { background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xFE, 0xFE, 0xFE), 0.0)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xFE, 0xFE, 0xFE), 0.85)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xBD, 0xBE, 0xCE), 1.0)); } else { background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xF9, 0xFA, 0xFD), 0.0)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xF9, 0xFA, 0xFD), 0.85)); background.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xBD, 0xBE, 0xCE), 1.0)); } background.Freeze(); CacheFreezable(background, (int)backgroundType); } dc.DrawRectangle(background, null, new Rect(0.0, 0.0, size.Width, size.Height)); if (isHovered && !isPressed && (size.Width >= 6.0) && (size.Height >= 4.0)) { // When hovered, there is a colored tab at the bottom TranslateTransform positionTransform = new TranslateTransform(0.0, size.Height - 3.0); positionTransform.Freeze(); dc.PushTransform(positionTransform); PathGeometry tabGeometry = new PathGeometry(); PathFigure tabFigure = new PathFigure(); tabFigure.StartPoint = new Point(0.5, 0.5); LineSegment line = new LineSegment(new Point(size.Width - 0.5, 0.5), true); line.Freeze(); tabFigure.Segments.Add(line); ArcSegment arc = new ArcSegment(new Point(size.Width - 2.5, 2.5), new Size(2.0, 2.0), 90.0, false, SweepDirection.Clockwise, true); arc.Freeze(); tabFigure.Segments.Add(arc); line = new LineSegment(new Point(2.5, 2.5), true); line.Freeze(); tabFigure.Segments.Add(line); arc = new ArcSegment(new Point(0.5, 0.5), new Size(2.0, 2.0), 90.0, false, SweepDirection.Clockwise, true); arc.Freeze(); tabFigure.Segments.Add(arc); tabFigure.IsClosed = true; tabFigure.Freeze(); tabGeometry.Figures.Add(tabFigure); tabGeometry.Freeze(); Pen tabStroke = (Pen)GetCachedFreezable((int)RoyaleFreezables.TabStroke); if (tabStroke == null) { SolidColorBrush tabStrokeBrush = new SolidColorBrush(Color.FromArgb(0xFF, 0xF8, 0xA9, 0x00)); tabStrokeBrush.Freeze(); tabStroke = new Pen(tabStrokeBrush, 1.0); tabStroke.Freeze(); CacheFreezable(tabStroke, (int)RoyaleFreezables.TabStroke); } LinearGradientBrush tabFill = (LinearGradientBrush)GetCachedFreezable((int)RoyaleFreezables.TabFill); if (tabFill == null) { tabFill = new LinearGradientBrush(); tabFill.StartPoint = new Point(); tabFill.EndPoint = new Point(1.0, 0.0); tabFill.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xFC, 0xE0, 0xA6), 0.0)); tabFill.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xF6, 0xC4, 0x56), 0.1)); tabFill.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xF6, 0xC4, 0x56), 0.9)); tabFill.GradientStops.Add(new GradientStop(Color.FromArgb(0xFF, 0xDF, 0x97, 0x00), 1.0)); tabFill.Freeze(); CacheFreezable(tabFill, (int)RoyaleFreezables.TabFill); } dc.DrawGeometry(tabFill, tabStroke, tabGeometry); dc.Pop(); // Translate Transform } if (isPressed && (size.Width >= 2.0) && (size.Height >= 2.0)) { // When pressed, there is a border on the left and bottom SolidColorBrush border = (SolidColorBrush)GetCachedFreezable((int)RoyaleFreezables.PressedBorder); if (border == null) { border = new SolidColorBrush(Color.FromArgb(0xFF, 0x80, 0x80, 0x99)); border.Freeze(); CacheFreezable(border, (int)RoyaleFreezables.PressedBorder); } dc.DrawRectangle(border, null, new Rect(0.0, 0.0, 1.0, size.Height)); dc.DrawRectangle(border, null, new Rect(0.0, Max0(size.Height - 1.0), size.Width, 1.0)); } if (!isPressed && !isHovered && (size.Width >= 4.0)) { if (SeparatorVisibility == Visibility.Visible) { Brush sideBrush; if (SeparatorBrush != null) { sideBrush = SeparatorBrush; } else { // When not pressed or hovered, draw the resize gripper LinearGradientBrush gripper = (LinearGradientBrush)GetCachedFreezable((int)(horizontal ? RoyaleFreezables.HorizontalGripper : RoyaleFreezables.VerticalGripper)); if (gripper == null) { gripper = new LinearGradientBrush(); gripper.StartPoint = new Point(); gripper.EndPoint = new Point(1.0, 0.0); Color highlight = Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF); Color shadow = Color.FromArgb(0xFF, 0xC7, 0xC5, 0xB2); if (horizontal) { gripper.GradientStops.Add(new GradientStop(highlight, 0.0)); gripper.GradientStops.Add(new GradientStop(highlight, 0.25)); gripper.GradientStops.Add(new GradientStop(shadow, 0.75)); gripper.GradientStops.Add(new GradientStop(shadow, 1.0)); } else { gripper.GradientStops.Add(new GradientStop(shadow, 0.0)); gripper.GradientStops.Add(new GradientStop(shadow, 0.25)); gripper.GradientStops.Add(new GradientStop(highlight, 0.75)); gripper.GradientStops.Add(new GradientStop(highlight, 1.0)); } gripper.Freeze(); CacheFreezable(gripper, (int)(horizontal ? RoyaleFreezables.HorizontalGripper : RoyaleFreezables.VerticalGripper)); } sideBrush = gripper; } dc.DrawRectangle(sideBrush, null, new Rect(horizontal ? 0.0 : Max0(size.Width - 2.0), 4.0, 2.0, Max0(size.Height - 8.0))); } } if (isSorted && (size.Width > 14.0) && (size.Height > 10.0)) { // When sorted, draw an arrow on the right TranslateTransform positionTransform = new TranslateTransform(size.Width - 15.0, (size.Height - 5.0) * 0.5); positionTransform.Freeze(); dc.PushTransform(positionTransform); bool ascending = (sortDirection == ListSortDirection.Ascending); PathGeometry arrowGeometry = (PathGeometry)GetCachedFreezable(ascending ? (int)RoyaleFreezables.ArrowUpGeometry : (int)RoyaleFreezables.ArrowDownGeometry); if (arrowGeometry == null) { arrowGeometry = new PathGeometry(); PathFigure arrowFigure = new PathFigure(); if (ascending) { arrowFigure.StartPoint = new Point(0.0, 5.0); LineSegment line = new LineSegment(new Point(5.0, 0.0), false); line.Freeze(); arrowFigure.Segments.Add(line); line = new LineSegment(new Point(10.0, 5.0), false); line.Freeze(); arrowFigure.Segments.Add(line); } else { arrowFigure.StartPoint = new Point(0.0, 0.0); LineSegment line = new LineSegment(new Point(10.0, 0.0), false); line.Freeze(); arrowFigure.Segments.Add(line); line = new LineSegment(new Point(5.0, 5.0), false); line.Freeze(); arrowFigure.Segments.Add(line); } arrowFigure.IsClosed = true; arrowFigure.Freeze(); arrowGeometry.Figures.Add(arrowFigure); arrowGeometry.Freeze(); CacheFreezable(arrowGeometry, ascending ? (int)RoyaleFreezables.ArrowUpGeometry : (int)RoyaleFreezables.ArrowDownGeometry); } SolidColorBrush arrowFill = (SolidColorBrush)GetCachedFreezable((int)RoyaleFreezables.ArrowFill); if (arrowFill == null) { arrowFill = new SolidColorBrush(Color.FromArgb(0xFF, 0xAC, 0xA8, 0x99)); arrowFill.Freeze(); CacheFreezable(arrowFill, (int)RoyaleFreezables.ArrowFill); } dc.DrawGeometry(arrowFill, null, arrowGeometry); dc.Pop(); // Position Transform } if (horizontal) { dc.Pop(); // Horizontal Rotate } }
private static PathGeometry ArcBlock(Arc arc, double fromAngle, double toAngle, double tickLength) { PathGeometry geometry = new PathGeometry(); PathFigure figure = new PathFigure(); geometry.Figures.Add(figure); var op1 = arc.GetPoint(fromAngle); var ip1 = arc.GetPoint(fromAngle, -1 * tickLength); var op2 = arc.GetPoint(toAngle); var ip2 = arc.GetPoint(toAngle, -1 * tickLength); figure.StartPoint = op1; var rotationAngle = toAngle - fromAngle; var isLargeArc = arc.IsLargeAngle(fromAngle, toAngle); var sweepDirection = arc.SweepDirection(fromAngle, toAngle); figure.Segments.Add(new ArcSegment(op2, new Size(arc.Radius, arc.Radius), rotationAngle, isLargeArc, sweepDirection, true)); figure.Segments.Add(new LineSegment(ip2, true)); sweepDirection = arc.SweepDirection(toAngle, fromAngle); var ri = arc.Radius - tickLength; if (ri < 0) { ri = 0; } figure.Segments.Add(new ArcSegment(ip1, new Size(ri, ri), rotationAngle, isLargeArc, sweepDirection, true)); figure.Segments.Add(new LineSegment(op1, true)); figure.IsClosed = true; figure.Freeze(); geometry.Freeze(); return geometry; }
protected override void OnRender(DrawingContext drawingContext) { var cornerRadius = this.CornerRadius; var rect = new Rect(new Point(ShadowDepth, ShadowDepth), new Size(base.RenderSize.Width, base.RenderSize.Height)); Color c = this.Color; if ((rect.Width <= 0.0 || rect.Height <= 0.0) || c.A <= 0) return; var width = (rect.Right - rect.Left) - 10.0; var height = (rect.Bottom - rect.Top) - 10.0; var minSide = Math.Min(width*ShadowDepth, height*ShadowDepth); cornerRadius.TopLeft = Math.Min(cornerRadius.TopLeft, minSide); cornerRadius.TopRight = Math.Min(cornerRadius.TopRight, minSide); cornerRadius.BottomLeft = Math.Min(cornerRadius.BottomLeft, minSide); cornerRadius.BottomRight = Math.Min(cornerRadius.BottomRight, minSide); Brush[] brushes = this.GetBrushes(c, cornerRadius); var topMargin = rect.Top + ShadowDepth; var leftMargin = rect.Left + ShadowDepth; var rightMargin = rect.Right - ShadowDepth; var bottomMargin = rect.Bottom - ShadowDepth; var guidelinesX = new[] { leftMargin, leftMargin + cornerRadius.TopLeft, rightMargin - cornerRadius.TopRight, leftMargin + cornerRadius.BottomLeft, rightMargin - cornerRadius.BottomRight, rightMargin }; var guidelinesY = new[] { topMargin, topMargin + cornerRadius.TopLeft, topMargin + cornerRadius.TopRight, bottomMargin - cornerRadius.BottomLeft, bottomMargin - cornerRadius.BottomRight, bottomMargin }; drawingContext.PushGuidelineSet(new GuidelineSet(guidelinesX, guidelinesY)); cornerRadius.TopLeft += ShadowDepth; cornerRadius.TopRight += ShadowDepth; cornerRadius.BottomLeft += ShadowDepth; cornerRadius.BottomRight += ShadowDepth; var shadowRect = new Rect(rect.Left, rect.Top, cornerRadius.TopLeft, cornerRadius.TopLeft); drawingContext.DrawRectangle(brushes[0], null, shadowRect); double firstX = guidelinesX[2] - guidelinesX[1]; if (firstX > 0.0) { drawingContext.DrawRectangle(brushes[1], null, new Rect(guidelinesX[1], rect.Top, firstX, 5.0)); } drawingContext.DrawRectangle(brushes[2], null, new Rect(guidelinesX[2], rect.Top, cornerRadius.TopRight, cornerRadius.TopRight)); double firstY = guidelinesY[3] - guidelinesY[1]; if (firstY > 0.0) { drawingContext.DrawRectangle(brushes[3], null, new Rect(rect.Left, guidelinesY[1], 5.0, firstY)); } double middleY = guidelinesY[4] - guidelinesY[2]; if (middleY > 0.0) { drawingContext.DrawRectangle(brushes[5], null, new Rect(guidelinesX[5], guidelinesY[2], 5.0, middleY)); } drawingContext.DrawRectangle(brushes[6], null, new Rect(rect.Left, guidelinesY[3], cornerRadius.BottomLeft, cornerRadius.BottomLeft)); double middleX = guidelinesX[4] - guidelinesX[3]; if (middleX > 0.0) { drawingContext.DrawRectangle(brushes[7], null, new Rect(guidelinesX[3], guidelinesY[5], middleX, 5.0)); } drawingContext.DrawRectangle(brushes[8], null, new Rect(guidelinesX[4], guidelinesY[4], cornerRadius.BottomRight, cornerRadius.BottomRight)); if (cornerRadius.TopLeft == ShadowDepth && cornerRadius.TopLeft == cornerRadius.TopRight && cornerRadius.TopLeft == cornerRadius.BottomLeft && cornerRadius.TopLeft == cornerRadius.BottomRight) { drawingContext.DrawRectangle(brushes[4], null, new Rect(guidelinesX[0], guidelinesY[0], width, height)); } else { var figure = new PathFigure(); if (cornerRadius.TopLeft > ShadowDepth) { figure.StartPoint = new Point(guidelinesX[1], guidelinesY[0]); figure.Segments.Add(new LineSegment(new Point(guidelinesX[1], guidelinesY[1]), true)); figure.Segments.Add(new LineSegment(new Point(guidelinesX[0], guidelinesY[1]), true)); } else { figure.StartPoint = new Point(guidelinesX[0], guidelinesY[0]); } if (cornerRadius.BottomLeft > ShadowDepth) { figure.Segments.Add(new LineSegment(new Point(guidelinesX[0], guidelinesY[3]), true)); figure.Segments.Add(new LineSegment(new Point(guidelinesX[3], guidelinesY[3]), true)); figure.Segments.Add(new LineSegment(new Point(guidelinesX[3], guidelinesY[5]), true)); } else { figure.Segments.Add(new LineSegment(new Point(guidelinesX[0], guidelinesY[5]), true)); } if (cornerRadius.BottomRight > ShadowDepth) { figure.Segments.Add(new LineSegment(new Point(guidelinesX[4], guidelinesY[5]), true)); figure.Segments.Add(new LineSegment(new Point(guidelinesX[4], guidelinesY[4]), true)); figure.Segments.Add(new LineSegment(new Point(guidelinesX[5], guidelinesY[4]), true)); } else { figure.Segments.Add(new LineSegment(new Point(guidelinesX[5], guidelinesY[5]), true)); } if (cornerRadius.TopRight > ShadowDepth) { figure.Segments.Add(new LineSegment(new Point(guidelinesX[5], guidelinesY[2]), true)); figure.Segments.Add(new LineSegment(new Point(guidelinesX[2], guidelinesY[2]), true)); figure.Segments.Add(new LineSegment(new Point(guidelinesX[2], guidelinesY[0]), true)); } else { figure.Segments.Add(new LineSegment(new Point(guidelinesX[5], guidelinesY[0]), true)); } figure.IsClosed = true; figure.Freeze(); var geometry = new PathGeometry(); geometry.Figures.Add(figure); geometry.Freeze(); drawingContext.DrawGeometry(brushes[4], null, geometry); } drawingContext.Pop(); }