|
@@ -28,6 +28,9 @@ internal class TransformOverlay : Control
|
|
DependencyProperty.Register(nameof(CornerFreedom), typeof(TransformCornerFreedom), typeof(TransformOverlay),
|
|
DependencyProperty.Register(nameof(CornerFreedom), typeof(TransformCornerFreedom), typeof(TransformOverlay),
|
|
new PropertyMetadata(TransformCornerFreedom.Locked));
|
|
new PropertyMetadata(TransformCornerFreedom.Locked));
|
|
|
|
|
|
|
|
+ public static readonly DependencyProperty LockRotationProperty =
|
|
|
|
+ DependencyProperty.Register(nameof(LockRotation), typeof(bool), typeof(TransformOverlay), new(false));
|
|
|
|
+
|
|
public static readonly DependencyProperty SnapToAnglesProperty =
|
|
public static readonly DependencyProperty SnapToAnglesProperty =
|
|
DependencyProperty.Register(nameof(SnapToAngles), typeof(bool), typeof(TransformOverlay), new PropertyMetadata(false));
|
|
DependencyProperty.Register(nameof(SnapToAngles), typeof(bool), typeof(TransformOverlay), new PropertyMetadata(false));
|
|
|
|
|
|
@@ -77,6 +80,12 @@ internal class TransformOverlay : Control
|
|
set => SetValue(ZoomboxScaleProperty, value);
|
|
set => SetValue(ZoomboxScaleProperty, value);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ public bool LockRotation
|
|
|
|
+ {
|
|
|
|
+ get => (bool)GetValue(LockRotationProperty);
|
|
|
|
+ set => SetValue(LockRotationProperty, value);
|
|
|
|
+ }
|
|
|
|
+
|
|
private bool isResettingRequestedCorners = false;
|
|
private bool isResettingRequestedCorners = false;
|
|
private bool isMoving = false;
|
|
private bool isMoving = false;
|
|
private VecD mousePosOnStartMove = new();
|
|
private VecD mousePosOnStartMove = new();
|
|
@@ -174,8 +183,8 @@ internal class TransformOverlay : Control
|
|
base.OnMouseDown(e);
|
|
base.OnMouseDown(e);
|
|
|
|
|
|
e.Handled = true;
|
|
e.Handled = true;
|
|
- var pos = TransformHelper.ToVecD(e.GetPosition(this));
|
|
|
|
- var anchor = TransformHelper.GetAnchorInPosition(pos, Corners, InternalState.Origin, ZoomboxScale);
|
|
|
|
|
|
+ VecD pos = TransformHelper.ToVecD(e.GetPosition(this));
|
|
|
|
+ Anchor? anchor = TransformHelper.GetAnchorInPosition(pos, Corners, InternalState.Origin, ZoomboxScale);
|
|
if (anchor is not null)
|
|
if (anchor is not null)
|
|
{
|
|
{
|
|
capturedAnchor = anchor;
|
|
capturedAnchor = anchor;
|
|
@@ -190,7 +199,7 @@ internal class TransformOverlay : Control
|
|
originOnStartMove = InternalState.Origin;
|
|
originOnStartMove = InternalState.Origin;
|
|
cornersOnStartMove = Corners;
|
|
cornersOnStartMove = Corners;
|
|
}
|
|
}
|
|
- else
|
|
|
|
|
|
+ else if (!LockRotation)
|
|
{
|
|
{
|
|
isRotating = true;
|
|
isRotating = true;
|
|
mousePosOnStartRotate = TransformHelper.ToVecD(e.GetPosition(this));
|
|
mousePosOnStartRotate = TransformHelper.ToVecD(e.GetPosition(this));
|
|
@@ -198,6 +207,10 @@ internal class TransformOverlay : Control
|
|
propAngle1OnStartRotate = InternalState.ProportionalAngle1;
|
|
propAngle1OnStartRotate = InternalState.ProportionalAngle1;
|
|
propAngle2OnStartRotate = InternalState.ProportionalAngle2;
|
|
propAngle2OnStartRotate = InternalState.ProportionalAngle2;
|
|
}
|
|
}
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
CaptureMouse();
|
|
CaptureMouse();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -211,8 +224,8 @@ internal class TransformOverlay : Control
|
|
|
|
|
|
if (isMoving)
|
|
if (isMoving)
|
|
{
|
|
{
|
|
- var pos = TransformHelper.ToVecD(e.GetPosition(this));
|
|
|
|
- var delta = pos - mousePosOnStartMove;
|
|
|
|
|
|
+ VecD pos = TransformHelper.ToVecD(e.GetPosition(this));
|
|
|
|
+ VecD delta = pos - mousePosOnStartMove;
|
|
|
|
|
|
if (Corners.IsSnappedToPixels)
|
|
if (Corners.IsSnappedToPixels)
|
|
delta = delta.Round();
|
|
delta = delta.Round();
|
|
@@ -229,8 +242,8 @@ internal class TransformOverlay : Control
|
|
}
|
|
}
|
|
else if (isRotating)
|
|
else if (isRotating)
|
|
{
|
|
{
|
|
- var pos = TransformHelper.ToVecD(e.GetPosition(this));
|
|
|
|
- var angle = (mousePosOnStartRotate - InternalState.Origin).CCWAngleTo(pos - InternalState.Origin);
|
|
|
|
|
|
+ VecD pos = TransformHelper.ToVecD(e.GetPosition(this));
|
|
|
|
+ double angle = (mousePosOnStartRotate - InternalState.Origin).CCWAngleTo(pos - InternalState.Origin);
|
|
if (SnapToAngles)
|
|
if (SnapToAngles)
|
|
angle = TransformHelper.FindSnappingAngle(cornersOnStartRotate, angle);
|
|
angle = TransformHelper.FindSnappingAngle(cornersOnStartRotate, angle);
|
|
InternalState = InternalState with { ProportionalAngle1 = propAngle1OnStartRotate + angle, ProportionalAngle2 = propAngle2OnStartRotate + angle, };
|
|
InternalState = InternalState with { ProportionalAngle1 = propAngle1OnStartRotate + angle, ProportionalAngle2 = propAngle2OnStartRotate + angle, };
|
|
@@ -243,16 +256,16 @@ internal class TransformOverlay : Control
|
|
if (capturedAnchor is null)
|
|
if (capturedAnchor is null)
|
|
throw new InvalidOperationException("No anchor is captured");
|
|
throw new InvalidOperationException("No anchor is captured");
|
|
e.Handled = true;
|
|
e.Handled = true;
|
|
- if (TransformHelper.IsCorner((Anchor)capturedAnchor) && CornerFreedom == TransformCornerFreedom.Locked ||
|
|
|
|
- TransformHelper.IsSide((Anchor)capturedAnchor) && SideFreedom == TransformSideFreedom.Locked)
|
|
|
|
|
|
+ if ((TransformHelper.IsCorner((Anchor)capturedAnchor) && CornerFreedom == TransformCornerFreedom.Locked) ||
|
|
|
|
+ (TransformHelper.IsSide((Anchor)capturedAnchor) && SideFreedom == TransformSideFreedom.Locked))
|
|
return;
|
|
return;
|
|
|
|
|
|
- var pos = TransformHelper.ToVecD(e.GetPosition(this));
|
|
|
|
|
|
+ VecD pos = TransformHelper.ToVecD(e.GetPosition(this));
|
|
|
|
|
|
if (TransformHelper.IsCorner((Anchor)capturedAnchor))
|
|
if (TransformHelper.IsCorner((Anchor)capturedAnchor))
|
|
{
|
|
{
|
|
- var targetPos = TransformHelper.GetAnchorPosition(cornersOnStartAnchorDrag, (Anchor)capturedAnchor) + pos - mousePosOnStartAnchorDrag;
|
|
|
|
- var newCorners = TransformUpdateHelper.UpdateShapeFromCorner
|
|
|
|
|
|
+ VecD targetPos = TransformHelper.GetAnchorPosition(cornersOnStartAnchorDrag, (Anchor)capturedAnchor) + pos - mousePosOnStartAnchorDrag;
|
|
|
|
+ ShapeCorners? newCorners = TransformUpdateHelper.UpdateShapeFromCorner
|
|
((Anchor)capturedAnchor, CornerFreedom, InternalState.ProportionalAngle1, InternalState.ProportionalAngle2, cornersOnStartAnchorDrag, targetPos);
|
|
((Anchor)capturedAnchor, CornerFreedom, InternalState.ProportionalAngle1, InternalState.ProportionalAngle2, cornersOnStartAnchorDrag, targetPos);
|
|
if (newCorners is not null)
|
|
if (newCorners is not null)
|
|
{
|
|
{
|
|
@@ -264,8 +277,8 @@ internal class TransformOverlay : Control
|
|
}
|
|
}
|
|
else if (TransformHelper.IsSide((Anchor)capturedAnchor))
|
|
else if (TransformHelper.IsSide((Anchor)capturedAnchor))
|
|
{
|
|
{
|
|
- var targetPos = TransformHelper.GetAnchorPosition(cornersOnStartAnchorDrag, (Anchor)capturedAnchor) + pos - mousePosOnStartAnchorDrag;
|
|
|
|
- var newCorners = TransformUpdateHelper.UpdateShapeFromSide
|
|
|
|
|
|
+ VecD targetPos = TransformHelper.GetAnchorPosition(cornersOnStartAnchorDrag, (Anchor)capturedAnchor) + pos - mousePosOnStartAnchorDrag;
|
|
|
|
+ ShapeCorners? newCorners = TransformUpdateHelper.UpdateShapeFromSide
|
|
((Anchor)capturedAnchor, SideFreedom, InternalState.ProportionalAngle1, InternalState.ProportionalAngle2, cornersOnStartAnchorDrag, targetPos);
|
|
((Anchor)capturedAnchor, SideFreedom, InternalState.ProportionalAngle1, InternalState.ProportionalAngle2, cornersOnStartAnchorDrag, targetPos);
|
|
if (newCorners is not null)
|
|
if (newCorners is not null)
|
|
{
|
|
{
|