| File: MS\Internal\Controls\InkCanvasFeedbackAdorner.cs | Web Access |
| Project: src\wpf\src\Microsoft.DotNet.Wpf\src\PresentationFramework\PresentationFramework.csproj (PresentationFramework) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // // Description: // A class which is used as the feedback adorner of the InkCanvas selection // using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Media; namespace MS.Internal.Controls { /// <summary> /// InkCanvasFeedbackAdorner /// </summary> internal class InkCanvasFeedbackAdorner : Adorner { // No default constructor private InkCanvasFeedbackAdorner() : base(null) { } /// <summary> /// InkCanvasFeedbackAdorner Constructor /// </summary> /// <param name="inkCanvas">The adorned InkCanvas</param> internal InkCanvasFeedbackAdorner(InkCanvas inkCanvas) : base((inkCanvas?.InnerCanvas)) { ArgumentNullException.ThrowIfNull(inkCanvas); // Initialize the internal data _inkCanvas = inkCanvas; _adornerBorderPen = new Pen(Brushes.Black, 1.0); DoubleCollection dashes = new DoubleCollection(); dashes.Add(4.5); dashes.Add(4.5); _adornerBorderPen.DashStyle = new DashStyle(dashes, 2.25); _adornerBorderPen.DashCap = PenLineCap.Flat; } /// <summary> /// The overridden GetDesiredTransform method /// </summary> public override GeneralTransform GetDesiredTransform(GeneralTransform transform) { ArgumentNullException.ThrowIfNull(transform); VerifyAccess(); GeneralTransformGroup desiredTransform = new GeneralTransformGroup(); desiredTransform.Children.Add(transform); // Check if we need translate the adorner. if (!DoubleUtil.AreClose(_offsetX, 0) || !DoubleUtil.AreClose(_offsetY, 0)) { desiredTransform.Children.Add(new TranslateTransform(_offsetX, _offsetY)); } return desiredTransform; } /// <summary> /// The OnBoundsUpdated method /// </summary> /// <param name="rect"></param> private void OnBoundsUpdated(Rect rect) { VerifyAccess(); // Check if the rectangle has been changed. if (rect != _previousRect) { Size newSize; double offsetX; double offsetY; bool invalidArrange = false; if (!rect.IsEmpty) { double offset = BorderMargin + CornerResizeHandleSize / 2; Rect adornerRect = Rect.Inflate(rect, offset, offset); newSize = new Size(adornerRect.Width, adornerRect.Height); offsetX = adornerRect.Left; offsetY = adornerRect.Top; } else { newSize = new Size(0, 0); offsetX = 0; offsetY = 0; } // Check if the size has been changed if (_frameSize != newSize) { _frameSize = newSize; invalidArrange = true; } if (!DoubleUtil.AreClose(_offsetX, offsetX) || !DoubleUtil.AreClose(_offsetY, offsetY)) { _offsetX = offsetX; _offsetY = offsetY; invalidArrange = true; } if (invalidArrange) { InvalidateMeasure(); InvalidateVisual(); //ensure re-rendering UIElement parent = ((UIElement)VisualTreeHelper.GetParent(this)) as UIElement; if (parent != null) { ((UIElement)VisualTreeHelper.GetParent(this)).InvalidateArrange(); } } _previousRect = rect; } } /// <summary> /// The overridden MeasureOverride method /// </summary> /// <param name="constraint"></param> protected override Size MeasureOverride(Size constraint) { VerifyAccess(); // return the frame size. return _frameSize; } /// <summary> /// The overridden OnRender method /// </summary> /// <param name="drawingContext"></param> protected override void OnRender(DrawingContext drawingContext) { // No need to invoke VerifyAccess since this method calls DrawingContext.DrawRectangle. Debug.Assert(_frameSize != new Size(0, 0)); // Draw the wire frame. drawingContext.DrawRectangle(null, _adornerBorderPen, new Rect(CornerResizeHandleSize / 2, CornerResizeHandleSize / 2, _frameSize.Width - CornerResizeHandleSize, _frameSize.Height - CornerResizeHandleSize)); } /// <summary> /// The method is called by InkCanvasSelection.UpdateFeedbackRect /// </summary> /// <param name="rect"></param> internal void UpdateBounds(Rect rect) { // Invoke OnBoundsUpdated. OnBoundsUpdated(rect); } private InkCanvas _inkCanvas; private Size _frameSize = new Size(0, 0); private Rect _previousRect = Rect.Empty; private double _offsetX = 0; private double _offsetY = 0; private Pen _adornerBorderPen; private const int CornerResizeHandleSize = 8; private const double BorderMargin = 8f; } }