|
@@ -0,0 +1,161 @@
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Linq;
|
|
|
+using System.Text;
|
|
|
+using System.Threading.Tasks;
|
|
|
+using System.Windows;
|
|
|
+using System.Windows.Controls;
|
|
|
+using System.Windows.Input;
|
|
|
+using System.Windows.Media;
|
|
|
+using ChunkyImageLib.DataHolders;
|
|
|
+using PixiEditor;
|
|
|
+using PixiEditor.DrawingApi.Core.Numerics;
|
|
|
+using PixiEditor.Views;
|
|
|
+using PixiEditor.Views.UserControls;
|
|
|
+using PixiEditor.Views.UserControls.Overlays;
|
|
|
+using PixiEditor.Views.UserControls.Overlays.LineToolOverlay;
|
|
|
+using PixiEditor.Views.UserControls.Overlays.TransformOverlay;
|
|
|
+using TerraFX.Interop.Windows;
|
|
|
+
|
|
|
+namespace PixiEditor.Views.UserControls.Overlays.LineToolOverlay;
|
|
|
+internal class LineToolOverlay : Control
|
|
|
+{
|
|
|
+ public static readonly DependencyProperty ZoomboxScaleProperty =
|
|
|
+ DependencyProperty.Register(nameof(ZoomboxScale), typeof(double), typeof(LineToolOverlay),
|
|
|
+ new FrameworkPropertyMetadata(1.0, FrameworkPropertyMetadataOptions.AffectsRender, OnZoomboxScaleChanged));
|
|
|
+
|
|
|
+ public static readonly DependencyProperty LineStartProperty =
|
|
|
+ DependencyProperty.Register(nameof(LineStart), typeof(VecD), typeof(LineToolOverlay),
|
|
|
+ new FrameworkPropertyMetadata(VecD.Zero, FrameworkPropertyMetadataOptions.AffectsRender));
|
|
|
+
|
|
|
+ public static readonly DependencyProperty LineEndProperty =
|
|
|
+ DependencyProperty.Register(nameof(LineEnd), typeof(VecD), typeof(LineToolOverlay),
|
|
|
+ new FrameworkPropertyMetadata(VecD.Zero, FrameworkPropertyMetadataOptions.AffectsRender));
|
|
|
+
|
|
|
+ public VecD LineEnd
|
|
|
+ {
|
|
|
+ get => (VecD)GetValue(LineEndProperty);
|
|
|
+ set => SetValue(LineEndProperty, value);
|
|
|
+ }
|
|
|
+
|
|
|
+ public VecD LineStart
|
|
|
+ {
|
|
|
+ get => (VecD)GetValue(LineStartProperty);
|
|
|
+ set => SetValue(LineStartProperty, value);
|
|
|
+ }
|
|
|
+
|
|
|
+ public double ZoomboxScale
|
|
|
+ {
|
|
|
+ get => (double)GetValue(ZoomboxScaleProperty);
|
|
|
+ set => SetValue(ZoomboxScaleProperty, value);
|
|
|
+ }
|
|
|
+
|
|
|
+ private Pen blackPen = new Pen(Brushes.Black, 1);
|
|
|
+
|
|
|
+ private VecD mouseDownPos = VecD.Zero;
|
|
|
+ private VecD lineStartOnMouseDown = VecD.Zero;
|
|
|
+ private VecD lineEndOnMouseDown = VecD.Zero;
|
|
|
+
|
|
|
+ private LineToolOverlayAnchor? capturedAnchor = null;
|
|
|
+ private bool dragging = false;
|
|
|
+
|
|
|
+ private PathGeometry handleGeometry = new()
|
|
|
+ {
|
|
|
+ FillRule = FillRule.Nonzero,
|
|
|
+ Figures = (PathFigureCollection)new PathFigureCollectionConverter()
|
|
|
+ .ConvertFrom("M 0.50025839 0 0.4248062 0.12971572 0.34987079 0.25994821 h 0.1002584 V 0.45012906 H 0.25994831 V 0.34987066 L 0.12971577 0.42480604 0 0.5002582 0.12971577 0.57519373 0.25994831 0.65012926 V 0.5498709 H 0.45012919 V 0.74005175 H 0.34987079 L 0.42480619 0.87028439 0.50025839 1 0.57519399 0.87028439 0.65012959 0.74005175 H 0.54987119 V 0.5498709 H 0.74005211 V 0.65012926 L 0.87028423 0.57519358 1 0.5002582 0.87028423 0.42480604 0.74005169 0.34987066 v 0.1002584 H 0.54987077 V 0.25994821 h 0.1002584 L 0.5751938 0.12971572 Z"),
|
|
|
+ };
|
|
|
+
|
|
|
+ public LineToolOverlay()
|
|
|
+ {
|
|
|
+ Cursor = Cursors.Arrow;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void OnZoomboxScaleChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
|
|
|
+ {
|
|
|
+ var self = (LineToolOverlay)obj;
|
|
|
+ double newScale = (double)args.NewValue;
|
|
|
+ self.blackPen.Thickness = 1.0 / newScale;
|
|
|
+ }
|
|
|
+
|
|
|
+ protected override void OnRender(DrawingContext context)
|
|
|
+ {
|
|
|
+ context.DrawRectangle(Brushes.White, blackPen, TransformHelper.ToAnchorRect(LineStart, ZoomboxScale));
|
|
|
+ context.DrawRectangle(Brushes.White, blackPen, TransformHelper.ToAnchorRect(LineEnd, ZoomboxScale));
|
|
|
+
|
|
|
+ VecD handlePos = TransformHelper.GetDragHandlePos(new ShapeCorners(new RectD(LineStart, LineEnd - LineStart)), ZoomboxScale);
|
|
|
+ const double CrossSize = TransformHelper.MoveHandleSize - 1;
|
|
|
+ context.DrawRectangle(Brushes.White, blackPen, TransformHelper.ToHandleRect(handlePos, ZoomboxScale));
|
|
|
+ handleGeometry.Transform = new MatrixTransform(
|
|
|
+ 0, CrossSize / ZoomboxScale,
|
|
|
+ CrossSize / ZoomboxScale, 0,
|
|
|
+ handlePos.X - CrossSize / (ZoomboxScale * 2), handlePos.Y - CrossSize / (ZoomboxScale * 2)
|
|
|
+ );
|
|
|
+ context.DrawGeometry(Brushes.Black, null, handleGeometry);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected override void OnMouseDown(MouseButtonEventArgs e)
|
|
|
+ {
|
|
|
+ base.OnMouseDown(e);
|
|
|
+ if (e.ChangedButton != MouseButton.Left)
|
|
|
+ return;
|
|
|
+
|
|
|
+ e.Handled = true;
|
|
|
+
|
|
|
+ VecD pos = TransformHelper.ToVecD(e.GetPosition(this));
|
|
|
+ VecD handlePos = TransformHelper.GetDragHandlePos(new ShapeCorners(new RectD(LineStart, LineEnd - LineStart)), ZoomboxScale);
|
|
|
+
|
|
|
+ if (TransformHelper.IsWithinAnchor(LineStart, pos, ZoomboxScale))
|
|
|
+ capturedAnchor = LineToolOverlayAnchor.Start;
|
|
|
+ else if (TransformHelper.IsWithinAnchor(LineEnd, pos, ZoomboxScale))
|
|
|
+ capturedAnchor = LineToolOverlayAnchor.End;
|
|
|
+ else if (TransformHelper.IsWithinTransformHandle(handlePos, pos, ZoomboxScale))
|
|
|
+ dragging = true;
|
|
|
+
|
|
|
+ mouseDownPos = pos;
|
|
|
+ lineStartOnMouseDown = LineStart;
|
|
|
+ lineEndOnMouseDown = LineEnd;
|
|
|
+
|
|
|
+ CaptureMouse();
|
|
|
+ }
|
|
|
+
|
|
|
+ protected override void OnMouseMove(MouseEventArgs e)
|
|
|
+ {
|
|
|
+ base.OnMouseMove(e);
|
|
|
+ e.Handled = true;
|
|
|
+
|
|
|
+ VecD pos = TransformHelper.ToVecD(e.GetPosition(this));
|
|
|
+ if (capturedAnchor == LineToolOverlayAnchor.Start)
|
|
|
+ {
|
|
|
+ LineStart = pos;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (capturedAnchor == LineToolOverlayAnchor.End)
|
|
|
+ {
|
|
|
+ LineEnd = pos;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (dragging)
|
|
|
+ {
|
|
|
+ var delta = pos - mouseDownPos;
|
|
|
+ LineStart = lineStartOnMouseDown + delta;
|
|
|
+ LineEnd = lineEndOnMouseDown + delta;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected override void OnMouseUp(MouseButtonEventArgs e)
|
|
|
+ {
|
|
|
+ base.OnMouseUp(e);
|
|
|
+ if (e.ChangedButton != MouseButton.Left)
|
|
|
+ return;
|
|
|
+
|
|
|
+ e.Handled = true;
|
|
|
+ capturedAnchor = null;
|
|
|
+ dragging = false;
|
|
|
+
|
|
|
+ ReleaseMouseCapture();
|
|
|
+ }
|
|
|
+}
|