|
@@ -7,7 +7,6 @@ using PixiEditor.Models.Controllers.InputDevice;
|
|
using Drawie.Backend.Core.Numerics;
|
|
using Drawie.Backend.Core.Numerics;
|
|
using Drawie.Backend.Core.Surfaces;
|
|
using Drawie.Backend.Core.Surfaces;
|
|
using Drawie.Backend.Core.Surfaces.PaintImpl;
|
|
using Drawie.Backend.Core.Surfaces.PaintImpl;
|
|
-using Drawie.Backend.Core.Surfaces.Vector;
|
|
|
|
using PixiEditor.Extensions.UI.Overlays;
|
|
using PixiEditor.Extensions.UI.Overlays;
|
|
using Drawie.Numerics;
|
|
using Drawie.Numerics;
|
|
using PixiEditor.Views.Overlays.Drawables;
|
|
using PixiEditor.Views.Overlays.Drawables;
|
|
@@ -17,6 +16,7 @@ using Colors = Drawie.Backend.Core.ColorsImpl.Colors;
|
|
using Point = Avalonia.Point;
|
|
using Point = Avalonia.Point;
|
|
|
|
|
|
namespace PixiEditor.Views.Overlays.LineToolOverlay;
|
|
namespace PixiEditor.Views.Overlays.LineToolOverlay;
|
|
|
|
+
|
|
internal class LineToolOverlay : Overlay
|
|
internal class LineToolOverlay : Overlay
|
|
{
|
|
{
|
|
public static readonly StyledProperty<VecD> LineStartProperty =
|
|
public static readonly StyledProperty<VecD> LineStartProperty =
|
|
@@ -46,8 +46,9 @@ internal class LineToolOverlay : Overlay
|
|
set => SetValue(ActionCompletedProperty, value);
|
|
set => SetValue(ActionCompletedProperty, value);
|
|
}
|
|
}
|
|
|
|
|
|
- public static readonly StyledProperty<SnappingController> SnappingControllerProperty = AvaloniaProperty.Register<LineToolOverlay, SnappingController>(
|
|
|
|
- nameof(SnappingController));
|
|
|
|
|
|
+ public static readonly StyledProperty<SnappingController> SnappingControllerProperty =
|
|
|
|
+ AvaloniaProperty.Register<LineToolOverlay, SnappingController>(
|
|
|
|
+ nameof(SnappingController));
|
|
|
|
|
|
public SnappingController SnappingController
|
|
public SnappingController SnappingController
|
|
{
|
|
{
|
|
@@ -64,30 +65,34 @@ internal class LineToolOverlay : Overlay
|
|
set => SetValue(ShowHandlesProperty, value);
|
|
set => SetValue(ShowHandlesProperty, value);
|
|
}
|
|
}
|
|
|
|
|
|
- public static readonly StyledProperty<bool> IsSizeBoxEnabledProperty = AvaloniaProperty.Register<LineToolOverlay, bool>(
|
|
|
|
- nameof(IsSizeBoxEnabled));
|
|
|
|
|
|
+ public static readonly StyledProperty<bool> IsSizeBoxEnabledProperty =
|
|
|
|
+ AvaloniaProperty.Register<LineToolOverlay, bool>(
|
|
|
|
+ nameof(IsSizeBoxEnabled));
|
|
|
|
|
|
public bool IsSizeBoxEnabled
|
|
public bool IsSizeBoxEnabled
|
|
{
|
|
{
|
|
get => GetValue(IsSizeBoxEnabledProperty);
|
|
get => GetValue(IsSizeBoxEnabledProperty);
|
|
set => SetValue(IsSizeBoxEnabledProperty, value);
|
|
set => SetValue(IsSizeBoxEnabledProperty, value);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
static LineToolOverlay()
|
|
static LineToolOverlay()
|
|
{
|
|
{
|
|
LineStartProperty.Changed.Subscribe(RenderAffectingPropertyChanged);
|
|
LineStartProperty.Changed.Subscribe(RenderAffectingPropertyChanged);
|
|
LineEndProperty.Changed.Subscribe(RenderAffectingPropertyChanged);
|
|
LineEndProperty.Changed.Subscribe(RenderAffectingPropertyChanged);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
|
|
- private Paint blackPaint = new Paint() { Color = Colors.Black, StrokeWidth = 1, Style = PaintStyle.Stroke, IsAntiAliased = true };
|
|
|
|
- private Paint whiteDashPaint = new Paint() { Color = Colors.White, StrokeWidth = 1, Style = PaintStyle.Stroke, PathEffect = PathEffect.CreateDash(
|
|
|
|
- [2, 2], 2), IsAntiAliased = true };
|
|
|
|
|
|
+
|
|
|
|
+ private DashedStroke dashedStroke = new DashedStroke();
|
|
|
|
+
|
|
|
|
+ private Paint blackPaint = new Paint()
|
|
|
|
+ {
|
|
|
|
+ Color = Colors.Black, StrokeWidth = 1, Style = PaintStyle.Stroke, IsAntiAliased = true
|
|
|
|
+ };
|
|
|
|
|
|
private VecD mouseDownPos = VecD.Zero;
|
|
private VecD mouseDownPos = VecD.Zero;
|
|
private VecD lineStartOnMouseDown = VecD.Zero;
|
|
private VecD lineStartOnMouseDown = VecD.Zero;
|
|
private VecD lineEndOnMouseDown = VecD.Zero;
|
|
private VecD lineEndOnMouseDown = VecD.Zero;
|
|
-
|
|
|
|
|
|
+
|
|
private VecD lastMousePos = VecD.Zero;
|
|
private VecD lastMousePos = VecD.Zero;
|
|
|
|
|
|
private bool movedWhileMouseDown = false;
|
|
private bool movedWhileMouseDown = false;
|
|
@@ -95,7 +100,7 @@ internal class LineToolOverlay : Overlay
|
|
private RectangleHandle startHandle;
|
|
private RectangleHandle startHandle;
|
|
private RectangleHandle endHandle;
|
|
private RectangleHandle endHandle;
|
|
private TransformHandle moveHandle;
|
|
private TransformHandle moveHandle;
|
|
-
|
|
|
|
|
|
+
|
|
private bool isDraggingHandle = false;
|
|
private bool isDraggingHandle = false;
|
|
private InfoBox infoBox;
|
|
private InfoBox infoBox;
|
|
|
|
|
|
@@ -129,7 +134,7 @@ internal class LineToolOverlay : Overlay
|
|
moveHandle.OnHover += handle => Refresh();
|
|
moveHandle.OnHover += handle => Refresh();
|
|
moveHandle.OnRelease += OnHandleRelease;
|
|
moveHandle.OnRelease += OnHandleRelease;
|
|
AddHandle(moveHandle);
|
|
AddHandle(moveHandle);
|
|
-
|
|
|
|
|
|
+
|
|
infoBox = new InfoBox();
|
|
infoBox = new InfoBox();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -147,25 +152,15 @@ internal class LineToolOverlay : Overlay
|
|
SnappingController.HighlightedYAxis = null;
|
|
SnappingController.HighlightedYAxis = null;
|
|
Refresh();
|
|
Refresh();
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
isDraggingHandle = false;
|
|
isDraggingHandle = false;
|
|
IsSizeBoxEnabled = false;
|
|
IsSizeBoxEnabled = false;
|
|
}
|
|
}
|
|
|
|
|
|
protected override void ZoomChanged(double newZoom)
|
|
protected override void ZoomChanged(double newZoom)
|
|
{
|
|
{
|
|
- blackPaint.StrokeWidth = (float)(1.0 / newZoom);
|
|
|
|
-
|
|
|
|
- whiteDashPaint.StrokeWidth = (float)(2.0 / newZoom);
|
|
|
|
- whiteDashPaint?.PathEffect?.Dispose();
|
|
|
|
-
|
|
|
|
- float[] dashes = new float[] { whiteDashPaint.StrokeWidth * 4, whiteDashPaint.StrokeWidth * 3 };
|
|
|
|
-
|
|
|
|
- dashes[0] = whiteDashPaint.StrokeWidth * 4;
|
|
|
|
- dashes[1] = whiteDashPaint.StrokeWidth * 3;
|
|
|
|
-
|
|
|
|
- whiteDashPaint.PathEffect = PathEffect.CreateDash(dashes, 2);
|
|
|
|
-
|
|
|
|
|
|
+ blackPaint.StrokeWidth = 1 / (float)newZoom;
|
|
|
|
+ dashedStroke.UpdateZoom((float)newZoom);
|
|
infoBox.ZoomScale = newZoom;
|
|
infoBox.ZoomScale = newZoom;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -173,17 +168,16 @@ internal class LineToolOverlay : Overlay
|
|
{
|
|
{
|
|
VecD mappedStart = LineStart;
|
|
VecD mappedStart = LineStart;
|
|
VecD mappedEnd = LineEnd;
|
|
VecD mappedEnd = LineEnd;
|
|
-
|
|
|
|
|
|
+
|
|
startHandle.Position = mappedStart;
|
|
startHandle.Position = mappedStart;
|
|
- endHandle.Position = mappedEnd;
|
|
|
|
-
|
|
|
|
|
|
+ endHandle.Position = mappedEnd;
|
|
|
|
+
|
|
VecD center = (mappedStart + mappedEnd) / 2;
|
|
VecD center = (mappedStart + mappedEnd) / 2;
|
|
VecD size = mappedEnd - mappedStart;
|
|
VecD size = mappedEnd - mappedStart;
|
|
-
|
|
|
|
|
|
+
|
|
moveHandle.Position = TransformHelper.GetHandlePos(new ShapeCorners(center, size), ZoomScale, moveHandle.Size);
|
|
moveHandle.Position = TransformHelper.GetHandlePos(new ShapeCorners(center, size), ZoomScale, moveHandle.Size);
|
|
|
|
|
|
- context.DrawLine(new VecD(mappedStart.X, mappedStart.Y), new VecD(mappedEnd.X, mappedEnd.Y), blackPaint);
|
|
|
|
- context.DrawLine(new VecD(mappedStart.X, mappedStart.Y), new VecD(mappedEnd.X, mappedEnd.Y), whiteDashPaint);
|
|
|
|
|
|
+ dashedStroke.Draw(context, mappedStart, mappedEnd);
|
|
|
|
|
|
if (ShowHandles)
|
|
if (ShowHandles)
|
|
{
|
|
{
|
|
@@ -217,7 +211,7 @@ internal class LineToolOverlay : Overlay
|
|
VecD delta = position - mouseDownPos;
|
|
VecD delta = position - mouseDownPos;
|
|
LineStart = SnapAndHighlight(lineStartOnMouseDown + delta);
|
|
LineStart = SnapAndHighlight(lineStartOnMouseDown + delta);
|
|
movedWhileMouseDown = true;
|
|
movedWhileMouseDown = true;
|
|
-
|
|
|
|
|
|
+
|
|
lastMousePos = position;
|
|
lastMousePos = position;
|
|
isDraggingHandle = true;
|
|
isDraggingHandle = true;
|
|
IsSizeBoxEnabled = true;
|
|
IsSizeBoxEnabled = true;
|
|
@@ -227,10 +221,10 @@ internal class LineToolOverlay : Overlay
|
|
{
|
|
{
|
|
VecD delta = position - mouseDownPos;
|
|
VecD delta = position - mouseDownPos;
|
|
VecD final = SnapAndHighlight(lineEndOnMouseDown + delta);
|
|
VecD final = SnapAndHighlight(lineEndOnMouseDown + delta);
|
|
-
|
|
|
|
|
|
+
|
|
LineEnd = final;
|
|
LineEnd = final;
|
|
movedWhileMouseDown = true;
|
|
movedWhileMouseDown = true;
|
|
-
|
|
|
|
|
|
+
|
|
isDraggingHandle = true;
|
|
isDraggingHandle = true;
|
|
lastMousePos = position;
|
|
lastMousePos = position;
|
|
IsSizeBoxEnabled = true;
|
|
IsSizeBoxEnabled = true;
|
|
@@ -243,17 +237,17 @@ internal class LineToolOverlay : Overlay
|
|
{
|
|
{
|
|
double? x = SnappingController.SnapToHorizontal(position.X, out string snapAxisX);
|
|
double? x = SnappingController.SnapToHorizontal(position.X, out string snapAxisX);
|
|
double? y = SnappingController.SnapToVertical(position.Y, out string snapAxisY);
|
|
double? y = SnappingController.SnapToVertical(position.Y, out string snapAxisY);
|
|
-
|
|
|
|
|
|
+
|
|
if (x.HasValue)
|
|
if (x.HasValue)
|
|
{
|
|
{
|
|
final = new VecD(x.Value, final.Y);
|
|
final = new VecD(x.Value, final.Y);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
if (y.HasValue)
|
|
if (y.HasValue)
|
|
{
|
|
{
|
|
final = new VecD(final.X, y.Value);
|
|
final = new VecD(final.X, y.Value);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
SnappingController.HighlightedXAxis = snapAxisX;
|
|
SnappingController.HighlightedXAxis = snapAxisX;
|
|
SnappingController.HighlightedYAxis = snapAxisY;
|
|
SnappingController.HighlightedYAxis = snapAxisY;
|
|
}
|
|
}
|
|
@@ -264,7 +258,7 @@ internal class LineToolOverlay : Overlay
|
|
private void MoveHandleOnDrag(Handle source, VecD position)
|
|
private void MoveHandleOnDrag(Handle source, VecD position)
|
|
{
|
|
{
|
|
var delta = position - mouseDownPos;
|
|
var delta = position - mouseDownPos;
|
|
-
|
|
|
|
|
|
+
|
|
VecD mappedStart = lineStartOnMouseDown;
|
|
VecD mappedStart = lineStartOnMouseDown;
|
|
VecD mappedEnd = lineEndOnMouseDown;
|
|
VecD mappedEnd = lineEndOnMouseDown;
|
|
|
|
|
|
@@ -275,7 +269,7 @@ internal class LineToolOverlay : Overlay
|
|
SnappingController.HighlightedXAxis = snapDeltaResult.Item1.Item1;
|
|
SnappingController.HighlightedXAxis = snapDeltaResult.Item1.Item1;
|
|
SnappingController.HighlightedYAxis = snapDeltaResult.Item1.Item2;
|
|
SnappingController.HighlightedYAxis = snapDeltaResult.Item1.Item2;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
LineStart = lineStartOnMouseDown + delta + snapDeltaResult.Item2;
|
|
LineStart = lineStartOnMouseDown + delta + snapDeltaResult.Item2;
|
|
LineEnd = lineEndOnMouseDown + delta + snapDeltaResult.Item2;
|
|
LineEnd = lineEndOnMouseDown + delta + snapDeltaResult.Item2;
|
|
|
|
|
|
@@ -289,7 +283,6 @@ internal class LineToolOverlay : Overlay
|
|
|
|
|
|
if (movedWhileMouseDown && ActionCompleted is not null && ActionCompleted.CanExecute(null))
|
|
if (movedWhileMouseDown && ActionCompleted is not null && ActionCompleted.CanExecute(null))
|
|
ActionCompleted.Execute(null);
|
|
ActionCompleted.Execute(null);
|
|
-
|
|
|
|
}
|
|
}
|
|
|
|
|
|
private ((string, string), VecD) TrySnapLine(VecD originalStart, VecD originalEnd, VecD delta)
|
|
private ((string, string), VecD) TrySnapLine(VecD originalStart, VecD originalEnd, VecD delta)
|
|
@@ -298,21 +291,17 @@ internal class LineToolOverlay : Overlay
|
|
{
|
|
{
|
|
return ((string.Empty, string.Empty), delta);
|
|
return ((string.Empty, string.Empty), delta);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
VecD center = (originalStart + originalEnd) / 2f;
|
|
VecD center = (originalStart + originalEnd) / 2f;
|
|
- VecD[] pointsToTest = new VecD[]
|
|
|
|
- {
|
|
|
|
- center + delta,
|
|
|
|
- originalStart + delta,
|
|
|
|
- originalEnd + delta,
|
|
|
|
- };
|
|
|
|
|
|
+ VecD[] pointsToTest = new VecD[] { center + delta, originalStart + delta, originalEnd + delta, };
|
|
|
|
|
|
- VecD snapDelta = SnappingController.GetSnapDeltaForPoints(pointsToTest, out string snapAxisX, out string snapAxisY);
|
|
|
|
|
|
+ VecD snapDelta =
|
|
|
|
+ SnappingController.GetSnapDeltaForPoints(pointsToTest, out string snapAxisX, out string snapAxisY);
|
|
|
|
|
|
return ((snapAxisX, snapAxisY), snapDelta);
|
|
return ((snapAxisX, snapAxisY), snapDelta);
|
|
}
|
|
}
|
|
-
|
|
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+
|
|
private static void RenderAffectingPropertyChanged(AvaloniaPropertyChangedEventArgs<VecD> e)
|
|
private static void RenderAffectingPropertyChanged(AvaloniaPropertyChangedEventArgs<VecD> e)
|
|
{
|
|
{
|
|
if (e.Sender is LineToolOverlay overlay)
|
|
if (e.Sender is LineToolOverlay overlay)
|