浏览代码

Layers selection shapes reactivity

flabbet 1 年之前
父节点
当前提交
e859a28dd3

+ 1 - 1
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/LineExecutor.cs

@@ -104,7 +104,7 @@ internal abstract class LineExecutor<T> : UpdateableChangeExecutor where T : ILi
             return;
         }
 
-        document!.LineToolOverlayHandler.Show(startPos + new VecD(0.5), curPos + new VecD(0.5));
+        document!.LineToolOverlayHandler.Show(startPos + new VecD(0.5), curPos + new VecD(0.5), true);
         transforming = true;
     }
 

+ 5 - 1
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/ShapeToolExecutor.cs

@@ -192,14 +192,18 @@ internal abstract class ShapeToolExecutor<T> : UpdateableChangeExecutor where T
     {
         if (transforming)
             return;
+        
         if (noMovement)
         {
             internals!.ActionAccumulator.AddFinishedActions(EndDrawAction());
             onEnded?.Invoke(this);
             return;
         }
-        transforming = true;
+        
+        
+        document!.TransformHandler.HideTransform();
         document!.TransformHandler.ShowTransform(TransformMode, false, new ShapeCorners((RectD)lastRect), true);
+        transforming = true;
     }
 
     public override void ForceStop()

+ 1 - 1
src/PixiEditor/Models/Handlers/ILineOverlayHandler.cs

@@ -9,5 +9,5 @@ internal interface ILineOverlayHandler
     public bool Nudge(VecD distance);
     public bool Undo();
     public bool Redo();
-    public void Show(VecD startPos, VecD curPos);
+    public void Show(VecD startPos, VecD curPos, bool showApplyButton);
 }

+ 1 - 1
src/PixiEditor/ViewModels/Document/TransformOverlays/DocumentTransformViewModel.cs

@@ -184,7 +184,7 @@ internal class DocumentTransformViewModel : ObservableObject, ITransformHandler
 
     public void ShowTransform(DocumentTransformMode mode, bool coverWholeScreen, ShapeCorners initPos, bool showApplyButton)
     {
-        if (undoStack is not null)
+        if (undoStack is not null || initPos.IsPartiallyDegenerate)
             return;
         undoStack = new();
 

+ 18 - 2
src/PixiEditor/ViewModels/Document/TransformOverlays/LineToolOverlayViewModel.cs

@@ -6,6 +6,7 @@ using PixiEditor.Models.Handlers;
 using PixiEditor.Numerics;
 
 namespace PixiEditor.ViewModels.Document.TransformOverlays;
+
 internal class LineToolOverlayViewModel : ObservableObject, ILineOverlayHandler
 {
     public event EventHandler<(VecD, VecD)>? LineMoved;
@@ -13,6 +14,7 @@ internal class LineToolOverlayViewModel : ObservableObject, ILineOverlayHandler
     private TransformOverlayUndoStack<(VecD, VecD)>? undoStack = null;
 
     private VecD lineStart;
+
     public VecD LineStart
     {
         get => lineStart;
@@ -24,6 +26,7 @@ internal class LineToolOverlayViewModel : ObservableObject, ILineOverlayHandler
     }
 
     private VecD lineEnd;
+
     public VecD LineEnd
     {
         get => lineEnd;
@@ -35,6 +38,7 @@ internal class LineToolOverlayViewModel : ObservableObject, ILineOverlayHandler
     }
 
     private bool isEnabled;
+
     public bool IsEnabled
     {
         get => isEnabled;
@@ -42,18 +46,28 @@ internal class LineToolOverlayViewModel : ObservableObject, ILineOverlayHandler
     }
 
     private ICommand? actionCompletedCommand = null;
+
     public ICommand? ActionCompletedCommand
     {
         get => actionCompletedCommand;
         set => SetProperty(ref actionCompletedCommand, value);
     }
 
+    private bool showApplyButton;
+
+    public bool ShowApplyButton
+    {
+        get => showApplyButton;
+        set => SetProperty(ref showApplyButton, value);
+    }
+
     public LineToolOverlayViewModel()
     {
-        ActionCompletedCommand = new RelayCommand(() => undoStack?.AddState((LineStart, LineEnd), TransformOverlayStateType.Move));
+        ActionCompletedCommand =
+            new RelayCommand(() => undoStack?.AddState((LineStart, LineEnd), TransformOverlayStateType.Move));
     }
 
-    public void Show(VecD lineStart, VecD lineEnd)
+    public void Show(VecD lineStart, VecD lineEnd, bool showApplyButton)
     {
         if (undoStack is not null)
             return;
@@ -63,6 +77,7 @@ internal class LineToolOverlayViewModel : ObservableObject, ILineOverlayHandler
         LineStart = lineStart;
         LineEnd = lineEnd;
         IsEnabled = true;
+        ShowApplyButton = showApplyButton;
     }
 
     public void Hide()
@@ -71,6 +86,7 @@ internal class LineToolOverlayViewModel : ObservableObject, ILineOverlayHandler
             return;
         undoStack = null;
         IsEnabled = false;
+        ShowApplyButton = false;
     }
 
     public bool Nudge(VecD distance)

+ 7 - 0
src/PixiEditor/ViewModels/Tools/ToolViewModel.cs

@@ -107,6 +107,11 @@ internal abstract class ToolViewModel : ObservableObject, IToolHandler
         
         var layer = layers[0];
 
+        if (IsActive)
+        {
+            OnSelectedLayersChanged(layers);
+        }
+
         if (SupportedLayerTypes == null)
         {
             CanBeUsedOnActiveLayer = true;
@@ -134,6 +139,8 @@ internal abstract class ToolViewModel : ObservableObject, IToolHandler
 
     public virtual void UseTool(VecD pos) { }
     public virtual void OnSelected() { }
+    
+    protected virtual void OnSelectedLayersChanged(IStructureMemberHandler[] layers) { }
 
     public virtual void OnDeselecting()
     {

+ 10 - 4
src/PixiEditor/ViewModels/Tools/Tools/VectorEllipseToolViewModel.cs

@@ -21,9 +21,9 @@ internal class VectorEllipseToolViewModel : ShapeTool, IVectorEllipseToolHandler
     {
         ActionDisplay = defaultActionDisplay;
     }
-    
+
     // This doesn't include a Vector layer because it is designed to create new layer each use
-    public override Type[]? SupportedLayerTypes { get; } = []; 
+    public override Type[]? SupportedLayerTypes { get; } = [];
     public override LocalizedString Tooltip => new LocalizedString("ELLIPSE_TOOL_TOOLTIP", Shortcut);
     public bool DrawCircle { get; private set; }
 
@@ -31,7 +31,7 @@ internal class VectorEllipseToolViewModel : ShapeTool, IVectorEllipseToolHandler
 
     public override Type LayerTypeToCreateOnEmptyUse { get; } = typeof(VectorLayerNode);
 
-    public string? DefaultNewLayerName { get; } = new LocalizedString("NEW_ELLIPSE_LAYER_NAME"); 
+    public string? DefaultNewLayerName { get; } = new LocalizedString("NEW_ELLIPSE_LAYER_NAME");
 
     public override void UseTool(VecD pos)
     {
@@ -47,7 +47,7 @@ internal class VectorEllipseToolViewModel : ShapeTool, IVectorEllipseToolHandler
             ViewModelMain.Current?.DocumentManagerSubViewModel.ActiveDocument.TransformViewModel.ShowTransform(
                 DocumentTransformMode.Scale_Rotate_Shear_NoPerspective, false, corners, false);
         }
-        
+
         ViewModelMain.Current?.DocumentManagerSubViewModel.ActiveDocument?.Tools.UseVectorEllipseTool();
     }
 
@@ -55,4 +55,10 @@ internal class VectorEllipseToolViewModel : ShapeTool, IVectorEllipseToolHandler
     {
         ViewModelMain.Current.DocumentManagerSubViewModel.ActiveDocument?.Operations.TryStopToolLinkedExecutor();
     }
+
+    protected override void OnSelectedLayersChanged(IStructureMemberHandler[] layers)
+    {
+        OnDeselecting();
+        OnSelected();
+    }
 }

+ 8 - 2
src/PixiEditor/ViewModels/Tools/Tools/VectorLineToolViewModel.cs

@@ -68,12 +68,18 @@ internal class VectorLineToolViewModel : ShapeTool, IVectorLineToolHandler
             IReadOnlyLineData? lineVectorData = vectorLayer.GetShapeData(document.AnimationDataViewModel.ActiveFrameTime) as IReadOnlyLineData;
             if (lineVectorData is null) return;
             
-            document.LineToolOverlayViewModel.Show(lineVectorData.Start, lineVectorData.End);
+            document.LineToolOverlayViewModel.Show(lineVectorData.Start, lineVectorData.End, false);
         }
 
         document.Tools.UseVectorLineTool();
     }
-    
+
+    protected override void OnSelectedLayersChanged(IStructureMemberHandler[] layers)
+    {
+        OnDeselecting();
+        OnSelected();
+    }
+
     public override void OnDeselecting()
     {
         ViewModelMain.Current.DocumentManagerSubViewModel.ActiveDocument?.Operations.TryStopToolLinkedExecutor();

+ 6 - 0
src/PixiEditor/ViewModels/Tools/Tools/VectorRectangleToolViewModel.cs

@@ -67,4 +67,10 @@ internal class VectorRectangleToolViewModel : ShapeTool, IVectorRectangleToolHan
     {
         ViewModelMain.Current.DocumentManagerSubViewModel.ActiveDocument?.Operations.TryStopToolLinkedExecutor();
     }
+    
+    protected override void OnSelectedLayersChanged(IStructureMemberHandler[] layers)
+    {
+        OnDeselecting();
+        OnSelected();
+    }
 }

+ 1 - 1
src/PixiEditor/Views/Main/ViewportControls/Viewport.axaml

@@ -173,7 +173,7 @@
                 <MultiBinding Converter="{converters:BoolOrToVisibilityConverter}">
                     <MultiBinding.Bindings>
                         <Binding ElementName="vpUc" Path="Document.TransformViewModel.ShowTransformControls" />
-                        <Binding ElementName="vpUc" Path="Document.LineToolOverlayViewModel.IsEnabled" />
+                        <Binding ElementName="vpUc" Path="Document.LineToolOverlayViewModel.ShowApplyButton" />
                     </MultiBinding.Bindings>
                 </MultiBinding>
             </Button.IsVisible>

+ 8 - 1
src/PixiEditor/Views/Overlays/LineToolOverlay/LineToolOverlay.cs

@@ -11,6 +11,7 @@ using PixiEditor.Extensions.UI.Overlays;
 using PixiEditor.Numerics;
 using PixiEditor.Views.Overlays.Handles;
 using PixiEditor.Views.Overlays.TransformOverlay;
+using Point = Avalonia.Point;
 
 namespace PixiEditor.Views.Overlays.LineToolOverlay;
 internal class LineToolOverlay : Overlay
@@ -49,6 +50,8 @@ internal class LineToolOverlay : Overlay
     }
 
     private Pen blackPen = new Pen(Brushes.Black, 1);
+    private Pen blackDashedPen = new Pen(Brushes.Black, 1) { DashStyle = new DashStyle(new double[] { 2, 4 }, 0) };
+    private Pen whiteDashedPen = new Pen(Brushes.White, 1) { DashStyle = new DashStyle(new double[] { 2, 4 }, 2) };
 
     private VecD mouseDownPos = VecD.Zero;
     private VecD lineStartOnMouseDown = VecD.Zero;
@@ -70,7 +73,7 @@ internal class LineToolOverlay : Overlay
         AddHandle(startHandle);
 
         endHandle = new AnchorHandle(this);
-        startHandle.HandlePen = blackPen;
+        endHandle.HandlePen = blackPen;
         endHandle.OnDrag += EndHandleOnDrag;
         AddHandle(endHandle);
 
@@ -83,6 +86,8 @@ internal class LineToolOverlay : Overlay
     protected override void ZoomChanged(double newZoom)
     {
         blackPen.Thickness = 1.0 / newZoom;
+        blackDashedPen.Thickness = 2.0 / newZoom;
+        whiteDashedPen.Thickness = 2.0 / newZoom;
     }
 
     public override void RenderOverlay(DrawingContext context, RectD canvasBounds)
@@ -93,6 +98,8 @@ internal class LineToolOverlay : Overlay
         VecD size = LineEnd - LineStart;
         moveHandle.Position = TransformHelper.GetHandlePos(new ShapeCorners(center, size), ZoomScale, moveHandle.Size);
 
+        context.DrawLine(blackDashedPen, new Point(LineStart.X, LineStart.Y), new Point(LineEnd.X, LineEnd.Y));
+        context.DrawLine(whiteDashedPen, new Point(LineStart.X, LineStart.Y), new Point(LineEnd.X, LineEnd.Y));
         startHandle.Draw(context);
         endHandle.Draw(context);
         moveHandle.Draw(context);

+ 9 - 0
src/PixiEditor/Views/Overlays/Overlay.cs

@@ -46,6 +46,7 @@ public abstract class Overlay : Decorator, IOverlay // TODO: Maybe make it not a
     public Overlay()
     {
         ZoomScaleProperty.Changed.Subscribe(OnZoomScaleChanged);
+        IsVisibleProperty.Changed.Subscribe(OnIsVisibleChanged);
     }
 
     ~Overlay()
@@ -209,6 +210,14 @@ public abstract class Overlay : Decorator, IOverlay // TODO: Maybe make it not a
             }
         }
     }
+    
+    private void OnIsVisibleChanged(AvaloniaPropertyChangedEventArgs<bool> e)
+    {
+        if (e.NewValue.Value)
+        {
+            Refresh();
+        }
+    }
 }
 
 public enum OverlayRenderSorting

+ 0 - 1
src/PixiEditor/Views/Overlays/TransformOverlay/TransformOverlay.cs

@@ -113,7 +113,6 @@ internal class TransformOverlay : Overlay
     static TransformOverlay()
     {
         AffectsRender<TransformOverlay>(CornersProperty, ZoomScaleProperty, SideFreedomProperty, CornerFreedomProperty, LockRotationProperty, SnapToAnglesProperty, InternalStateProperty, ZoomboxAngleProperty, CoverWholeScreenProperty);
-
         RequestCornersExecutorProperty.Changed.Subscribe(OnCornersExecutorChanged);
     }