Просмотр исходного кода

Merge pull request #877 from PixiEditor/fixes/4.04.2025

Added ctrl scroll to change tool size
Krzysztof Krysiński 5 месяцев назад
Родитель
Сommit
876ac9594c

+ 3 - 1
src/PixiEditor/Models/Controllers/InputDevice/MouseInputFilter.cs

@@ -11,6 +11,7 @@ internal class MouseInputFilter
     public EventHandler<MouseOnCanvasEventArgs> OnMouseDown;
     public EventHandler<VecD> OnMouseMove;
     public EventHandler<MouseOnCanvasEventArgs> OnMouseUp;
+    public EventHandler<ScrollOnCanvasEventArgs> OnMouseWheel;
 
 
     private Dictionary<MouseButton, bool> buttonStates = new()
@@ -35,7 +36,6 @@ internal class MouseInputFilter
     }
 
     public void MouseMoveInlet(object args) => OnMouseMove?.Invoke(this, ((MouseOnCanvasEventArgs)args).PositionOnCanvas);
-
     public void MouseUpInlet(object args) => MouseUpInlet(((MouseOnCanvasEventArgs)args));
     public void MouseUpInlet(object? sender, Point p, MouseButton button) => MouseUpInlet(button);
     public void MouseUpInlet(MouseOnCanvasEventArgs args)
@@ -49,6 +49,8 @@ internal class MouseInputFilter
         OnMouseUp?.Invoke(this, args);
     }
 
+    public void MouseWheelInlet(ScrollOnCanvasEventArgs e) => OnMouseWheel?.Invoke(this, e);
+
     public void DeactivatedInlet(object? sender, EventArgs e)
     {
         MouseOnCanvasEventArgs argsLeft = new(MouseButton.Left, VecD.Zero, KeyModifiers.None, 0);

+ 21 - 0
src/PixiEditor/Models/Controllers/InputDevice/ScrollOnCanvasEventArgs.cs

@@ -0,0 +1,21 @@
+using Avalonia.Input;
+using Drawie.Backend.Core.Numerics;
+using Drawie.Numerics;
+
+namespace PixiEditor.Models.Controllers.InputDevice;
+
+internal class ScrollOnCanvasEventArgs : EventArgs
+{
+    public VecD Delta { get; }
+    public VecD PositionOnCanvas { get; }
+    public KeyModifiers KeyModifiers { get; }
+    public bool Handled { get; set; }
+
+
+    public ScrollOnCanvasEventArgs(VecD delta, VecD positionOnCanvas, KeyModifiers keyModifiers)
+    {
+        Delta = delta;
+        PositionOnCanvas = positionOnCanvas;
+        KeyModifiers = keyModifiers;
+    }
+}

+ 1 - 0
src/PixiEditor/Models/Handlers/IToolsHandler.cs

@@ -36,4 +36,5 @@ internal interface IToolsHandler : IHandler
     public void OnPreRedoInlet();
     public void OnPreUndoInlet();
     public void QuickToolSwitchInlet();
+    public void ChangeToolSize(double by);
 }

+ 17 - 0
src/PixiEditor/ViewModels/SubViewModels/IoViewModel.cs

@@ -36,6 +36,7 @@ internal class IoViewModel : SubViewModel<ViewModelMain>
     public RelayCommand<MouseOnCanvasEventArgs> MouseDownCommand { get; set; }
     public RelayCommand PreviewMouseMiddleButtonCommand { get; set; }
     public RelayCommand<MouseOnCanvasEventArgs> MouseUpCommand { get; set; }
+    public RelayCommand<ScrollOnCanvasEventArgs> MouseWheelCommand { get; set; }
 
     private MouseInputFilter mouseFilter = new();
     private KeyboardInputFilter keyboardFilter = new();
@@ -46,6 +47,7 @@ internal class IoViewModel : SubViewModel<ViewModelMain>
         MouseDownCommand = new RelayCommand<MouseOnCanvasEventArgs>(mouseFilter.MouseDownInlet);
         MouseMoveCommand = new RelayCommand<MouseOnCanvasEventArgs>(mouseFilter.MouseMoveInlet);
         MouseUpCommand = new RelayCommand<MouseOnCanvasEventArgs>(mouseFilter.MouseUpInlet);
+        MouseWheelCommand = new RelayCommand<ScrollOnCanvasEventArgs>(mouseFilter.MouseWheelInlet);
         PreviewMouseMiddleButtonCommand = new RelayCommand(OnMiddleMouseButton);
         Owner.LayoutSubViewModel.LayoutManager.WindowFloated += OnLayoutManagerOnWindowFloated;
         // TODO: Implement mouse capturing
@@ -63,6 +65,7 @@ internal class IoViewModel : SubViewModel<ViewModelMain>
         mouseFilter.OnMouseDown += OnMouseDown;
         mouseFilter.OnMouseMove += OnMouseMove;
         mouseFilter.OnMouseUp += OnMouseUp;
+        mouseFilter.OnMouseWheel += HandleMouseWheel;
 
         keyboardFilter.OnAnyKeyDown += OnKeyDown;
         keyboardFilter.OnAnyKeyUp += OnKeyUp;
@@ -357,6 +360,20 @@ internal class IoViewModel : SubViewModel<ViewModelMain>
         }
     }
 
+    private void HandleMouseWheel(object sender, ScrollOnCanvasEventArgs args)
+    {
+        if (Owner.DocumentManagerSubViewModel.ActiveDocument is null)
+            return;
+
+        if (args.KeyModifiers == KeyModifiers.Control)
+        {
+            var delta = args.Delta;
+
+            Owner.ToolsSubViewModel.ChangeToolSize(delta.Y);
+            args.Handled = true;
+        }
+    }
+
     private void ToolSessionFinished()
     {
         Owner.ColorsSubViewModel.SwapColors(null);

+ 3 - 3
src/PixiEditor/ViewModels/SubViewModels/ToolsViewModel.cs

@@ -309,11 +309,11 @@ internal class ToolsViewModel : SubViewModel<ViewModelMain>, IToolsHandler
         SetActiveTool(tool.GetType(), false, source);
     }
 
-    [Command.Basic("PixiEditor.Tools.IncreaseSize", 1, "INCREASE_TOOL_SIZE", "INCREASE_TOOL_SIZE",
+    [Command.Basic("PixiEditor.Tools.IncreaseSize", 1d, "INCREASE_TOOL_SIZE", "INCREASE_TOOL_SIZE",
         CanExecute = "PixiEditor.Tools.CanChangeToolSize", Key = Key.OemCloseBrackets, AnalyticsTrack = true)]
-    [Command.Basic("PixiEditor.Tools.DecreaseSize", -1, "DECREASE_TOOL_SIZE", "DECREASE_TOOL_SIZE",
+    [Command.Basic("PixiEditor.Tools.DecreaseSize", -1d, "DECREASE_TOOL_SIZE", "DECREASE_TOOL_SIZE",
         CanExecute = "PixiEditor.Tools.CanChangeToolSize", Key = Key.OemOpenBrackets, AnalyticsTrack = true)]
-    public void ChangeToolSize(int increment)
+    public void ChangeToolSize(double increment)
     {
         if (ActiveTool?.Toolbar is not IToolSizeToolbar toolbar)
             return;

+ 1 - 0
src/PixiEditor/Views/Dock/DocumentTemplate.axaml

@@ -25,6 +25,7 @@
         MouseDownCommand="{Binding Path=IoSubViewModel.MouseDownCommand, Source={viewModels1:MainVM}}"
         MouseMoveCommand="{Binding Path=IoSubViewModel.MouseMoveCommand, Source={viewModels1:MainVM}}"
         MouseUpCommand="{Binding Path=IoSubViewModel.MouseUpCommand, Source={viewModels1:MainVM}}"
+        MouseWheelCommand="{Binding Path=IoSubViewModel.MouseWheelCommand, Source={viewModels1:MainVM}}"
         MiddleMouseClickedCommand="{Binding IoSubViewModel.PreviewMouseMiddleButtonCommand, Source={viewModels1:MainVM}}"
         Cursor="{Binding ToolsSubViewModel.ToolCursor, Source={viewModels1:MainVM}}"
         GridLinesVisible="{Binding ViewportSubViewModel.GridLinesEnabled, Source={viewModels1:MainVM}}"

+ 33 - 4
src/PixiEditor/Views/Main/ViewportControls/Viewport.axaml.cs

@@ -96,6 +96,10 @@ internal partial class Viewport : UserControl, INotifyPropertyChanged
     public static readonly StyledProperty<ICommand> MiddleMouseClickedCommandProperty =
         AvaloniaProperty.Register<Viewport, ICommand>(nameof(MiddleMouseClickedCommand), null);
 
+    public static readonly StyledProperty<ICommand> MouseWheelCommandProperty =
+        AvaloniaProperty.Register<Viewport, ICommand>(
+            nameof(MouseWheelCommand));
+
     public static readonly StyledProperty<ViewportColorChannels> ChannelsProperty =
         AvaloniaProperty.Register<Viewport, ViewportColorChannels>(
             nameof(Channels));
@@ -152,6 +156,12 @@ internal partial class Viewport : UserControl, INotifyPropertyChanged
         set => SetValue(StylusButtonDownCommandProperty, value);
     }
 
+    public ICommand MouseWheelCommand
+    {
+        get => GetValue(MouseWheelCommandProperty);
+        set => SetValue(MouseWheelCommandProperty, value);
+    }
+
     public bool UseTouchGestures
     {
         get => (bool)GetValue(UseTouchGesturesProperty);
@@ -187,6 +197,7 @@ internal partial class Viewport : UserControl, INotifyPropertyChanged
         get => (double)GetValue(GridLinesXSizeProperty);
         set => SetValue(GridLinesXSizeProperty, value);
     }
+
     public double GridLinesYSize
     {
         get => (double)GetValue(GridLinesYSizeProperty);
@@ -318,8 +329,9 @@ internal partial class Viewport : UserControl, INotifyPropertyChanged
     public static readonly StyledProperty<ObservableCollection<string>> AvailableRenderOutputsProperty =
         AvaloniaProperty.Register<Viewport, ObservableCollection<string>>(nameof(AvailableRenderOutputs));
 
-    public static readonly StyledProperty<string> ViewportRenderOutputProperty = AvaloniaProperty.Register<Viewport, string>(
-        nameof(ViewportRenderOutput), "DEFAULT");
+    public static readonly StyledProperty<string> ViewportRenderOutputProperty =
+        AvaloniaProperty.Register<Viewport, string>(
+            nameof(ViewportRenderOutput), "DEFAULT");
 
     public string ViewportRenderOutput
     {
@@ -359,6 +371,7 @@ internal partial class Viewport : UserControl, INotifyPropertyChanged
         //TODO: It's weird that I had to do it this way, right click didn't raise Image_MouseUp otherwise.
         viewportGrid.AddHandler(PointerReleasedEvent, Image_MouseUp, RoutingStrategies.Tunnel);
         viewportGrid.AddHandler(PointerPressedEvent, Image_MouseDown, RoutingStrategies.Bubble);
+        viewportGrid.AddHandler(PointerWheelChangedEvent, Image_MouseWheel, RoutingStrategies.Tunnel);
 
         Scene.PointerExited += (sender, args) => IsOverCanvas = false;
         Scene.PointerEntered += (sender, args) => IsOverCanvas = true;
@@ -475,7 +488,8 @@ internal partial class Viewport : UserControl, INotifyPropertyChanged
 
         var pos = e.GetPosition(Scene);
         VecD scenePos = Scene.ToZoomboxSpace(new VecD(pos.X, pos.Y));
-        MouseOnCanvasEventArgs? parameter = new MouseOnCanvasEventArgs(mouseButton, scenePos, e.KeyModifiers, e.ClickCount);
+        MouseOnCanvasEventArgs? parameter =
+            new MouseOnCanvasEventArgs(mouseButton, scenePos, e.KeyModifiers, e.ClickCount);
 
         if (MouseDownCommand.CanExecute(parameter))
             MouseDownCommand.Execute(parameter);
@@ -508,6 +522,21 @@ internal partial class Viewport : UserControl, INotifyPropertyChanged
             MouseUpCommand.Execute(parameter);
     }
 
+    private void Image_MouseWheel(object? sender, PointerWheelEventArgs e)
+    {
+        if (MouseWheelCommand is null)
+            return;
+
+        VecD delta = new VecD(e.Delta.X, e.Delta.Y);
+        Point pos = e.GetPosition(Scene);
+        VecD posOnCanvas = Scene.ToZoomboxSpace(new VecD(pos.X, pos.Y));
+        ScrollOnCanvasEventArgs args = new ScrollOnCanvasEventArgs(delta, posOnCanvas, e.KeyModifiers);
+        if (MouseWheelCommand.CanExecute(args))
+            MouseWheelCommand.Execute(args);
+
+        e.Handled = args.Handled;
+    }
+
     private void CenterZoomboxContent(object? sender, VecI args)
     {
         scene.CenterContent(args);
@@ -613,7 +642,7 @@ internal partial class Viewport : UserControl, INotifyPropertyChanged
     {
         if (e.Source is ComboBox comboBox)
         {
-            if(!comboBox.IsAttachedToVisualTree()) return;
+            if (!comboBox.IsAttachedToVisualTree()) return;
 
             if (e.AddedItems.Count > 0)
             {