Преглед на файлове

Added square brush to brightness tool

Krzysztof Krysiński преди 5 месеца
родител
ревизия
99eae431ac

+ 53 - 10
src/PixiEditor.ChangeableDocument/Changes/Drawing/ChangeBrightness_UpdateableChange.cs

@@ -16,13 +16,16 @@ internal class ChangeBrightness_UpdateableChange : UpdateableChange
     private readonly bool repeat;
     private int frame;
     private int lastAppliedPointIndex = -1;
+    private bool squareBrush;
 
     private List<VecI> ellipseLines;
+    private RectI squareRect;
 
     private CommittedChunkStorage? savedChunks;
 
     [GenerateUpdateableChangeActions]
     public ChangeBrightness_UpdateableChange(Guid layerGuid, VecI pos, float correctionFactor, int strokeWidth,
+        bool square,
         bool repeat, int frame)
     {
         this.layerGuid = layerGuid;
@@ -30,11 +33,16 @@ internal class ChangeBrightness_UpdateableChange : UpdateableChange
         this.strokeWidth = strokeWidth;
         this.repeat = repeat;
         this.frame = frame;
+        this.squareBrush = square;
         positions.Add(pos);
 
-        ellipseLines =
-            EllipseHelper.SplitEllipseIntoLines(
-                (EllipseHelper.GenerateEllipseFromRect(new RectI(0, 0, strokeWidth, strokeWidth), 0)));
+        squareRect = new RectI(0, 0, strokeWidth, strokeWidth);
+        if (!square)
+        {
+            ellipseLines =
+                EllipseHelper.SplitEllipseIntoLines(
+                    (EllipseHelper.GenerateEllipseFromRect(squareRect, 0)));
+        }
     }
 
     [UpdateChangeMethod]
@@ -67,8 +75,16 @@ internal class ChangeBrightness_UpdateableChange : UpdateableChange
         for (int i = Math.Max(lastAppliedPointIndex, 0); i < positions.Count; i++)
         {
             VecI pos = positions[i];
-            ChangeBrightness(ellipseLines, strokeWidth, pos + new VecI(-strokeWidth / 2), correctionFactor, repeat,
-                layerImage);
+            if (squareBrush)
+            {
+                ChangeBrightness(squareRect, pos + new VecI(-strokeWidth / 2), correctionFactor, repeat,
+                    layerImage);
+            }
+            else
+            {
+                ChangeBrightness(ellipseLines, pos + new VecI(-strokeWidth / 2), correctionFactor, repeat,
+                    layerImage);
+            }
         }
 
         var affected = layerImage.FindAffectedArea(queueLength);
@@ -79,11 +95,9 @@ internal class ChangeBrightness_UpdateableChange : UpdateableChange
     }
 
     private static void ChangeBrightness(
-        List<VecI> circleLines, int circleDiameter, VecI offset, float correctionFactor, bool repeat,
+        List<VecI> circleLines, VecI offset, float correctionFactor, bool repeat,
         ChunkyImage layerImage)
     {
-        // TODO: Circle diameter is unused, check if it should be used
-
         for (var i = 0; i < circleLines.Count - 1; i++)
         {
             VecI left = circleLines[i];
@@ -105,6 +119,27 @@ internal class ChangeBrightness_UpdateableChange : UpdateableChange
         }
     }
 
+    private static void ChangeBrightness(
+        RectI square, VecI offset, float correctionFactor, bool repeat,
+        ChunkyImage layerImage)
+    {
+        for (int i = square.X; i < square.X + square.Width; i++)
+        {
+            for (int j = square.Y; j < square.Y + square.Height; j++)
+            {
+                layerImage.EnqueueDrawPixel(
+                    new VecI(i, j) + offset,
+                    (commitedColor, upToDateColor) =>
+                    {
+                        Color newColor = ColorHelper.ChangeColorBrightness(repeat ? upToDateColor : commitedColor,
+                            correctionFactor);
+                        return ColorHelper.ChangeColorBrightness(newColor, correctionFactor);
+                    },
+                    BlendMode.Src);
+            }
+        }
+    }
+
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Apply(Document target, bool firstApply,
         out bool ignoreInUndo)
     {
@@ -121,8 +156,16 @@ internal class ChangeBrightness_UpdateableChange : UpdateableChange
             DrawingChangeHelper.ApplyClipsSymmetriesEtc(target, layerImage, layerGuid, false);
             foreach (VecI pos in positions)
             {
-                ChangeBrightness(ellipseLines, strokeWidth, pos + new VecI(-strokeWidth / 2), correctionFactor, repeat,
-                    layerImage);
+                if (squareBrush)
+                {
+                    ChangeBrightness(squareRect, pos + new VecI(-strokeWidth / 2), correctionFactor, repeat,
+                        layerImage);
+                }
+                else
+                {
+                    ChangeBrightness(ellipseLines, pos + new VecI(-strokeWidth / 2), correctionFactor, repeat,
+                        layerImage);
+                }
             }
         }
 

+ 4 - 4
src/PixiEditor/Data/Configs/ToolSetsConfig.json

@@ -10,7 +10,7 @@
         "Settings": {
           "ExposePixelPerfectEnabled": true,
           "Spacing": 0,
-          "ExposePenShape": true
+          "ExposePaintShape": true
         }
       },
       "Select",
@@ -32,7 +32,7 @@
         "ToolName": "Eraser",
         "Settings": {
           "Spacing": 0,
-          "ExposePenShape": true,
+          "ExposePaintShape": true
         }
       },
       "ColorPicker",
@@ -53,7 +53,7 @@
           "ExposeHardness": true,
           "ExposeSpacing": true,
           "BrushShapeSetting": "CircleSmooth",
-          "PenShape": "Circle"
+          "PaintShape": "Circle"
         }
       },
       "Select",
@@ -106,7 +106,7 @@
           "ExposeHardness": true,
           "ExposeSpacing": true,
           "BrushShapeSetting": "CircleSmooth",
-          "PenShape": "Circle"
+          "PaintShape": "Circle"
         }
       },
       "ColorPicker",

+ 1 - 1
src/PixiEditor/Data/Localization/Languages/en.json

@@ -998,5 +998,5 @@
   "DOWNLOAD_UPDATE": "Download",
   "DOWNLOADING_UPDATE": "Downloading update...",
   "CHECKING_FOR_UPDATES": "Checking for updates...",
-  "PEN_SHAPE_SETTING": "Brush shape"
+  "PAINT_SHAPE_SETTING": "Brush shape"
 }

+ 5 - 2
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/BrightnessToolExecutor.cs

@@ -15,6 +15,7 @@ internal class BrightnessToolExecutor : UpdateableChangeExecutor
     private bool repeat;
     private float correctionFactor;
     private int toolSize;
+    private bool squareBrush;
 
     public override ExecutionState Start()
     {
@@ -30,7 +31,9 @@ internal class BrightnessToolExecutor : UpdateableChangeExecutor
         toolSize = (int)toolbar.ToolSize;
         correctionFactor = tool.Darken || tool.UsedWith == MouseButton.Right ? -tool.CorrectionFactor : tool.CorrectionFactor;
 
-        ChangeBrightness_Action action = new(guidValue, controller!.LastPixelPosition, correctionFactor, toolSize, repeat, document.AnimationHandler.ActiveFrameBindable);
+        squareBrush = tool.BrushShape == PaintBrushShape.Square;
+
+        ChangeBrightness_Action action = new(guidValue, controller!.LastPixelPosition, correctionFactor, toolSize, squareBrush, repeat, document.AnimationHandler.ActiveFrameBindable);
         internals!.ActionAccumulator.AddActions(action);
 
         return ExecutionState.Success;
@@ -38,7 +41,7 @@ internal class BrightnessToolExecutor : UpdateableChangeExecutor
 
     public override void OnPixelPositionChange(VecI pos)
     {
-        ChangeBrightness_Action action = new(guidValue, pos, correctionFactor, toolSize, repeat, document!.AnimationHandler.ActiveFrameBindable);
+        ChangeBrightness_Action action = new(guidValue, pos, correctionFactor, toolSize, squareBrush, repeat, document!.AnimationHandler.ActiveFrameBindable);
         internals!.ActionAccumulator.AddActions(action);
     }
 

+ 1 - 1
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/EraserToolExecutor.cs

@@ -14,7 +14,7 @@ namespace PixiEditor.Models.DocumentModels.UpdateableChangeExecutors;
 
 internal class EraserToolExecutor : UpdateableChangeExecutor
 {
-    public bool SquareBrush => penToolbar.PenShape == PenBrushShape.Square;
+    public bool SquareBrush => penToolbar.PaintShape == PaintBrushShape.Square;
     private Guid guidValue;
     private Color color;
     private double toolSize;

+ 1 - 1
src/PixiEditor/Models/DocumentModels/UpdateableChangeExecutors/PenToolExecutor.cs

@@ -15,7 +15,7 @@ internal class PenToolExecutor : UpdateableChangeExecutor
     private Guid guidValue;
     private Color color;
     public double ToolSize => penToolbar.ToolSize;
-    public bool SquareBrush => penToolbar.PenShape == PenBrushShape.Square;
+    public bool SquareBrush => penToolbar.PaintShape == PaintBrushShape.Square;
 
     private bool drawOnMask;
     private bool pixelPerfect;

+ 1 - 1
src/PixiEditor/Models/Handlers/Toolbars/IPenToolbar.cs

@@ -7,5 +7,5 @@ internal interface IPenToolbar : IToolbar, IToolSizeToolbar
     public bool AntiAliasing { get; set; }
     public float Hardness { get; set; }
     public float Spacing { get; set; }
-    public PenBrushShape PenShape { get; set; }
+    public PaintBrushShape PaintShape { get; set; }
 }

+ 1 - 1
src/PixiEditor/Models/Handlers/Toolbars/PenBrushShape.cs → src/PixiEditor/Models/Handlers/Toolbars/PaintBrushShape.cs

@@ -1,6 +1,6 @@
 namespace PixiEditor.Models.Handlers.Toolbars;
 
-public enum PenBrushShape
+public enum PaintBrushShape
 {
     Circle,
     Square,

+ 1 - 0
src/PixiEditor/Models/Handlers/Tools/IBrightnessToolHandler.cs

@@ -10,4 +10,5 @@ internal interface IBrightnessToolHandler : IToolHandler
     public bool Darken { get; }
     public MouseButton UsedWith { get; }
     public float CorrectionFactor { get; }
+    public PaintBrushShape BrushShape { get; }
 }

+ 4 - 4
src/PixiEditor/ViewModels/Tools/ToolSettings/Toolbars/PenToolbar.cs

@@ -30,10 +30,10 @@ internal class PenToolbar : Toolbar, IPenToolbar
         set => GetSetting<SizeSettingViewModel>(nameof(ToolSize)).Value = value;
     }
 
-    public PenBrushShape PenShape
+    public PaintBrushShape PaintShape
     {
-        get => GetSetting<EnumSettingViewModel<PenBrushShape>>(nameof(PenShape)).Value;
-        set => GetSetting<EnumSettingViewModel<PenBrushShape>>(nameof(PenShape)).Value = value;
+        get => GetSetting<EnumSettingViewModel<PaintBrushShape>>(nameof(PaintShape)).Value;
+        set => GetSetting<EnumSettingViewModel<PaintBrushShape>>(nameof(PaintShape)).Value = value;
     }
 
     public override void OnLoadedSettings()
@@ -49,6 +49,6 @@ internal class PenToolbar : Toolbar, IPenToolbar
         var setting = new SizeSettingViewModel(nameof(ToolSize), "TOOL_SIZE_LABEL");
         setting.ValueChanged += (_, _) => OnPropertyChanged(nameof(ToolSize));
         AddSetting(setting);
-        AddSetting(new EnumSettingViewModel<PenBrushShape>(nameof(PenShape), "PEN_SHAPE_SETTING") { IsExposed = false });
+        AddSetting(new EnumSettingViewModel<PaintBrushShape>(nameof(PaintShape), "PAINT_SHAPE_SETTING") { IsExposed = false });
     }
 }

+ 18 - 1
src/PixiEditor/ViewModels/Tools/Tools/BrightnessToolViewModel.cs

@@ -7,6 +7,7 @@ using PixiEditor.Models.Handlers;
 using PixiEditor.Models.Handlers.Tools;
 using PixiEditor.Models.Tools;
 using Drawie.Numerics;
+using PixiEditor.Models.Handlers.Toolbars;
 using PixiEditor.UI.Common.Fonts;
 using PixiEditor.ViewModels.Tools.ToolSettings.Toolbars;
 using PixiEditor.Views.Overlays.BrushShapeOverlay;
@@ -29,7 +30,7 @@ internal class BrightnessToolViewModel : ToolViewModel, IBrightnessToolHandler
     public override bool IsErasable => true;
     public override LocalizedString Tooltip => new LocalizedString("BRIGHTNESS_TOOL_TOOLTIP", Shortcut);
 
-    public override BrushShape FinalBrushShape => BrushShape.CirclePixelated;
+    public override BrushShape FinalBrushShape => BrushShape == PaintBrushShape.Square ? Views.Overlays.BrushShapeOverlay.BrushShape.Square : Views.Overlays.BrushShapeOverlay.BrushShape.CirclePixelated;
 
     public override string DefaultIcon => PixiPerfectIcons.Sun;
 
@@ -51,6 +52,17 @@ internal class BrightnessToolViewModel : ToolViewModel, IBrightnessToolHandler
 
     [Settings.Enum("MODE_LABEL")]
     public BrightnessMode BrightnessMode => GetValue<BrightnessMode>();
+
+    [Settings.Enum("PAINT_SHAPE_SETTING", PaintBrushShape.Circle, Notify = nameof(BrushShapeChanged))]
+    public PaintBrushShape BrushShape
+    {
+        get => GetValue<PaintBrushShape>();
+        set
+        {
+            SetValue(value);
+            OnPropertyChanged(nameof(FinalBrushShape));
+        }
+    }
     
     public bool Darken { get; private set; } = false;
 
@@ -76,4 +88,9 @@ internal class BrightnessToolViewModel : ToolViewModel, IBrightnessToolHandler
     {
         ViewModelMain.Current?.DocumentManagerSubViewModel.ActiveDocument?.Tools.UseBrightnessTool();
     }
+
+    private void BrushShapeChanged()
+    {
+        OnPropertyChanged(nameof(FinalBrushShape));
+    }
 }

+ 3 - 3
src/PixiEditor/ViewModels/Tools/Tools/EraserToolViewModel.cs

@@ -27,7 +27,7 @@ internal class EraserToolViewModel : ToolViewModel, IEraserToolHandler
     public override bool IsErasable => true;
 
     public override string ToolNameLocalizationKey => "ERASER_TOOL";
-    public override BrushShape FinalBrushShape => PenShape == PenBrushShape.Square ? BrushShape.Square : BrushShapeSetting;
+    public override BrushShape FinalBrushShape => PaintShape == PaintBrushShape.Square ? BrushShape.Square : BrushShapeSetting;
     public override Type[]? SupportedLayerTypes { get; } = { typeof(IRasterLayerHandler) };
 
     public override string DefaultIcon => PixiPerfectIcons.Eraser;
@@ -41,9 +41,9 @@ internal class EraserToolViewModel : ToolViewModel, IEraserToolHandler
     public BrushShape BrushShapeSetting => GetValue<BrushShape>();
 
     [Settings.Inherited(Notify = nameof(PenShapeChanged))]
-    public PenBrushShape PenShape
+    public PaintBrushShape PaintShape
     {
-        get => GetValue<PenBrushShape>();
+        get => GetValue<PaintBrushShape>();
         set
         {
             SetValue(value);

+ 3 - 3
src/PixiEditor/ViewModels/Tools/Tools/PenToolViewModel.cs

@@ -23,7 +23,7 @@ namespace PixiEditor.ViewModels.Tools.Tools
         public override string ToolNameLocalizationKey => "PEN_TOOL";
 
         public override BrushShape FinalBrushShape =>
-            PenShape == PenBrushShape.Square ? BrushShape.Square : BrushShapeSetting;
+            PaintShape == PaintBrushShape.Square ? BrushShape.Square : BrushShapeSetting;
         
         public override Type[]? SupportedLayerTypes { get; } = { typeof(IRasterLayerHandler) };
 
@@ -58,7 +58,7 @@ namespace PixiEditor.ViewModels.Tools.Tools
         }
 
         [Settings.Inherited(Notify = nameof(PenShapeChanged))]
-        public PenBrushShape PenShape => GetValue<PenBrushShape>();
+        public PaintBrushShape PaintShape => GetValue<PaintBrushShape>();
 
         public override string DefaultIcon => PixiPerfectIcons.Pen;
 
@@ -155,7 +155,7 @@ namespace PixiEditor.ViewModels.Tools.Tools
 
         private void PenShapeChanged()
         {
-            OnPropertyChanged(nameof(PenShape));
+            OnPropertyChanged(nameof(PaintShape));
             OnPropertyChanged(nameof(FinalBrushShape));
         }
     }