Browse Source

Implemented lasso tool

CPKreuz 2 years ago
parent
commit
74b4bef941

+ 10 - 0
src/PixiEditor/Helpers/Converters/IsSelectionToolConverter.cs

@@ -0,0 +1,10 @@
+using System.Globalization;
+using PixiEditor.ViewModels.SubViewModels.Tools.Tools;
+
+namespace PixiEditor.Helpers.Converters;
+
+internal class IsSelectionToolConverter : SingleInstanceConverter<IsSelectionToolConverter>
+{
+    public override object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
+        value is SelectToolViewModel or LassoToolViewModel or MagicWandToolViewModel;
+}

+ 1 - 0
src/PixiEditor/Helpers/Extensions/ServiceCollectionHelpers.cs

@@ -51,6 +51,7 @@ internal static class ServiceCollectionHelpers
         .AddSingleton<ToolViewModel, SelectToolViewModel>()
         .AddSingleton<ToolViewModel, SelectToolViewModel>()
         .AddSingleton<ToolViewModel, MagicWandToolViewModel>()
         .AddSingleton<ToolViewModel, MagicWandToolViewModel>()
         .AddSingleton<ToolViewModel, FloodFillToolViewModel>()
         .AddSingleton<ToolViewModel, FloodFillToolViewModel>()
+        .AddSingleton<ToolViewModel, LassoToolViewModel>()
         .AddSingleton<ToolViewModel, LineToolViewModel>()
         .AddSingleton<ToolViewModel, LineToolViewModel>()
         .AddSingleton<ToolViewModel, EllipseToolViewModel>()
         .AddSingleton<ToolViewModel, EllipseToolViewModel>()
         .AddSingleton<ToolViewModel, RectangleToolViewModel>()
         .AddSingleton<ToolViewModel, RectangleToolViewModel>()

+ 2 - 0
src/PixiEditor/Models/DocumentModels/Public/DocumentToolsModule.cs

@@ -51,4 +51,6 @@ internal class DocumentToolsModule
     public void UseBrightnessTool() => Internals.ChangeController.TryStartExecutor<BrightnessToolExecutor>();
     public void UseBrightnessTool() => Internals.ChangeController.TryStartExecutor<BrightnessToolExecutor>();
 
 
     public void UseFloodFillTool() => Internals.ChangeController.TryStartExecutor<FloodFillToolExecutor>();
     public void UseFloodFillTool() => Internals.ChangeController.TryStartExecutor<FloodFillToolExecutor>();
+
+    public void UseLassoTool() => Internals.ChangeController.TryStartExecutor<LassoToolExecuter>();
 }
 }

+ 44 - 0
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/LassoToolExecuter.cs

@@ -0,0 +1,44 @@
+using PixiEditor.ChangeableDocument.Enums;
+using PixiEditor.DrawingApi.Core.Numerics;
+using PixiEditor.Models.Enums;
+using PixiEditor.ViewModels.SubViewModels.Tools.Tools;
+using PixiEditor.ViewModels.SubViewModels.Tools.ToolSettings.Toolbars;
+
+namespace PixiEditor.Models.DocumentModels.UpdateableChangeExecutors;
+
+internal sealed class LassoToolExecuter : UpdateableChangeExecutor
+{
+    private SelectionMode? mode;
+    
+    public override ExecutionState Start()
+    {
+        mode = ((LassoToolbar)ViewModelMain.Current?.ToolsSubViewModel.GetTool<LassoToolViewModel>()?.Toolbar)?.SelectMode;
+
+        if (mode == null)
+            return ExecutionState.Error;
+        
+        AddStartAction(controller!.LastPixelPosition);
+
+        return ExecutionState.Success;
+    }
+
+    public override void OnPixelPositionChange(VecI pos) => AddStartAction(pos);
+
+    public override void OnLeftMouseButtonUp()
+    {
+        internals!.ActionAccumulator.AddActions(new EndSelectLasso_Action());
+        onEnded!(this);
+    }
+
+    public override void ForceStop()
+    {
+        OnLeftMouseButtonUp();
+    }
+
+    private void AddStartAction(VecI pos)
+    {
+        var action = new SelectLasso_Action(pos, mode!.Value);
+        
+        internals!.ActionAccumulator.AddActions(action);
+    }
+}

+ 14 - 0
src/PixiEditor/ViewModels/SubViewModels/Tools/ToolSettings/Toolbars/LassoToolbar.cs

@@ -0,0 +1,14 @@
+using PixiEditor.ChangeableDocument.Enums;
+using PixiEditor.ViewModels.SubViewModels.Tools.ToolSettings.Settings;
+
+namespace PixiEditor.ViewModels.SubViewModels.Tools.ToolSettings.Toolbars;
+
+internal class LassoToolbar : Toolbar
+{
+    public SelectionMode SelectMode => GetSetting<EnumSetting<SelectionMode>>(nameof(SelectMode)).Value;
+    
+    public LassoToolbar()
+    {
+        Settings.Add(new EnumSetting<SelectionMode>(nameof(SelectMode), "Selection type"));
+    }
+}

+ 26 - 0
src/PixiEditor/ViewModels/SubViewModels/Tools/Tools/LassoToolViewModel.cs

@@ -0,0 +1,26 @@
+using System.Windows.Input;
+using PixiEditor.DrawingApi.Core.Numerics;
+using PixiEditor.Models.Commands.Attributes.Commands;
+using PixiEditor.ViewModels.SubViewModels.Tools.ToolSettings.Toolbars;
+using PixiEditor.Views.UserControls.BrushShapeOverlay;
+
+namespace PixiEditor.ViewModels.SubViewModels.Tools.Tools;
+
+[Command.ToolAttribute(Key = Key.L)]
+internal class LassoToolViewModel : ToolViewModel
+{
+    public override string Tooltip => $"Lasso. ({Shortcut})";
+    
+    public override BrushShape BrushShape => BrushShape.Pixel;
+
+    public LassoToolViewModel()
+    {
+        Toolbar = new LassoToolbar();
+        ActionDisplay = "Click and move to select pixels inside of lasso.";
+    }
+
+    public override void OnLeftMouseButtonDown(VecD pos)
+    {
+        ViewModelMain.Current?.DocumentManagerSubViewModel.ActiveDocument?.Tools.UseLassoTool();
+    }
+}

+ 1 - 4
src/PixiEditor/Views/UserControls/Viewport.xaml

@@ -124,9 +124,6 @@
                     </ImageBrush>
                     </ImageBrush>
                 </Border.Background>
                 </Border.Background>
                 <Grid>
                 <Grid>
-                    <Grid.Resources>
-                        <converters:IsSpecifiedTypeConverter x:Key="IsSelectToolConverter" SpecifiedType="{x:Type tools:SelectToolViewModel}"/>
-                    </Grid.Resources>
                     <Canvas>
                     <Canvas>
                         <Image
                         <Image
                             Width="{Binding Document.ReferenceBitmap.Width}"
                             Width="{Binding Document.ReferenceBitmap.Width}"
@@ -159,7 +156,7 @@
                         DragEndCommand="{cmds:Command PixiEditor.Document.EndDragSymmetry, UseProvided=True}" 
                         DragEndCommand="{cmds:Command PixiEditor.Document.EndDragSymmetry, UseProvided=True}" 
                         DragStartCommand="{cmds:Command PixiEditor.Document.StartDragSymmetry, UseProvided=True}" />
                         DragStartCommand="{cmds:Command PixiEditor.Document.StartDragSymmetry, UseProvided=True}" />
                     <uc:SelectionOverlay
                     <uc:SelectionOverlay
-                        ShowFill="{Binding ToolsSubViewModel.ActiveTool, Source={vm:MainVM}, Converter={StaticResource IsSelectToolConverter}}"
+                        ShowFill="{Binding ToolsSubViewModel.ActiveTool, Source={vm:MainVM}, Converter={converters:IsSelectionToolConverter}}"
                         Path="{Binding Document.SelectionPathBindable}"
                         Path="{Binding Document.SelectionPathBindable}"
                         ZoomboxScale="{Binding Zoombox.Scale}" />
                         ZoomboxScale="{Binding Zoombox.Scale}" />
                     <brush:BrushShapeOverlay
                     <brush:BrushShapeOverlay