浏览代码

Merge branch 'master' into fix/transform-path

Krzysztof Krysiński 3 周之前
父节点
当前提交
b405c4e9ac

+ 29 - 17
src/PixiEditor.ChangeableDocument/Changes/Selection/MagicWand/MagicWand_Change.cs → src/PixiEditor.ChangeableDocument/Changes/Selection/MagicWand/MagicWand_UpdateableChange.cs

@@ -6,7 +6,7 @@ using Drawie.Numerics;
 
 namespace PixiEditor.ChangeableDocument.Changes.Selection.MagicWand;
 
-internal class MagicWand_Change : Change
+internal class MagicWand_UpdateableChange : UpdateableChange
 {
     private VectorPath? originalPath;
     private VectorPath path = new() { FillType = PathFillType.EvenOdd };
@@ -16,8 +16,8 @@ internal class MagicWand_Change : Change
     private int frame;
     private double tolerance;
 
-    [GenerateMakeChangeAction]
-    public MagicWand_Change(List<Guid> memberGuids, VecI point, SelectionMode mode, double tolerance, int frame)
+    [GenerateUpdateableChangeActions]
+    public MagicWand_UpdateableChange(List<Guid> memberGuids, VecI point, SelectionMode mode, double tolerance, int frame)
     {
         path.MoveTo(point);
         this.mode = mode;
@@ -33,7 +33,24 @@ internal class MagicWand_Change : Change
         return true;
     }
 
+    [UpdateChangeMethod]
+    public void Update(VecI point)
+    {
+        this.point = point;
+    }
+
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Apply(Document target, bool firstApply, out bool ignoreInUndo)
+    {
+        ignoreInUndo = false;
+        return CommonApply(target);
+    }
+
+    public override OneOf<None, IChangeInfo, List<IChangeInfo>> ApplyTemporarily(Document target)
+    {
+        return CommonApply(target);
+    }
+
+    private Selection_ChangeInfo CommonApply(Document target)
     {
         HashSet<Guid> membersToReference = new();
 
@@ -45,19 +62,6 @@ internal class MagicWand_Change : Change
 
         path = MagicWandHelper.DoMagicWandFloodFill(point, membersToReference, tolerance, target, frame);
 
-        ignoreInUndo = false;
-        return CommonApply(target);
-    }
-
-    public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
-    {
-        (var toDispose, target.Selection.SelectionPath) = (target.Selection.SelectionPath, new VectorPath(originalPath!));
-        toDispose.Dispose();
-        return new Selection_ChangeInfo(new VectorPath(target.Selection.SelectionPath));
-    }
-
-    private Selection_ChangeInfo CommonApply(Document target)
-    {
         var toDispose = target.Selection.SelectionPath;
         if (mode == SelectionMode.New)
         {
@@ -67,13 +71,21 @@ internal class MagicWand_Change : Change
         }
         else
         {
-            target.Selection.SelectionPath = originalPath!.Op(path, mode.ToVectorPathOp());
+            target.Selection.SelectionPath = target.Selection.SelectionPath!.Op(path, mode.ToVectorPathOp());
         }
         toDispose.Dispose();
 
         return new Selection_ChangeInfo(new VectorPath(target.Selection.SelectionPath));
     }
 
+    public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
+    {
+        var toDispose = target.Selection.SelectionPath;
+        target.Selection.SelectionPath = new VectorPath(originalPath!);
+        toDispose.Dispose();
+        return new Selection_ChangeInfo(new VectorPath(target.Selection.SelectionPath));
+    }
+
     public override void Dispose()
     {
         path.Dispose();

+ 3 - 1
src/PixiEditor/Data/Localization/Languages/en.json

@@ -312,7 +312,9 @@
   "LINE_TOOL_ACTION_DISPLAY_DEFAULT": "Click and move to draw a line. Hold Shift to enable snapping.",
   "LINE_TOOL_ACTION_DISPLAY_SHIFT": "Click and move mouse to draw a line with snapping enabled.",
   "MAGIC_WAND_TOOL_TOOLTIP": "Magic Wand ({0}). Flood's the selection",
-  "MAGIC_WAND_ACTION_DISPLAY": "Click to flood the selection.",
+  "MAGIC_WAND_ACTION_DISPLAY": "Click to flood the selection. Hold Shift to add to existing selection. Hold Ctrl to subtract from it.",
+  "MAGIC_WAND_ACTION_DISPLAY_SHIFT": "Click to add to the current selection.",
+  "MAGIC_WAND_ACTION_DISPLAY_CTRL": "Click to subtract from the current selection.",
   "PEN_TOOL": "Pen",
   "BRIGHTNESS_TOOL": "Brightness",
   "COLOR_PICKER_TOOL": "Color Picker",

+ 19 - 4
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/MagicWandToolExecutor.cs

@@ -25,7 +25,7 @@ internal class MagicWandToolExecutor : UpdateableChangeExecutor
         if (magicWand is null || members.Count == 0)
             return ExecutionState.Error;
 
-        mode = magicWand.SelectMode;
+        mode = magicWand.ResultingSelectionMode;
         memberGuids = members;
         considerAllLayers = magicWand.DocumentScope == DocumentScope.Canvas;
         if (considerAllLayers)
@@ -33,19 +33,34 @@ internal class MagicWandToolExecutor : UpdateableChangeExecutor
         var pos = controller!.LastPixelPosition;
         tolerance = (float)magicWand.Tolerance;
 
-        internals!.ActionAccumulator.AddActions(new MagicWand_Action(memberGuids, pos, mode, tolerance, document!.AnimationHandler.ActiveFrameBindable));
+        AddUpdateAction(pos);
 
         return ExecutionState.Success;
     }
 
+    public override void OnPixelPositionChange(VecI pos)
+    {
+        AddUpdateAction(pos);
+    }
+
     public override void OnLeftMouseButtonUp(VecD argsPositionOnCanvas)
     {
-        internals!.ActionAccumulator.AddActions(new ChangeBoundary_Action());
+        AddFinishAction();
         onEnded!(this);
     }
 
     public override void ForceStop()
     {
-        internals!.ActionAccumulator.AddActions(new ChangeBoundary_Action());
+        AddFinishAction();
+    }
+
+    private void AddUpdateAction(VecI pos)
+    {
+        var action = new MagicWand_Action(memberGuids, pos, mode, tolerance, document!.AnimationHandler.ActiveFrameBindable);
+        internals!.ActionAccumulator.AddActions(action);
+    }
+    private void AddFinishAction()
+    {
+        internals!.ActionAccumulator.AddFinishedActions(new EndMagicWand_Action());
     }
 }

+ 1 - 1
src/PixiEditor/Models/Handlers/Tools/IMagicWandToolHandler.cs

@@ -5,7 +5,7 @@ namespace PixiEditor.Models.Handlers.Tools;
 
 internal interface IMagicWandToolHandler : IToolHandler
 {
-    public SelectionMode SelectMode { get; }
+    public SelectionMode ResultingSelectionMode { get; }
     public DocumentScope DocumentScope { get; }
     public float Tolerance { get; }
 }

+ 24 - 4
src/PixiEditor/ViewModels/Tools/Tools/MagicWandToolViewModel.cs

@@ -17,11 +17,12 @@ namespace PixiEditor.ViewModels.Tools.Tools;
 internal class MagicWandToolViewModel : ToolViewModel, IMagicWandToolHandler
 {
     public override LocalizedString Tooltip => new LocalizedString("MAGIC_WAND_TOOL_TOOLTIP", Shortcut);
-
+    private LocalizedString defaultActionDisplay => new LocalizedString("MAGIC_WAND_ACTION_DISPLAY");
     public override string ToolNameLocalizationKey => "MAGIC_WAND_TOOL";
     public override BrushShape FinalBrushShape => BrushShape.Pixel;
-    public override Type[]? SupportedLayerTypes { get; } = { typeof(IRasterLayerHandler) }; 
-
+    public override Type[]? SupportedLayerTypes { get; } = { typeof(IRasterLayerHandler) };
+    private SelectionMode KeyModifierSelectionMode = SelectionMode.New;
+    public SelectionMode ResultingSelectionMode => KeyModifierSelectionMode != SelectionMode.New ? KeyModifierSelectionMode : SelectMode;
     [Settings.Enum("MODE_LABEL")]
     public SelectionMode SelectMode => GetValue<SelectionMode>();
 
@@ -36,7 +37,7 @@ internal class MagicWandToolViewModel : ToolViewModel, IMagicWandToolHandler
     public MagicWandToolViewModel()
     {
         Toolbar = ToolbarFactory.Create(this);
-        ActionDisplay = "MAGIC_WAND_ACTION_DISPLAY";
+        ActionDisplay = defaultActionDisplay;
     }
 
     public override Type LayerTypeToCreateOnEmptyUse { get; } = null;
@@ -45,4 +46,23 @@ internal class MagicWandToolViewModel : ToolViewModel, IMagicWandToolHandler
     {
         ViewModelMain.Current?.DocumentManagerSubViewModel.ActiveDocument?.Tools.UseMagicWandTool();
     }
+
+    public override void KeyChanged(bool ctrlIsDown, bool shiftIsDown, bool altIsDown, Key argsKey)
+    {
+        if (shiftIsDown)
+        {
+            ActionDisplay = new LocalizedString("MAGIC_WAND_ACTION_DISPLAY_SHIFT");
+            KeyModifierSelectionMode = SelectionMode.Add;
+        }
+        else if (ctrlIsDown)
+        {
+            ActionDisplay = new LocalizedString("MAGIC_WAND_ACTION_DISPLAY_CTRL");
+            KeyModifierSelectionMode = SelectionMode.Subtract;
+        }
+        else
+        {
+            ActionDisplay = defaultActionDisplay;
+            KeyModifierSelectionMode = SelectionMode.New;
+        }
+    }
 }