فهرست منبع

Fixed undo spamming on blackboard change

Krzysztof Krysiński 2 روز پیش
والد
کامیت
2cb1adebc3

+ 23 - 2
src/PixiEditor.ChangeableDocument/Changes/NodeGraph/Blackboard/SetBlackboardVariable_Change.cs

@@ -6,7 +6,7 @@ using PixiEditor.ChangeableDocument.ChangeInfos.NodeGraph.Blackboard;
 
 namespace PixiEditor.ChangeableDocument.Changes.NodeGraph.Blackboard;
 
-internal class SetBlackboardVariable_Change : Change
+internal class SetBlackboardVariable_Change : InterruptableUpdateableChange
 {
     private string variable;
     private object value;
@@ -19,7 +19,7 @@ internal class SetBlackboardVariable_Change : Change
     private string unit;
     private bool isExposed;
 
-    [GenerateMakeChangeAction]
+    [GenerateUpdateableChangeActions]
     public SetBlackboardVariable_Change(string variable, object value, double min, double max, string unit, bool isExposed)
     {
         this.variable = variable;
@@ -30,6 +30,17 @@ internal class SetBlackboardVariable_Change : Change
         this.isExposed = isExposed;
     }
 
+    [UpdateChangeMethod]
+    public void Update(string variable, object value, double min, double max, string unit, bool isExposed)
+    {
+        this.variable = variable;
+        this.value = value;
+        this.min = min;
+        this.max = max;
+        this.unit = unit;
+        this.isExposed = isExposed;
+    }
+
     public override bool InitializeAndValidate(Document target)
     {
         if (variable == null)
@@ -80,6 +91,11 @@ internal class SetBlackboardVariable_Change : Change
         out bool ignoreInUndo)
     {
         ignoreInUndo = false;
+        return Apply(target);
+    }
+
+    private OneOf<None, IChangeInfo, List<IChangeInfo>> Apply(Document target)
+    {
         if (target.NodeGraph.Blackboard.GetVariable(variable) == null)
         {
             Type type = value.GetType();
@@ -95,6 +111,11 @@ internal class SetBlackboardVariable_Change : Change
         return new List<IChangeInfo>() { new BlackboardVariable_ChangeInfo(variable, oldVar.Type, value, oldVar.Min ?? double.MinValue, oldVar.Max ?? double.MaxValue, oldVar.Unit), new BlackboardVariableExposed_ChangeInfo(variable, isExposed) };
     }
 
+    public override OneOf<None, IChangeInfo, List<IChangeInfo>> ApplyTemporarily(Document target)
+    {
+        return Apply(target);
+    }
+
     public override OneOf<None, IChangeInfo, List<IChangeInfo>> Revert(Document target)
     {
         if (!existsInBlackboard)

+ 1 - 0
src/PixiEditor.UI.Common/Controls/SizeInput.axaml

@@ -40,6 +40,7 @@
                      FocusNext="{Binding FocusNext, ElementName=uc}"
                      SelectOnMouseClick="{Binding BehaveLikeSmallEmbeddedField, ElementName=uc}"
                      ConfirmOnEnter="{Binding BehaveLikeSmallEmbeddedField, ElementName=uc}"
+                     DraggingGrabber="{Binding DraggingGrabber, ElementName=uc, Mode=TwoWay}"
                      Width="53"/>
             <Grid Grid.Column="1" Background="{Binding BorderBrush, ElementName=border}"
                   d:Background="{DynamicResource ThemeAccentBrush}"/>

+ 8 - 0
src/PixiEditor.UI.Common/Controls/SizeInput.axaml.cs

@@ -9,6 +9,8 @@ namespace PixiEditor.UI.Common.Controls;
 /// </summary>
 public partial class SizeInput : UserControl
 {
+    public static readonly StyledProperty<bool> DraggingGrabberProperty = AvaloniaProperty.Register<SizeInput, bool>("DraggingGrabber");
+
     public static readonly StyledProperty<double> SizeProperty =
         AvaloniaProperty.Register<SizeInput, double>(nameof(Size), defaultValue: 1);
 
@@ -115,6 +117,12 @@ public partial class SizeInput : UserControl
         set => SetValue(UnitProperty, value);
     }
 
+    public bool DraggingGrabber
+    {
+        get { return (bool)GetValue(DraggingGrabberProperty); }
+        set { SetValue(DraggingGrabberProperty, value); }
+    }
+
     private void Border_MouseWheel(object? sender, PointerWheelEventArgs e)
     {
         int step = (int)e.Delta.Y / 100;

+ 16 - 1
src/PixiEditor/ViewModels/Document/Blackboard/VariableViewModel.cs

@@ -84,8 +84,23 @@ internal class VariableViewModel : ViewModelBase, IVariableHandler
             if (suppressValueChange)
                 return;
 
+            if (SettingView.MergeChanges)
+            {
+                internals.ActionAccumulator.AddActions(
+                    new SetBlackboardVariable_Action(Name, AdjustValueForBlackboard(SettingView.Value), min, max, unit, IsExposedBindable));
+            }
+            else
+            {
+                internals.ActionAccumulator.AddFinishedActions(
+                    new SetBlackboardVariable_Action(Name, AdjustValueForBlackboard(SettingView.Value), min, max, unit, IsExposedBindable),
+                    new EndSetBlackboardVariable_Action());
+            }
+        };
+
+        SettingView.MergeChangesEnded += () =>
+        {
             internals.ActionAccumulator.AddFinishedActions(
-                new SetBlackboardVariable_Action(Name, AdjustValueForBlackboard(SettingView.Value), min, max, unit, IsExposedBindable));
+                new EndSetBlackboardVariable_Action());
         };
 
         RemoveCommand = new RelayCommand(() =>

+ 16 - 0
src/PixiEditor/ViewModels/Tools/ToolSettings/Settings/Setting.cs

@@ -58,6 +58,8 @@ internal abstract class Setting : ObservableObject
     protected bool hasOverwrittenValue;
     protected bool hasOverwrittenExposed;
 
+    private bool mergeChanges;
+
     protected Setting(string name)
     {
         Name = name;
@@ -126,6 +128,20 @@ internal abstract class Setting : ObservableObject
         set => toolsetValues[currentToolset] = value;
     }
 
+    public bool MergeChanges
+    {
+        get => mergeChanges;
+        set
+        {
+            if (SetProperty(ref mergeChanges, value) && !value)
+            {
+                MergeChangesEnded?.Invoke();
+            }
+        }
+    }
+
+    public event Action MergeChangesEnded;
+
     public abstract Type GetSettingType();
 
     public void SetOverwriteValue(object value)

+ 1 - 0
src/PixiEditor/Views/Tools/ToolSettings/Settings/FloatSettingView.axaml

@@ -14,6 +14,7 @@
                        Value="{Binding Value, Mode=TwoWay}"
                        Min="{Binding Min}"
                        Max="{Binding Max}"
+                       DraggingGrabber="{Binding MergeChanges, Mode=OneWayToSource}"
                        Decimals="{Binding DecimalPlaces}"
                        Margin="0,0,0,0" 
                        FocusNext="False"

+ 1 - 0
src/PixiEditor/Views/Tools/ToolSettings/Settings/PercentSettingView.axaml

@@ -15,6 +15,7 @@
                        Size="{Binding Value, Mode=TwoWay, Converter={converters:IntPercentConverter}}"
                        MinSize="{Binding Min, Converter={converters:IntPercentConverter}}"
                        MaxSize="{Binding Max, Converter={converters:IntPercentConverter}}"
+                       DraggingGrabber="{Binding MergeChanges, Mode=OneWayToSource}"
                        Unit="%"
                        Margin="0,0,0,0" 
                         />

+ 1 - 0
src/PixiEditor/Views/Tools/ToolSettings/Settings/SizeSettingView.axaml

@@ -17,5 +17,6 @@
                      Decimals="{Binding DecimalPlaces}"
                      Unit="{Binding Unit}"
                      IsEnabled="{Binding IsEnabled}" FocusNext="False"
+                     DraggingGrabber="{Binding MergeChanges, Mode=OneWayToSource}"
                      Size="{Binding Value, Mode=TwoWay}"/>
 </UserControl>