Browse Source

Implemented Zoom tool

flabbet 5 years ago
parent
commit
3d3f8d6ef9

BIN
PixiEditor/Images/ZoomImage.png


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

@@ -132,10 +132,9 @@ namespace PixiEditor.Models.Controllers
 
         private void Controller_MousePositionChanged(object sender, MouseMovementEventArgs e)
         {
-            if (Mouse.LeftButton == MouseButtonState.Pressed && !IsDraggingViewport()
-                                                             && MouseController.ClickedOnCanvas && ActiveDocument != null)
+            if (Mouse.LeftButton == MouseButtonState.Pressed && !IsDraggingViewport() && ActiveDocument != null)
             {
-                ExecuteTool(e.NewPosition);   
+                ExecuteTool(e.NewPosition, MouseController.ClickedOnCanvas);   
             }
             else if (Mouse.LeftButton == MouseButtonState.Released)
             {
@@ -143,14 +142,21 @@ namespace PixiEditor.Models.Controllers
             }
         }
 
-        public void ExecuteTool(Coordinates newPosition)
+        public void ExecuteTool(Coordinates newPosition, bool clickedOnCanvas)
         {
-            if (IsOperationTool(SelectedTool))
-                BitmapOperations.ExecuteTool(newPosition,
-                    MouseController.LastMouseMoveCoordinates.ToList(), (BitmapOperationTool)SelectedTool);
-            else
-                ReadonlyToolUtility.ExecuteTool(MouseController.LastMouseMoveCoordinates.ToArray(),
-                    (ReadonlyTool)SelectedTool);
+            if (SelectedTool.CanStartOutsideCanvas || clickedOnCanvas)
+            {
+                if (IsOperationTool(SelectedTool))
+                {
+                    BitmapOperations.ExecuteTool(newPosition,
+                        MouseController.LastMouseMoveCoordinates.ToList(), (BitmapOperationTool)SelectedTool);
+                }
+                else
+                {
+                    ReadonlyToolUtility.ExecuteTool(MouseController.LastMouseMoveCoordinates.ToArray(),
+                        (ReadonlyTool)SelectedTool);
+                }
+            }
         }
 
         private bool IsDraggingViewport()

+ 2 - 2
PixiEditor/Models/Layers/Layer.cs

@@ -374,8 +374,8 @@ namespace PixiEditor.Models.Layers
 
         private void IncreaseSizeToTop(int newMinX, int newMinY)
         {
-            newMinX = Math.Clamp(Math.Min(newMinX, Width), -OffsetX, 0);
-            newMinY = Math.Clamp(Math.Min(newMinY, Height), -OffsetY, 0);
+            newMinX = Math.Clamp(Math.Min(newMinX, Width), Math.Min(-OffsetX, OffsetX), 0);
+            newMinY = Math.Clamp(Math.Min(newMinY, Height), Math.Min(-OffsetY, OffsetY), 0);
 
             Offset = new Thickness(Math.Clamp(OffsetX + newMinX, 0, MaxWidth),
                 Math.Clamp(OffsetY + newMinY, 0, MaxHeight), 0, 0);

+ 2 - 0
PixiEditor/Models/Tools/Tool.cs

@@ -27,9 +27,11 @@ namespace PixiEditor.Models.Tools
         public Toolbar Toolbar { get; set; } = new EmptyToolbar();
 
         private bool _isActive;
+        public bool CanStartOutsideCanvas { get; set; } = false;
 
         public virtual void OnMouseDown(MouseEventArgs e)
         {
+            
         }
 
         public virtual void OnMouseUp(MouseEventArgs e)

+ 9 - 4
PixiEditor/Models/Tools/Tools/ZoomTool.cs

@@ -15,6 +15,8 @@ namespace PixiEditor.Models.Tools.Tools
         public ZoomTool()
         {
             HideHighlight = true;
+            CanStartOutsideCanvas = true;
+            Tooltip = "Zooms viewport (Z). Click to zoom in, hold alt and click to zoom out.";            
         }
 
         public override void OnMouseDown(MouseEventArgs e)
@@ -28,19 +30,22 @@ namespace PixiEditor.Models.Tools.Tools
             if (e.LeftButton == MouseButtonState.Released && e.RightButton == MouseButtonState.Released && 
                 _startingX == MousePositionConverter.GetCursorPosition().X)
             {
-                double zoomModifier;
                 if (Keyboard.Modifiers.HasFlag(ModifierKeys.Alt))
                 {
-                    zoomModifier =  85;
+                    Zoom(85);
                 }
                 else
                 {
-                    zoomModifier = 115;
+                    Zoom(115);
                 }
-                ViewModelMain.Current.ZoomPercentage = zoomModifier;
             }
         }
 
+        public void Zoom(double percentage)
+        {
+            ViewModelMain.Current.ZoomPercentage = percentage;
+        }
+
         public override void Use(Coordinates[] pixels)
         {
             double xPos = MousePositionConverter.GetCursorPosition().X;

+ 17 - 2
PixiEditor/ViewModels/ViewModelMain.cs

@@ -79,6 +79,8 @@ namespace PixiEditor.ViewModels
         public RelayCommand CloseWindowCommand { get; set; }
         public RelayCommand CenterContentCommand { get; set; }
         public RelayCommand OpenHyperlinkCommand { get; set; }
+        public RelayCommand ZoomCommand { get; set; }
+
 
         private double _mouseXonCanvas;
 
@@ -236,6 +238,7 @@ namespace PixiEditor.ViewModels
             CloseWindowCommand = new RelayCommand(CloseWindow);
             CenterContentCommand = new RelayCommand(CenterContent, DocumentIsNotNull);
             OpenHyperlinkCommand = new RelayCommand(OpenHyperlink);
+            ZoomCommand = new RelayCommand(ZoomViewport);
             ToolSet = new ObservableCollection<Tool>
             {
                 new MoveTool(), new PenTool(), new SelectTool(), new FloodFill(), new LineTool(),
@@ -257,10 +260,13 @@ namespace PixiEditor.ViewModels
                     new Shortcut(Key.U, SelectToolCommand, ToolType.Brightness),
                     new Shortcut(Key.V, SelectToolCommand, ToolType.Move),
                     new Shortcut(Key.M, SelectToolCommand, ToolType.Select),
+                    new Shortcut(Key.Z, SelectToolCommand, ToolType.Zoom),
+                    new Shortcut(Key.OemPlus, ZoomCommand, 115),
+                    new Shortcut(Key.OemMinus, ZoomCommand, 85),
                     //Editor
                     new Shortcut(Key.X, SwapColorsCommand),
                     new Shortcut(Key.Y, RedoCommand, modifier: ModifierKeys.Control),
-                    new Shortcut(Key.Z, UndoCommand),
+                    new Shortcut(Key.Z, UndoCommand, modifier: ModifierKeys.Control),
                     new Shortcut(Key.D, DeselectCommand, modifier: ModifierKeys.Control),
                     new Shortcut(Key.A, SelectAllCommand, modifier: ModifierKeys.Control),
                     new Shortcut(Key.C, CopyCommand, modifier: ModifierKeys.Control),
@@ -286,6 +292,13 @@ namespace PixiEditor.ViewModels
             Current = this;
         }
 
+        private void ZoomViewport(object parameter)
+        {
+            double zoom = (int)parameter;
+            ZoomPercentage = zoom;
+            ZoomPercentage = 100;
+        }
+
         private void OpenHyperlink(object parameter)
         {
             if (parameter == null) return;
@@ -643,7 +656,9 @@ namespace PixiEditor.ViewModels
             {
                 if (!BitmapManager.MouseController.IsRecordingChanges)
                 {
-                    BitmapManager.MouseController.StartRecordingMouseMovementChanges(true);
+                    bool clickedOnCanvas = MouseXOnCanvas >= 0 && MouseXOnCanvas <= BitmapManager.ActiveDocument.Width &&
+                        MouseYOnCanvas >= 0 && MouseYOnCanvas <= BitmapManager.ActiveDocument.Height;
+                    BitmapManager.MouseController.StartRecordingMouseMovementChanges(clickedOnCanvas);
                     BitmapManager.MouseController.RecordMouseMovementChange(MousePositionConverter.CurrentCoordinates);
                 }
             }

+ 1 - 1
PixiEditor/Views/MainDrawingPanel.xaml

@@ -9,7 +9,7 @@
              xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
              mc:Ignorable="d"
              d:DesignHeight="450" d:DesignWidth="800" x:Name="mainDrawingPanel">
-    <xctk:Zoombox Cursor="{Binding Cursor}" IsAnimated="False" Name="Zoombox" KeepContentInBounds="True"
+    <xctk:Zoombox PreviewMouseDown="Zoombox_MouseDown"  Cursor="{Binding Cursor}" IsAnimated="False" Name="Zoombox" KeepContentInBounds="True"
                   Loaded="Zoombox_Loaded" DragModifiers="Shift" ZoomModifiers="None">
         <i:Interaction.Triggers>
             <i:EventTrigger EventName="MouseMove">

+ 6 - 1
PixiEditor/Views/MainDrawingPanel.xaml.cs

@@ -54,6 +54,11 @@ namespace PixiEditor.Views
         private static void ZoomPercentegeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
         {
             MainDrawingPanel panel = (MainDrawingPanel)d;
+            double percentage = (double)e.NewValue;
+            if(percentage == 100)
+            {
+                panel.ClickScale = panel.Zoombox.Scale;
+            }
             panel.Zoombox.ZoomTo(panel.ClickScale * ((double)e.NewValue / 100.0));
         }
 
@@ -63,7 +68,7 @@ namespace PixiEditor.Views
         {
             InitializeComponent();
             Zoombox.ZoomToSelectionModifiers = new KeyModifierCollection() { KeyModifier.RightAlt };
-            Zoombox.PreviewMouseDown += Zoombox_MouseDown;
+            ClickScale = Zoombox.Scale;
         }
 
         private void Zoombox_MouseDown(object sender, MouseButtonEventArgs e)

+ 3 - 5
PixiEditor/Views/MainWindow.xaml

@@ -169,6 +169,9 @@
                         <i:EventTrigger EventName="MouseUp">
                             <i:InvokeCommandAction Command="{Binding MouseUpCommand}" />
                         </i:EventTrigger>
+                        <i:EventTrigger EventName="MouseDown">
+                            <i:InvokeCommandAction Command="{Binding MouseDownCommand}"/>
+                        </i:EventTrigger>
                     </i:Interaction.Triggers>
                     <i:Interaction.Behaviors>
                         <behaviors:MouseBehaviour RelativeTo="{Binding ElementName=DrawingPanel, Path=Item}"
@@ -179,11 +182,6 @@
                         <Canvas Width="{Binding BitmapManager.ActiveDocument.Width}"
                                 Height="{Binding BitmapManager.ActiveDocument.Height}" VerticalAlignment="Center"
                                 HorizontalAlignment="Center">
-                            <i:Interaction.Triggers>
-                                <i:EventTrigger EventName="MouseDown">
-                                    <i:InvokeCommandAction Command="{Binding MouseDownCommand}" />
-                                </i:EventTrigger>
-                            </i:Interaction.Triggers>
                             <Image Source="/Images/transparentbg.png"
                                    Height="{Binding BitmapManager.ActiveDocument.Height}"
                                    Width="{Binding BitmapManager.ActiveDocument.Width}" Opacity="0.9"

+ 1 - 1
PixiEditorTests/ModelsTests/ControllersTests/BitmapManagerTests.cs

@@ -92,7 +92,7 @@ namespace PixiEditorTests.ModelsTests.ControllersTests
             bitmapManager.MouseController.RecordMouseMovementChange(new Coordinates(1, 1));
             bitmapManager.MouseController.StopRecordingMouseMovementChanges();
 
-            bitmapManager.ExecuteTool(new Coordinates(1, 1));
+            bitmapManager.ExecuteTool(new Coordinates(1, 1), true);
 
             Assert.Equal(Colors.Green, bitmapManager.ActiveLayer.GetPixelWithOffset(1, 1));
         }

+ 16 - 11
PixiEditorTests/ModelsTests/ControllersTests/UndoManagerTests.cs

@@ -10,10 +10,15 @@ namespace PixiEditorTests.ModelsTests.ControllersTests
         public int ExampleProperty { get; set; } = 1;
         public TestPropertyClass TestPropClass { get; set; } = new TestPropertyClass();
 
+        public UndoManagerTests()
+        {
+            PrepareUndoManagerForTest();
+        }
+
         [Fact]
         public void TestSetRoot()
         {
-            PrepareUnoManagerForTest();
+            PrepareUndoManagerForTest();
             UndoManager.SetMainRoot(null);
             UndoManager.SetMainRoot(this);
             Assert.Equal(this, UndoManager.MainRoot);
@@ -22,7 +27,7 @@ namespace PixiEditorTests.ModelsTests.ControllersTests
         [Fact]
         public void TestAddToUndoStack()
         {
-            PrepareUnoManagerForTest();
+            PrepareUndoManagerForTest();
             UndoManager.AddUndoChange(new Change("ExampleProperty", ExampleProperty, ExampleProperty));
             Assert.True(UndoManager.UndoStack.Count == 1);
             Assert.True((int)UndoManager.UndoStack.Peek().OldValue == ExampleProperty);
@@ -31,7 +36,7 @@ namespace PixiEditorTests.ModelsTests.ControllersTests
         [Fact]
         public void TestThatUndoAddsToRedoStack()
         {
-            PrepareUnoManagerForTest();
+            PrepareUndoManagerForTest();
             UndoManager.AddUndoChange(new Change("ExampleProperty", ExampleProperty, ExampleProperty));
             UndoManager.Undo();
             Assert.True(UndoManager.RedoStack.Count == 1);
@@ -40,7 +45,7 @@ namespace PixiEditorTests.ModelsTests.ControllersTests
         [Fact]
         public void TestUndo()
         {
-            PrepareUnoManagerForTest();
+            PrepareUndoManagerForTest();
             UndoManager.AddUndoChange(new Change("ExampleProperty", ExampleProperty, 55));
             ExampleProperty = 55;
             UndoManager.Undo();
@@ -51,7 +56,7 @@ namespace PixiEditorTests.ModelsTests.ControllersTests
         [Fact]
         public void TestThatRedoAddsToUndoStack()
         {
-            PrepareUnoManagerForTest();
+            PrepareUndoManagerForTest();
             UndoManager.AddUndoChange(new Change("ExampleProperty", ExampleProperty, ExampleProperty));
             UndoManager.Undo();
             UndoManager.Redo();
@@ -61,7 +66,7 @@ namespace PixiEditorTests.ModelsTests.ControllersTests
         [Fact]
         public void TestRedo()
         {
-            PrepareUnoManagerForTest();
+            PrepareUndoManagerForTest();
             ExampleProperty = 55;
             UndoManager.AddUndoChange(new Change("ExampleProperty", 1, ExampleProperty));
             UndoManager.Undo();
@@ -72,7 +77,7 @@ namespace PixiEditorTests.ModelsTests.ControllersTests
         [Fact]
         public void TestThatUndoManagerUndoAndRedoWithCustomRootCorrectly()
         {
-            PrepareUnoManagerForTest();
+            PrepareUndoManagerForTest();
             TestPropertyClass testProp = new TestPropertyClass();
             int newVal = 5;
             testProp.IntProperty = newVal;
@@ -91,7 +96,7 @@ namespace PixiEditorTests.ModelsTests.ControllersTests
         [Fact]
         public void TestThatMixedProcessOfUndoAndRedoWorks()
         {
-            PrepareUnoManagerForTest();
+            PrepareUndoManagerForTest();
 
 
             int newVal = 5;
@@ -119,7 +124,7 @@ namespace PixiEditorTests.ModelsTests.ControllersTests
         [Fact]
         public void TestThatProcessBasedUndoAndRedoWorks()
         {
-            PrepareUnoManagerForTest();
+            PrepareUndoManagerForTest();
             int newVal = 5;
             UndoManager.AddUndoChange(new Change(ReverseProcess, new object[]{ExampleProperty}, ReverseProcess, 
                 new object[]{newVal}));
@@ -140,7 +145,7 @@ namespace PixiEditorTests.ModelsTests.ControllersTests
         [Fact]
         public void TestThatNestedPropertyUndoWorks()
         {
-            PrepareUnoManagerForTest();
+            PrepareUndoManagerForTest();
             int newVal = 5;
 
             UndoManager.AddUndoChange(new Change("TestPropClass.IntProperty", TestPropClass.IntProperty, 
@@ -164,7 +169,7 @@ namespace PixiEditorTests.ModelsTests.ControllersTests
             ExampleProperty = (int)args[0];
         }
 
-        private void PrepareUnoManagerForTest()
+        private void PrepareUndoManagerForTest()
         {
             UndoManager.SetMainRoot(this);
             UndoManager.UndoStack.Clear();