|
@@ -19,10 +19,11 @@ namespace PixiEditor.ViewModels.Document.TransformOverlays;
|
|
|
internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
|
|
|
{
|
|
|
private DocumentViewModel document;
|
|
|
-
|
|
|
+
|
|
|
private TransformOverlayUndoStack<(ShapeCorners, TransformState)>? undoStack = null;
|
|
|
|
|
|
private TransformState internalState;
|
|
|
+
|
|
|
public TransformState InternalState
|
|
|
{
|
|
|
get => internalState;
|
|
@@ -30,6 +31,7 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
|
|
|
}
|
|
|
|
|
|
private TransformCornerFreedom cornerFreedom;
|
|
|
+
|
|
|
public TransformCornerFreedom CornerFreedom
|
|
|
{
|
|
|
get => cornerFreedom;
|
|
@@ -37,13 +39,23 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
|
|
|
}
|
|
|
|
|
|
private TransformSideFreedom sideFreedom;
|
|
|
+
|
|
|
public TransformSideFreedom SideFreedom
|
|
|
{
|
|
|
get => sideFreedom;
|
|
|
set => SetProperty(ref sideFreedom, value);
|
|
|
}
|
|
|
|
|
|
+ private bool scaleFromCenter;
|
|
|
+
|
|
|
+ public bool ScaleFromCenter
|
|
|
+ {
|
|
|
+ get => scaleFromCenter;
|
|
|
+ set => SetProperty(ref scaleFromCenter, value);
|
|
|
+ }
|
|
|
+
|
|
|
private bool lockRotation;
|
|
|
+
|
|
|
public bool LockRotation
|
|
|
{
|
|
|
get => lockRotation;
|
|
@@ -51,6 +63,7 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
|
|
|
}
|
|
|
|
|
|
private bool snapToAngles;
|
|
|
+
|
|
|
public bool SnapToAngles
|
|
|
{
|
|
|
get => snapToAngles;
|
|
@@ -58,6 +71,7 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
|
|
|
}
|
|
|
|
|
|
private bool transformActive;
|
|
|
+
|
|
|
public bool TransformActive
|
|
|
{
|
|
|
get => transformActive;
|
|
@@ -70,7 +84,8 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
|
|
|
|
|
|
if (value)
|
|
|
{
|
|
|
- document.ActionDisplays[nameof(DocumentTransformViewModel)] = new LocalizedString($"TRANSFORM_ACTION_DISPLAY_{activeTransformMode.GetDescription()}");
|
|
|
+ document.ActionDisplays[nameof(DocumentTransformViewModel)] =
|
|
|
+ new LocalizedString($"TRANSFORM_ACTION_DISPLAY_{activeTransformMode.GetDescription()}");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
@@ -80,6 +95,7 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
|
|
|
}
|
|
|
|
|
|
private bool showTransformControls;
|
|
|
+
|
|
|
public bool ShowTransformControls
|
|
|
{
|
|
|
get => showTransformControls;
|
|
@@ -89,6 +105,7 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
|
|
|
public event Action<MouseOnCanvasEventArgs>? PassthroughPointerPressed;
|
|
|
|
|
|
private bool coverWholeScreen;
|
|
|
+
|
|
|
public bool CoverWholeScreen
|
|
|
{
|
|
|
get => coverWholeScreen;
|
|
@@ -96,6 +113,7 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
|
|
|
}
|
|
|
|
|
|
private ShapeCorners corners;
|
|
|
+
|
|
|
public ShapeCorners Corners
|
|
|
{
|
|
|
get => corners;
|
|
@@ -112,25 +130,27 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
|
|
|
{
|
|
|
get => showHandles;
|
|
|
set => SetProperty(ref showHandles, value);
|
|
|
- }
|
|
|
-
|
|
|
+ }
|
|
|
+
|
|
|
private bool isSizeBoxEnabled;
|
|
|
|
|
|
public bool IsSizeBoxEnabled
|
|
|
{
|
|
|
get => isSizeBoxEnabled;
|
|
|
set => SetProperty(ref isSizeBoxEnabled, value);
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
private bool enableSnapping = true;
|
|
|
+
|
|
|
public bool EnableSnapping
|
|
|
{
|
|
|
get => enableSnapping;
|
|
|
set => SetProperty(ref enableSnapping, value);
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
private ExecutionTrigger<ShapeCorners> requestedCornersExecutor;
|
|
|
+
|
|
|
public ExecutionTrigger<ShapeCorners> RequestCornersExecutor
|
|
|
{
|
|
|
get => requestedCornersExecutor;
|
|
@@ -138,18 +158,21 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
|
|
|
}
|
|
|
|
|
|
private ICommand? actionCompletedCommand = null;
|
|
|
+
|
|
|
public ICommand? ActionCompletedCommand
|
|
|
{
|
|
|
get => actionCompletedCommand;
|
|
|
set => SetProperty(ref actionCompletedCommand, value);
|
|
|
}
|
|
|
|
|
|
- private RelayCommand<MouseOnCanvasEventArgs>? passThroughPointerPressedCommand;
|
|
|
+ private RelayCommand<MouseOnCanvasEventArgs>? passThroughPointerPressedCommand;
|
|
|
+
|
|
|
public RelayCommand<MouseOnCanvasEventArgs> PassThroughPointerPressedCommand
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
- return passThroughPointerPressedCommand ??= new RelayCommand<MouseOnCanvasEventArgs>(x => PassthroughPointerPressed?.Invoke(x));
|
|
|
+ return passThroughPointerPressedCommand ??=
|
|
|
+ new RelayCommand<MouseOnCanvasEventArgs>(x => PassthroughPointerPressed?.Invoke(x));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -166,7 +189,8 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
|
|
|
return;
|
|
|
|
|
|
var lastState = undoStack.PeekCurrent();
|
|
|
- if (lastState is not null && lastState.Value.Item1.AlmostEquals(Corners) && lastState.Value.Item2.AlmostEquals(InternalState))
|
|
|
+ if (lastState is not null && lastState.Value.Item1.AlmostEquals(Corners) &&
|
|
|
+ lastState.Value.Item2.AlmostEquals(InternalState))
|
|
|
return;
|
|
|
|
|
|
undoStack.AddState((Corners, InternalState), TransformOverlayStateType.Move);
|
|
@@ -208,7 +232,7 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
- public bool HasUndo => undoStack is not null && undoStack.UndoCount > 0;
|
|
|
+ public bool HasUndo => undoStack is not null && undoStack.UndoCount > 0;
|
|
|
public bool HasRedo => undoStack is not null && undoStack.RedoCount > 0;
|
|
|
|
|
|
public void HideTransform()
|
|
@@ -221,7 +245,8 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
|
|
|
ShowTransformControls = false;
|
|
|
}
|
|
|
|
|
|
- public void ShowTransform(DocumentTransformMode mode, bool coverWholeScreen, ShapeCorners initPos, bool showApplyButton)
|
|
|
+ public void ShowTransform(DocumentTransformMode mode, bool coverWholeScreen, ShapeCorners initPos,
|
|
|
+ bool showApplyButton)
|
|
|
{
|
|
|
if (undoStack is not null || initPos.IsPartiallyDegenerate)
|
|
|
return;
|
|
@@ -253,21 +278,24 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
|
|
|
requestedCornerFreedom = TransformCornerFreedom.ScaleProportionally;
|
|
|
requestedSideFreedom = TransformSideFreedom.ScaleProportionally;
|
|
|
}
|
|
|
- else if (isCtrlDown)
|
|
|
+ else if (isAltDown)
|
|
|
{
|
|
|
requestedCornerFreedom = TransformCornerFreedom.Free;
|
|
|
requestedSideFreedom = TransformSideFreedom.Free;
|
|
|
}
|
|
|
- else if (isAltDown)
|
|
|
+ /*else if (isAltDown)
|
|
|
{
|
|
|
+ TODO: Add shear to the transform overlay
|
|
|
requestedSideFreedom = TransformSideFreedom.Shear;
|
|
|
- }
|
|
|
+ }*/
|
|
|
else
|
|
|
{
|
|
|
requestedCornerFreedom = TransformCornerFreedom.Scale;
|
|
|
requestedSideFreedom = TransformSideFreedom.Stretch;
|
|
|
}
|
|
|
|
|
|
+ ScaleFromCenter = isCtrlDown;
|
|
|
+
|
|
|
switch (activeTransformMode)
|
|
|
{
|
|
|
case DocumentTransformMode.Scale_Rotate_Shear_Perspective:
|
|
@@ -290,6 +318,8 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- public override string ToString() => !TransformActive ? "Not active" : $"Transform Mode: {activeTransformMode}; Corner Freedom: {CornerFreedom}; Side Freedom: {SideFreedom}";
|
|
|
+
|
|
|
+ public override string ToString() => !TransformActive
|
|
|
+ ? "Not active"
|
|
|
+ : $"Transform Mode: {activeTransformMode}; Corner Freedom: {CornerFreedom}; Side Freedom: {SideFreedom}";
|
|
|
}
|