Bläddra i källkod

Fixed transient tool

flabbet 2 år sedan
förälder
incheckning
c2c402f8ca

+ 4 - 11
src/PixiEditor/Helpers/ProcessHelper.cs

@@ -10,17 +10,10 @@ internal static class ProcessHelper
     public static Process RunAsAdmin(string path)
     {
         var proc = new Process();
-        try
-        {
-            proc.StartInfo.FileName = path;
-            proc.StartInfo.Verb = "runas";
-            proc.StartInfo.UseShellExecute = true;
-            proc.Start();
-        }
-        catch (Win32Exception)
-        {
-            throw;
-        }
+        proc.StartInfo.FileName = path;
+        proc.StartInfo.Verb = "runas";
+        proc.StartInfo.UseShellExecute = true;
+        proc.Start();
 
         return proc;
     }

+ 1 - 1
src/PixiEditor/Models/Commands/CommandCollection.cs

@@ -19,7 +19,7 @@ internal class CommandCollection : ICollection<Command>
     public Command this[string name] => _commandInternalNames[name];
     public bool ContainsKey(string key) => _commandInternalNames.ContainsKey(key);
 
-    public IEnumerable<Command> this[KeyCombination shortcut] => _commandShortcuts[shortcut];
+    public List<Command> this[KeyCombination shortcut] => _commandShortcuts[shortcut];
 
     public CommandCollection()
     {

+ 1 - 1
src/PixiEditor/Models/DataHolders/OneToManyDictionary.cs

@@ -25,7 +25,7 @@ internal class OneToManyDictionary<TKey, T> : ICollection<KeyValuePair<TKey, IEn
     public bool IsReadOnly => false;
 
     [NotNull]
-    public IEnumerable<T> this[TKey key]
+    public List<T> this[TKey key]
     {
         get
         {

+ 1 - 1
src/PixiEditor/ViewModels/SubViewModels/Document/DocumentManagerViewModel.cs

@@ -32,7 +32,7 @@ internal class DocumentManagerViewModel : SubViewModel<ViewModelMain>
             
             if (ViewModelMain.Current.ToolsSubViewModel.ActiveTool == null)
             {
-                ViewModelMain.Current.ToolsSubViewModel.SetActiveTool<PenToolViewModel>();
+                ViewModelMain.Current.ToolsSubViewModel.SetActiveTool<PenToolViewModel>(false);
             }
         }
     }

+ 24 - 57
src/PixiEditor/ViewModels/SubViewModels/Main/IoViewModel.cs

@@ -22,8 +22,6 @@ internal class IoViewModel : SubViewModel<ViewModelMain>
     public RelayCommand PreviewMouseMiddleButtonCommand { get; set; }
     public RelayCommand MouseUpCommand { get; set; }
 
-    private bool restoreToolOnKeyUp = false;
-
     private MouseInputFilter mouseFilter = new();
     private KeyboardInputFilter keyboardFilter = new();
 
@@ -66,7 +64,7 @@ internal class IoViewModel : SubViewModel<ViewModelMain>
 
     private void Current_PreProcessInput(object sender, PreProcessInputEventArgs e)
     {
-        if (e != null && e.StagingItem != null && e.StagingItem.Input != null)
+        if (e is { StagingItem: { Input: { } } })
         {
             InputEventArgs inputEvent = e.StagingItem.Input;
 
@@ -94,38 +92,39 @@ internal class IoViewModel : SubViewModel<ViewModelMain>
     private void OnKeyDown(object? sender, FilteredKeyEventArgs args)
     {
         ProcessShortcutDown(args.IsRepeat, args.Key);
-
         Owner.DocumentManagerSubViewModel.ActiveDocument?.EventInlet.OnKeyDown(args.Key);
-
-        HandleTransientKey(args, true);
     }
 
-    private void HandleTransientKey(FilteredKeyEventArgs args, bool state)
+    private void HandleTransientKey(Key transientKey)
     {
         if (ShortcutController.ShortcutExecutionBlocked)
         {
             return;
         }
 
-        ShortcutController controller = Owner.ShortcutController;
-
-        Models.Commands.Commands.Command.ToolCommand? tool = CommandController.Current.Commands
-            .OfType<Command.ToolCommand?>()
-            .FirstOrDefault(x => x != null && x.TransientKey == args.Key);
+        var tool = GetTransientTool(transientKey);
 
         if (tool is not null)
         {
-            ChangeToolState(tool.ToolType, state);
+            Owner.ToolsSubViewModel.SetActiveTool(tool.ToolType, true);
         }
     }
 
+    private static Command.ToolCommand? GetTransientTool(Key transientKey)
+    {
+        Command.ToolCommand? tool = CommandController.Current.Commands
+            .OfType<Command.ToolCommand?>()
+            .FirstOrDefault(x => x != null && x.TransientKey == transientKey);
+        return tool;
+    }
+
     private void ProcessShortcutDown(bool isRepeat, Key key)
     {
-        if (isRepeat && !restoreToolOnKeyUp && Owner.ShortcutController.LastCommands != null &&
-            Owner.ShortcutController.LastCommands.Any(x => x is Models.Commands.Commands.Command.ToolCommand))
+        HandleTransientKey(key);
+        if (isRepeat && Owner.ShortcutController.LastCommands != null &&
+            Owner.ShortcutController.LastCommands.Any(x => x is Command.ToolCommand))
         {
-            restoreToolOnKeyUp = true;
-            ShortcutController.BlockShortcutExecution("ShortcutDown");
+            Owner.ToolsSubViewModel.HandleToolRepeatShortcutDown();
         }
 
         Owner.ShortcutController.KeyPressed(key, Keyboard.Modifiers);
@@ -135,21 +134,17 @@ internal class IoViewModel : SubViewModel<ViewModelMain>
     {
         ProcessShortcutUp(new(args.Key, args.Modifiers));
 
-        if (Owner.DocumentManagerSubViewModel.ActiveDocument is not null)
-            Owner.DocumentManagerSubViewModel.ActiveDocument.EventInlet.OnKeyUp(args.Key);
-
-        HandleTransientKey(args, false);
+        Owner.DocumentManagerSubViewModel.ActiveDocument?.EventInlet.OnKeyUp(args.Key);
     }
 
     private void ProcessShortcutUp(KeyCombination shortcut)
     {
-        if (restoreToolOnKeyUp && Owner.ShortcutController.LastCommands != null &&
-            Owner.ShortcutController.LastCommands.Any(x => x.Shortcut == shortcut))
+        var transientTool = GetTransientTool(shortcut.Key);
+
+        if (Owner.ShortcutController.LastCommands != null &&
+            Owner.ShortcutController.LastCommands.Any(x => x.Shortcut == shortcut) || transientTool is not null)
         {
-            restoreToolOnKeyUp = false;
-            if (Owner.ToolsSubViewModel.LastActionTool is { } tool)
-                Owner.ToolsSubViewModel.SetActiveTool(tool);
-            ShortcutController.UnblockShortcutExecution("ShortcutDown");
+            Owner.ToolsSubViewModel.HandleToolShortcutUp();
         }
     }
 
@@ -169,35 +164,7 @@ internal class IoViewModel : SubViewModel<ViewModelMain>
 
     private void OnPreviewMiddleMouseButton(object sender)
     {
-        ChangeToolState<MoveViewportToolViewModel>(true);
-    }
-
-    private void ChangeToolState<T>(bool setOn)
-        where T : ToolViewModel
-    {
-        ChangeToolState(typeof(T), setOn);
-    }
-
-    private void ChangeToolState(Type type, bool setOn)
-    {
-        if (setOn)
-        {
-            var tool = Owner.ToolsSubViewModel.ActiveTool;
-            if (tool is null)
-                return;
-            bool transientToolIsActive = tool.GetType() == type;
-            if (!transientToolIsActive)
-            {
-                Owner.ToolsSubViewModel.SetActiveTool(type);
-                Owner.ToolsSubViewModel.ActiveToolIsTransient = true;
-            }
-        }
-        else if (Owner.ToolsSubViewModel.LastActionTool != null && Owner.ToolsSubViewModel.ActiveToolIsTransient)
-        {
-            Owner.ToolsSubViewModel.SetActiveTool(Owner.ToolsSubViewModel.LastActionTool);
-            restoreToolOnKeyUp = false;
-            ShortcutController.UnblockShortcutExecution("ShortcutDown");
-        }
+        Owner.ToolsSubViewModel.SetActiveTool<MoveViewportToolViewModel>(true);
     }
 
     private void OnMouseMove(object? sender, VecD pos)
@@ -218,7 +185,7 @@ internal class IoViewModel : SubViewModel<ViewModelMain>
         }
         else if (button == MouseButton.Middle)
         {
-            ChangeToolState<MoveViewportToolViewModel>(false);
+            Owner.ToolsSubViewModel.RestorePreviousTool();
         }
     }
 }

+ 2 - 2
src/PixiEditor/ViewModels/SubViewModels/Main/StylusViewModel.cs

@@ -91,7 +91,7 @@ internal class StylusViewModel : SubViewModel<ViewModelMain>
         if (e.StylusButton.Guid == StylusPointProperties.TipButton.Id && e.Inverted)
         {
             PreviousTool = Owner.ToolsSubViewModel.ActiveTool;
-            Owner.ToolsSubViewModel.SetActiveTool<EraserToolViewModel>();
+            Owner.ToolsSubViewModel.SetActiveTool<EraserToolViewModel>(true);
             ToolSetByStylus = true;
         }
     }
@@ -103,7 +103,7 @@ internal class StylusViewModel : SubViewModel<ViewModelMain>
 
         if (ToolSetByStylus && e.StylusButton.Guid == StylusPointProperties.TipButton.Id && e.Inverted)
         {
-            Owner.ToolsSubViewModel.SetActiveTool(PreviousTool);
+            Owner.ToolsSubViewModel.SetActiveTool(PreviousTool, false);
         }
     }
 }

+ 51 - 11
src/PixiEditor/ViewModels/SubViewModels/Main/ToolsViewModel.cs

@@ -3,6 +3,7 @@ using ChunkyImageLib.DataHolders;
 using Microsoft.Extensions.DependencyInjection;
 using PixiEditor.DrawingApi.Core.Numerics;
 using PixiEditor.Models.Commands.Attributes.Commands;
+using PixiEditor.Models.Controllers;
 using PixiEditor.Models.Events;
 using PixiEditor.Models.UserPreferences;
 using PixiEditor.ViewModels.SubViewModels.Document;
@@ -19,8 +20,6 @@ internal class ToolsViewModel : SubViewModel<ViewModelMain>
 
     public ToolViewModel? LastActionTool { get; private set; }
 
-    public bool ActiveToolIsTransient { get; set; }
-
     private Cursor? toolCursor;
     public Cursor? ToolCursor
     {
@@ -51,6 +50,9 @@ internal class ToolsViewModel : SubViewModel<ViewModelMain>
     private bool shiftIsDown;
     private bool ctrlIsDown;
     private bool altIsDown;
+    
+    private ToolViewModel _preTransientTool;
+
 
     public ToolsViewModel(ViewModelMain owner)
         : base(owner)
@@ -75,10 +77,10 @@ internal class ToolsViewModel : SubViewModel<ViewModelMain>
         return (T?)ToolSet?.Where(static tool => tool is T).FirstOrDefault();
     }
 
-    public void SetActiveTool<T>()
+    public void SetActiveTool<T>(bool transient)
         where T : ToolViewModel
     {
-        SetActiveTool(typeof(T));
+        SetActiveTool(typeof(T), transient);
     }
 
     [Command.Basic("PixiEditor.Tools.ApplyTransform", "Apply transform", "", Key = Key.Enter)]
@@ -93,12 +95,21 @@ internal class ToolsViewModel : SubViewModel<ViewModelMain>
     [Command.Internal("PixiEditor.Tools.SelectTool", CanExecute = "PixiEditor.HasDocument")]
     public void SetActiveTool(ToolViewModel tool)
     {
-        if (ActiveTool == tool) return;
+        SetActiveTool(tool, false);
+    }
+    
+    public void SetActiveTool(ToolViewModel tool, bool transient)
+    {
+        if (ActiveTool == tool)
+        {
+            ActiveTool.IsTransient = transient;
+            return;
+        }
 
         if (!tool.Toolbar.SettingsGenerated)
             tool.Toolbar.GenerateSettings();
 
-        ActiveToolIsTransient = false;
+        if (ActiveTool != null) ActiveTool.IsTransient = false;
         bool shareToolbar = IPreferences.Current.GetPreference<bool>("EnableSharedToolbar");
         if (ActiveTool is not null)
         {
@@ -109,7 +120,7 @@ internal class ToolsViewModel : SubViewModel<ViewModelMain>
 
         LastActionTool = ActiveTool;
         ActiveTool = tool;
-
+        
         if (shareToolbar)
         {
             ActiveTool.Toolbar.LoadSharedSettings();
@@ -126,6 +137,7 @@ internal class ToolsViewModel : SubViewModel<ViewModelMain>
         ActiveTool.OnSelected();
 
         tool.IsActive = true;
+        ActiveTool.IsTransient = transient;
         SetToolCursor(tool.GetType());
 
         if (Owner.StylusSubViewModel != null)
@@ -138,12 +150,12 @@ internal class ToolsViewModel : SubViewModel<ViewModelMain>
     {
         if (parameter is Type type)
         {
-            SetActiveTool(type);
+            SetActiveTool(type, false);
             return;
         }
 
         ToolViewModel tool = (ToolViewModel)parameter;
-        SetActiveTool(tool.GetType());
+        SetActiveTool(tool.GetType(), false);
     }
 
     [Command.Basic("PixiEditor.Tools.IncreaseSize", 1, "Increase Tool Size", "Increase Tool Size", Key = Key.OemCloseBrackets)]
@@ -157,12 +169,24 @@ internal class ToolsViewModel : SubViewModel<ViewModelMain>
             toolbar.ToolSize = newSize;
     }
 
-    public void SetActiveTool(Type toolType)
+    public void SetActiveTool(Type toolType, bool transient)
     {
         if (!typeof(ToolViewModel).IsAssignableFrom(toolType))
             throw new ArgumentException($"'{toolType}' does not inherit from {typeof(ToolViewModel)}");
         ToolViewModel foundTool = ToolSet!.First(x => x.GetType() == toolType);
-        SetActiveTool(foundTool);
+        SetActiveTool(foundTool, transient);
+    }
+    
+    public void RestorePreviousTool()
+    {
+        if (LastActionTool != null)
+        {
+            SetActiveTool(LastActionTool, false);
+        }
+        else
+        {
+            SetActiveTool<PenToolViewModel>(false);
+        }
     }
 
     private void SetToolCursor(Type tool)
@@ -177,6 +201,22 @@ internal class ToolsViewModel : SubViewModel<ViewModelMain>
         }
     }
 
+    public void HandleToolRepeatShortcutDown()
+    {
+        if (ActiveTool is null or { IsTransient: false })
+        {
+            ShortcutController.BlockShortcutExecution("ShortcutDown");
+            ActiveTool.IsTransient = true;
+        }
+    }
+    
+    public void HandleToolShortcutUp()
+    {
+        if (ActiveTool.IsTransient && LastActionTool is { } tool)
+            SetActiveTool(tool, false);
+        ShortcutController.UnblockShortcutExecution("ShortcutDown");
+    }
+
     public void LeftMouseButtonDownInlet(VecD canvasPos)
     {
         ActiveTool?.OnLeftMouseButtonDown(canvasPos);

+ 1 - 0
src/PixiEditor/ViewModels/SubViewModels/Tools/Tool.cs

@@ -12,6 +12,7 @@ namespace PixiEditor.ViewModels.SubViewModels.Tools;
 
 internal abstract class ToolViewModel : NotifyableObject
 {
+    public bool IsTransient { get; set; } = false;
     public KeyCombination Shortcut { get; set; }
 
     public virtual string ToolName => GetType().Name.Replace("Tool", string.Empty).Replace("ViewModel", string.Empty);