Browse Source

Merge pull request #80 from PixiEditor/moveVPTool

Added Move Viewport (Pan) Tool
Krzysztof Krysiński 4 years ago
parent
commit
83ce96efeb

+ 9 - 4
PixiEditor/Helpers/GlobalMouseHook.cs

@@ -4,6 +4,7 @@ using System.Diagnostics;
 using System.Diagnostics.CodeAnalysis;
 using System.Runtime.InteropServices;
 using System.Windows;
+using System.Windows.Input;
 
 namespace PixiEditor.Helpers
 {
@@ -32,7 +33,7 @@ namespace PixiEditor.Helpers
 
         public static void RaiseMouseUp()
         {
-            MouseUp?.Invoke(default, default);
+            MouseUp?.Invoke(default, default, default);
         }
 
         private static void Unsubscribe()
@@ -73,11 +74,13 @@ namespace PixiEditor.Helpers
             if (nCode >= 0)
             {
                 MSLLHOOKSTRUCT mouseHookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
-                if (wParam == WM_LBUTTONUP)
+                if (wParam == WM_LBUTTONUP || wParam == WM_MBUTTONUP || wParam == WM_RBUTTONUP)
                 {
                     if (MouseUp != null)
                     {
-                        MouseUp.Invoke(null, new Point(mouseHookStruct.pt.x, mouseHookStruct.pt.y));
+                        MouseButton button = wParam == WM_LBUTTONUP ? MouseButton.Left
+                            : wParam == WM_MBUTTONUP ? MouseButton.Middle : MouseButton.Right;
+                        MouseUp.Invoke(null, new Point(mouseHookStruct.pt.x, mouseHookStruct.pt.y), button);
                     }
                 }
             }
@@ -86,6 +89,8 @@ namespace PixiEditor.Helpers
 
         private const int WH_MOUSE_LL = 14;
         private const int WM_LBUTTONUP = 0x0202;
+        private const int WM_MBUTTONUP = 0x0208;
+        private const int WM_RBUTTONUP = 0x0205;
 
         [StructLayout(LayoutKind.Sequential)]
         private struct POINT
@@ -127,5 +132,5 @@ namespace PixiEditor.Helpers
         private static extern IntPtr GetModuleHandle(string name);
     }
 
-    public delegate void MouseUpEventHandler(object sender, Point p);
+    public delegate void MouseUpEventHandler(object sender, Point p, MouseButton button);
 }

+ 16 - 3
PixiEditor/Models/Controllers/BitmapManager.cs

@@ -12,6 +12,7 @@ using PixiEditor.Models.ImageManipulation;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Tools;
+using PixiEditor.Models.Tools.Tools;
 using PixiEditor.Models.Tools.ToolSettings.Settings;
 
 namespace PixiEditor.Models.Controllers
@@ -84,6 +85,8 @@ namespace PixiEditor.Models.Controllers
             MouseController.StartedRecordingChanges += MouseController_StartedRecordingChanges;
             MouseController.MousePositionChanged += Controller_MousePositionChanged;
             MouseController.StoppedRecordingChanges += MouseController_StoppedRecordingChanges;
+            MouseController.OnMouseDown += MouseController_OnMouseDown;
+            MouseController.OnMouseUp += MouseController_OnMouseUp;
             BitmapOperations = new BitmapOperationsUtility(this);
             ReadonlyToolUtility = new ReadonlyToolUtility();
         }
@@ -91,6 +94,16 @@ namespace PixiEditor.Models.Controllers
         public event EventHandler<LayersChangedEventArgs> LayersChanged;
         public event EventHandler<DocumentChangedEventArgs> DocumentChanged;
 
+        private void MouseController_OnMouseDown(object sender, MouseEventArgs e)
+        {
+            SelectedTool.OnMouseDown(e);
+        }
+
+        private void MouseController_OnMouseUp(object sender, MouseEventArgs e)
+        {
+            SelectedTool.OnMouseUp(e);
+        }
+
         public void SetActiveTool(Tool tool)
         {
             PreviewLayer = null;
@@ -174,18 +187,18 @@ namespace PixiEditor.Models.Controllers
 
         private bool IsDraggingViewport()
         {
-            return Keyboard.IsKeyDown(Key.LeftShift) && !(SelectedTool is ShapeTool);
+            return SelectedTool is MoveViewportTool;
         }
 
         private void MouseController_StartedRecordingChanges(object sender, EventArgs e)
         {
-            SelectedTool.OnMouseDown(new MouseEventArgs(Mouse.PrimaryDevice, (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds()));
+            SelectedTool.OnRecordingLeftMouseDown(new MouseEventArgs(Mouse.PrimaryDevice, (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds()));
             PreviewLayer = null;
         }
 
         private void MouseController_StoppedRecordingChanges(object sender, EventArgs e)
         {
-            SelectedTool.OnMouseUp(new MouseEventArgs(Mouse.PrimaryDevice, (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds()));
+            SelectedTool.OnStoppedRecordingMouseUp(new MouseEventArgs(Mouse.PrimaryDevice, (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds()));
             if (IsOperationTool(SelectedTool) && ((BitmapOperationTool) SelectedTool).RequiresPreviewLayer)
                 BitmapOperations.StopAction();
         }

+ 19 - 0
PixiEditor/Models/Controllers/MouseMovementController.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Windows.Input;
 using Accessibility;
 using PixiEditor.Models.Position;
 
@@ -11,6 +12,8 @@ namespace PixiEditor.Models.Controllers
         public bool IsRecordingChanges { get; private set; }
         public bool ClickedOnCanvas { get; set; }
         public event EventHandler StartedRecordingChanges;
+        public event EventHandler<MouseEventArgs> OnMouseDown;
+        public event EventHandler<MouseEventArgs> OnMouseUp;
         public event EventHandler<MouseMovementEventArgs> MousePositionChanged;
         public event EventHandler StoppedRecordingChanges;
 
@@ -44,6 +47,22 @@ namespace PixiEditor.Models.Controllers
             MousePositionChanged?.Invoke(this, new MouseMovementEventArgs(mouseCoordinates));
         }
 
+        /// <summary>
+        /// Plain mouse down, does not affect mouse recordings
+        /// </summary>
+        public void MouseDown(MouseEventArgs args)
+        {
+            OnMouseDown?.Invoke(this, args);
+        }
+
+        /// <summary>
+        /// Plain mouse up, does not affect mouse recordings
+        /// </summary>
+        public void MouseUp(MouseEventArgs args)
+        {
+            OnMouseUp?.Invoke(this, args);
+        }
+
         public void StopRecordingMouseMovementChanges()
         {
             if (IsRecordingChanges)

+ 4 - 1
PixiEditor/Models/Tools/Tool.cs

@@ -30,9 +30,12 @@ namespace PixiEditor.Models.Tools
         public bool CanStartOutsideCanvas { get; set; } = false;
 
         public virtual void OnMouseDown(MouseEventArgs e) { }
-
         public virtual void OnMouseUp(MouseEventArgs e) { }
 
+        public virtual void OnRecordingLeftMouseDown(MouseEventArgs e) { }
+
+        public virtual void OnStoppedRecordingMouseUp(MouseEventArgs e) { }
+
         public virtual void OnMouseMove(MouseEventArgs e) { }
 
         public virtual void AfterAddedUndo() { }

+ 1 - 0
PixiEditor/Models/Tools/ToolType.cs

@@ -3,6 +3,7 @@
     public enum ToolType
     {
         None,
+        MoveViewport,
         Move,
         Pen,
         Select,

+ 1 - 1
PixiEditor/Models/Tools/Tools/BrightnessTool.cs

@@ -28,7 +28,7 @@ namespace PixiEditor.Models.Tools.Tools
             Toolbar = new BrightnessToolToolbar(CorrectionFactor);
         }
 
-        public override void OnMouseDown(MouseEventArgs e)
+        public override void OnRecordingLeftMouseDown(MouseEventArgs e)
         {
             _pixelsVisited.Clear();
         }

+ 1 - 1
PixiEditor/Models/Tools/Tools/MoveTool.cs

@@ -62,7 +62,7 @@ namespace PixiEditor.Models.Tools.Tools
             }
         }
 
-        public override void OnMouseUp(MouseEventArgs e) //This adds undo if there is no selection, reason why this isn't in AfterUndoAdded,
+        public override void OnStoppedRecordingMouseUp(MouseEventArgs e) //This adds undo if there is no selection, reason why this isn't in AfterUndoAdded,
         {   //is because it doesn't fire if no pixel changes were made.
             if (_currentSelection != null && _currentSelection.Length == 0)
             {

+ 50 - 0
PixiEditor/Models/Tools/Tools/MoveViewportTool.cs

@@ -0,0 +1,50 @@
+using PixiEditor.Models.Position;
+using PixiEditor.ViewModels;
+using System.Drawing;
+using System.Windows.Input;
+
+namespace PixiEditor.Models.Tools.Tools
+{
+    public class MoveViewportTool : ReadonlyTool
+    {
+        public override ToolType ToolType => ToolType.MoveViewport;
+        private Point _clickPoint;
+
+        public MoveViewportTool()
+        {
+            HideHighlight = true;
+            Cursor = Cursors.SizeAll;
+            Tooltip = "Move viewport. (H)";
+        }
+
+        public override void OnMouseDown(MouseEventArgs e)
+        {
+            if (e.LeftButton == MouseButtonState.Pressed || e.MiddleButton == MouseButtonState.Pressed)
+            {
+                _clickPoint = MousePositionConverter.GetCursorPosition();
+            }
+        }
+
+        public override void OnMouseMove(MouseEventArgs e)
+        {
+            if (e.LeftButton == MouseButtonState.Pressed || e.MiddleButton == MouseButtonState.Pressed)
+            {
+                var point = MousePositionConverter.GetCursorPosition();
+                ViewModelMain.Current.ViewportPosition = new System.Windows.Point(point.X - _clickPoint.X, 
+                    point.Y - _clickPoint.Y);
+            }
+        }
+
+        public override void OnMouseUp(MouseEventArgs e)
+        {
+            if (e.MiddleButton == MouseButtonState.Pressed)
+            {
+                ViewModelMain.Current.SetActiveTool(ViewModelMain.Current.LastActionTool);
+            }
+        }
+
+        public override void Use(Coordinates[] pixels)
+        {
+        }
+    }
+}

+ 2 - 2
PixiEditor/Models/Tools/Tools/SelectTool.cs

@@ -25,7 +25,7 @@ namespace PixiEditor.Models.Tools.Tools
             Toolbar = new SelectToolToolbar();
         }
 
-        public override void OnMouseDown(MouseEventArgs e)
+        public override void OnRecordingLeftMouseDown(MouseEventArgs e)
         {
             Enum.TryParse((Toolbar.GetSetting<DropdownSetting>("Mode")?.Value as ComboBoxItem)?.Content as string, out SelectionType);
 
@@ -35,7 +35,7 @@ namespace PixiEditor.Models.Tools.Tools
                 _oldSelection = ViewModelMain.Current.ActiveSelection;
         }
 
-        public override void OnMouseUp(MouseEventArgs e)
+        public override void OnStoppedRecordingMouseUp(MouseEventArgs e)
         {
             if (ViewModelMain.Current.ActiveSelection.SelectedPoints.Count() <= 1)
             {

+ 2 - 2
PixiEditor/Models/Tools/Tools/ZoomTool.cs

@@ -25,7 +25,7 @@ namespace PixiEditor.Models.Tools.Tools
             _pixelsPerZoomMultiplier = _workAreaWidth / ZoomSensitivityMultiplier;
         }
 
-        public override void OnMouseDown(MouseEventArgs e)
+        public override void OnRecordingLeftMouseDown(MouseEventArgs e)
         {
             _startingX = MousePositionConverter.GetCursorPosition().X;
             ViewModelMain.Current.ZoomPercentage = 100; //This resest the value, so callback in MainDrawingPanel can fire again later
@@ -43,7 +43,7 @@ namespace PixiEditor.Models.Tools.Tools
             }
         }
 
-        public override void OnMouseUp(MouseEventArgs e)
+        public override void OnStoppedRecordingMouseUp(MouseEventArgs e)
         {
             if (e.LeftButton == MouseButtonState.Released && e.RightButton == MouseButtonState.Released && 
                 _startingX == MousePositionConverter.GetCursorPosition().X)

+ 27 - 6
PixiEditor/ViewModels/ViewModelMain.cs

@@ -196,6 +196,19 @@ namespace PixiEditor.ViewModels
             }
         }
 
+        private Point _viewPortPosition;
+
+        public Point ViewportPosition
+        {
+            get => _viewPortPosition;
+            set 
+            {
+                _viewPortPosition = value;
+                RaisePropertyChanged(nameof(ViewportPosition));
+            }
+        }
+
+
         private bool _updateReadyToInstall = false;
 
         public bool UpdateReadyToInstall
@@ -224,7 +237,7 @@ namespace PixiEditor.ViewModels
         }
 
         private bool _restoreToolOnKeyUp = false;
-        private Tool _lastActionTool;
+        public Tool LastActionTool { get; private set; }
 
         public UpdateChecker UpdateChecker { get; set; }
 
@@ -273,7 +286,7 @@ namespace PixiEditor.ViewModels
             RestartApplicationCommand = new RelayCommand(RestartApplication);
             ToolSet = new ObservableCollection<Tool>
             {
-                new MoveTool(), new PenTool(), new SelectTool(), new FloodFill(), new LineTool(),
+                new MoveViewportTool(), new MoveTool(), new PenTool(), new SelectTool(), new FloodFill(), new LineTool(),
                 new CircleTool(), new RectangleTool(), new EraserTool(), new ColorPickerTool(), new BrightnessTool(), 
                 new ZoomTool()
             };
@@ -293,6 +306,7 @@ namespace PixiEditor.ViewModels
                     new Shortcut(Key.V, SelectToolCommand, ToolType.Move),
                     new Shortcut(Key.M, SelectToolCommand, ToolType.Select),
                     new Shortcut(Key.Z, SelectToolCommand, ToolType.Zoom),
+                    new Shortcut(Key.H, SelectToolCommand, ToolType.MoveViewport),
                     new Shortcut(Key.OemPlus, ZoomCommand, 115),
                     new Shortcut(Key.OemMinus, ZoomCommand, 85),
                     new Shortcut(Key.OemOpenBrackets, ChangeToolSizeCommand, -1),
@@ -620,7 +634,7 @@ namespace PixiEditor.ViewModels
             if (_restoreToolOnKeyUp && ShortcutController.LastShortcut != null && ShortcutController.LastShortcut.ShortcutKey == args.Key)
             {
                 _restoreToolOnKeyUp = false;
-                SetActiveTool(_lastActionTool);
+                SetActiveTool(LastActionTool);
                 ShortcutController.BlockShortcutExecution = false;
             }
         }
@@ -724,7 +738,7 @@ namespace PixiEditor.ViewModels
             if (activeTool != null) activeTool.IsActive = false;
 
             tool.IsActive = true;
-            _lastActionTool = BitmapManager.SelectedTool;
+            LastActionTool = BitmapManager.SelectedTool;
             BitmapManager.SetActiveTool(tool);
             SetToolCursor(tool.ToolType);
         }
@@ -750,6 +764,8 @@ namespace PixiEditor.ViewModels
                     BitmapManager.MouseController.RecordMouseMovementChange(MousePositionConverter.CurrentCoordinates);
                 }
             }
+            BitmapManager.MouseController.MouseDown(new MouseEventArgs(Mouse.PrimaryDevice,
+                (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds()));
 
             // Mouse down is guaranteed to only be raised from within this application, so by subscribing here we
             // only listen for mouse up events that occurred as a result of a mouse down within this application.
@@ -758,10 +774,15 @@ namespace PixiEditor.ViewModels
         }
 
         // this is public for testing.
-        public void MouseHook_OnMouseUp(object sender, Point p)
+        public void MouseHook_OnMouseUp(object sender, Point p, MouseButton button)
         {
             GlobalMouseHook.OnMouseUp -= MouseHook_OnMouseUp;
-            BitmapManager.MouseController.StopRecordingMouseMovementChanges();
+            if (button == MouseButton.Left)
+            {
+                BitmapManager.MouseController.StopRecordingMouseMovementChanges();
+            }
+            BitmapManager.MouseController.MouseUp(new MouseEventArgs(Mouse.PrimaryDevice, 
+                (int)DateTimeOffset.UtcNow.ToUnixTimeSeconds()));
         }
 
         /// <summary>

+ 2 - 1
PixiEditor/Views/MainDrawingPanel.xaml

@@ -10,7 +10,8 @@
              mc:Ignorable="d" PreviewMouseDown="mainDrawingPanel_MouseDown" PreviewMouseUp="mainDrawingPanel_PreviewMouseUp"
              d:DesignHeight="450" d:DesignWidth="800" x:Name="mainDrawingPanel" PreviewMouseWheel="Zoombox_MouseWheel">
     <xctk:Zoombox PreviewMouseDown="Zoombox_PreviewMouseDown" Cursor="{Binding Cursor}" Name="Zoombox" KeepContentInBounds="True"
-                  Loaded="Zoombox_Loaded" IsAnimated="False" CurrentViewChanged="Zoombox_CurrentViewChanged" DragModifiers="Shift" ZoomModifiers="None">
+                  Loaded="Zoombox_Loaded" IsAnimated="False" MouseDown="Zoombox_MouseDown"
+                  CurrentViewChanged="Zoombox_CurrentViewChanged" DragModifiers="Blocked" ZoomModifiers="None">
         <i:Interaction.Triggers>
             <i:EventTrigger EventName="MouseMove">
                 <i:InvokeCommandAction Command="{Binding MouseMoveCommand, ElementName=mainDrawingPanel, Mode=OneWay}" />

+ 67 - 0
PixiEditor/Views/MainDrawingPanel.xaml.cs

@@ -7,6 +7,7 @@ using System.Windows.Input;
 using PixiEditor.Models.Tools.Tools;
 using Xceed.Wpf.Toolkit.Core.Input;
 using Xceed.Wpf.Toolkit.Zoombox;
+using PixiEditor.Models.Position;
 
 namespace PixiEditor.Views
 {
@@ -58,6 +59,18 @@ namespace PixiEditor.Views
             DependencyProperty.Register("ZoomPercentage", typeof(double), typeof(MainDrawingPanel), new PropertyMetadata(0.0, ZoomPercentegeChanged));
 
 
+
+        public Point ViewportPosition
+        {
+            get { return (Point)GetValue(ViewportPositionProperty); }
+            set { SetValue(ViewportPositionProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for ViewportPosition.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty ViewportPositionProperty =
+            DependencyProperty.Register("ViewportPosition", typeof(Point),
+                typeof(MainDrawingPanel), new PropertyMetadata(default(Point), ViewportPosCallback));
+
         public bool Center
         {
             get => (bool) GetValue(CenterProperty);
@@ -103,6 +116,31 @@ namespace PixiEditor.Views
             set => SetValue(IsUsingZoomToolProperty, value);
         }
 
+        public ICommand MiddleMouseClickedCommand
+        {
+            get { return (ICommand)GetValue(MiddleMouseClickedCommandProperty); }
+            set { SetValue(MiddleMouseClickedCommandProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for MiddleMouseClickedCommand.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty MiddleMouseClickedCommandProperty =
+            DependencyProperty.Register("MiddleMouseClickedCommand", typeof(ICommand), typeof(MainDrawingPanel), new PropertyMetadata(default(ICommand)));
+
+
+
+        public object MiddleMouseClickedCommandParameter
+        {
+            get { return (object)GetValue(MiddleMouseClickedCommandParameterProperty); }
+            set { SetValue(MiddleMouseClickedCommandParameterProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for MiddleMouseClickedCommandParameter.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty MiddleMouseClickedCommandParameterProperty =
+            DependencyProperty.Register("MiddleMouseClickedCommandParameter", typeof(object), typeof(MainDrawingPanel), 
+                new PropertyMetadata(default(object)));
+
+
+
         private static void ZoomPercentegeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
         {
             MainDrawingPanel panel = (MainDrawingPanel)d;
@@ -115,6 +153,7 @@ namespace PixiEditor.Views
         }
 
         public double ClickScale;
+        public Point ClickPosition;
 
         public MainDrawingPanel()
         {
@@ -122,6 +161,24 @@ namespace PixiEditor.Views
             Zoombox.ZoomToSelectionModifiers = new KeyModifierCollection() { KeyModifier.RightAlt };
         }
 
+        private static void ViewportPosCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
+        {
+            MainDrawingPanel panel = (MainDrawingPanel)d;
+            if (PresentationSource.FromVisual(panel.Zoombox) == null)
+            {
+                panel.Zoombox.Position = default;
+                return;
+            }           
+            TranslateZoombox(panel, (Point)e.NewValue);
+        }
+
+        private static void TranslateZoombox(MainDrawingPanel panel, Point vector)
+        {
+            var newPos = new Point(panel.ClickPosition.X + vector.X,
+                panel.ClickPosition.Y + vector.Y);
+            panel.Zoombox.Position = newPos;
+        }
+
         private void Zoombox_CurrentViewChanged(object sender, ZoomboxViewChangedEventArgs e)
         {
             Zoombox.MinScale = 32 / ((FrameworkElement)Item).Width;
@@ -173,6 +230,7 @@ namespace PixiEditor.Views
         {
             IsUsingZoomTool = ViewModelMain.Current.BitmapManager.SelectedTool is ZoomTool;
             Mouse.Capture((IInputElement)sender, CaptureMode.SubTree);
+            ClickPosition = ((FrameworkElement)Item).TranslatePoint(new Point(0, 0), Zoombox);
             SetClickValues();
         }
 
@@ -180,5 +238,14 @@ namespace PixiEditor.Views
         {
             ((IInputElement)sender).ReleaseMouseCapture();
         }
+
+        private void Zoombox_MouseDown(object sender, MouseButtonEventArgs e)
+        {
+            if (e.MiddleButton == MouseButtonState.Pressed && 
+                MiddleMouseClickedCommand.CanExecute(MiddleMouseClickedCommandParameter))
+            {
+                MiddleMouseClickedCommand.Execute(MiddleMouseClickedCommandParameter);
+            }
+        }
     }
 }

+ 5 - 2
PixiEditor/Views/MainWindow.xaml

@@ -5,7 +5,7 @@
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:vm="clr-namespace:PixiEditor.ViewModels"
         xmlns:vws="clr-namespace:PixiEditor.Views"
-        xmlns:helpers="clr-namespace:PixiEditor.Helpers"
+        xmlns:tools="clr-namespace:PixiEditor.Models.Tools"
         xmlns:converters="clr-namespace:PixiEditor.Helpers.Converters"
         xmlns:behaviors="clr-namespace:PixiEditor.Helpers.Behaviours"
         xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
@@ -163,7 +163,10 @@
         <Grid Grid.Column="1" Grid.Row="2" Background="#303030" Margin="0,7,5,0">
             <Grid>
                 <vws:MainDrawingPanel ZoomPercentage="{Binding ZoomPercentage, Mode=TwoWay}" Center="{Binding RecenterZoombox, Mode=TwoWay}" x:Name="DrawingPanel"
-                                      CenterOnStart="True" Cursor="{Binding ToolCursor}">
+                                      CenterOnStart="True" Cursor="{Binding ToolCursor}" 
+                                      MiddleMouseClickedCommand="{Binding SelectToolCommand}" 
+                                      MiddleMouseClickedCommandParameter="{x:Static tools:ToolType.MoveViewport}"
+                                      ViewportPosition="{Binding ViewportPosition, Mode=TwoWay}">
                     <i:Interaction.Triggers>
                         <i:EventTrigger EventName="MouseMove">
                             <i:InvokeCommandAction Command="{Binding MouseMoveCommand}" />

+ 1 - 1
PixiEditor/Views/MainWindow.xaml.cs

@@ -22,7 +22,7 @@ namespace PixiEditor
             InitializeComponent();
             StateChanged += MainWindowStateChangeRaised;
             MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight;
-            viewModel = ((ViewModelMain)DataContext);
+            viewModel = (ViewModelMain)DataContext;
             viewModel.CloseAction = Close;
         }
 

+ 1 - 1
PixiEditorTests/ViewModelsTests/ViewModelMainTests.cs

@@ -88,7 +88,7 @@ namespace PixiEditorTests.ViewModelsTests
 
             Assert.True(viewModel.BitmapManager.MouseController.IsRecordingChanges);
 
-            viewModel.MouseHook_OnMouseUp(default, default);
+            viewModel.MouseHook_OnMouseUp(default, default, default);
 
             Assert.False(viewModel.BitmapManager.MouseController.IsRecordingChanges);
         }