Browse Source

A slightly better opacity slider implementation

Equbuxu 3 years ago
parent
commit
642ca02368

+ 15 - 18
src/PixiEditorPrototype/Behaviors/SliderUpdateBehavior.cs

@@ -20,11 +20,13 @@ namespace PixiEditorPrototype.Behaviors
             get => (ICommand)GetValue(DragEndedProperty);
             set => SetValue(DragEndedProperty, value);
         }
-        public static DependencyProperty RegularValueChangedProperty = DependencyProperty.Register(nameof(RegularValueChanged), typeof(ICommand), typeof(SliderUpdateBehavior));
-        public ICommand? RegularValueChanged
+
+        public static DependencyProperty ValueFromSliderProperty =
+            DependencyProperty.Register(nameof(ValueFromSlider), typeof(double), typeof(SliderUpdateBehavior), new(OnSliderValuePropertyChange));
+        public double ValueFromSlider
         {
-            get => (ICommand)GetValue(RegularValueChangedProperty);
-            set => SetValue(RegularValueChangedProperty, value);
+            get => (double)GetValue(ValueFromSliderProperty);
+            set => SetValue(ValueFromSliderProperty, value);
         }
 
         private bool attached = false;
@@ -33,6 +35,9 @@ namespace PixiEditorPrototype.Behaviors
         protected override void OnAttached()
         {
             AssociatedObject.Loaded += AssociatedObject_Loaded;
+            AssociatedObject.Focusable = false;
+
+
             if (AssociatedObject.IsLoaded)
                 AttachEvents();
         }
@@ -53,7 +58,6 @@ namespace PixiEditorPrototype.Behaviors
 
             thumb.DragStarted += Thumb_DragStarted;
             thumb.DragCompleted += Thumb_DragCompleted;
-            AssociatedObject.ValueChanged += Slider_ValueChanged;
         }
 
         protected override void OnDetaching()
@@ -67,23 +71,16 @@ namespace PixiEditorPrototype.Behaviors
 
             thumb.DragStarted -= Thumb_DragStarted;
             thumb.DragCompleted -= Thumb_DragCompleted;
-            AssociatedObject.ValueChanged -= Slider_ValueChanged;
         }
 
-
-
-        private void Slider_ValueChanged(object sender, System.Windows.RoutedPropertyChangedEventArgs<double> e)
+        private static void OnSliderValuePropertyChange(DependencyObject slider, DependencyPropertyChangedEventArgs e)
         {
-            if (dragging)
-            {
-                if (DragValueChanged != null && DragValueChanged.CanExecute(e.NewValue))
-                    DragValueChanged.Execute(e.NewValue);
-                valueChangedWhileDragging = true;
-            }
-            else
+            var obj = (SliderUpdateBehavior)slider;
+            if (obj.dragging)
             {
-                if (RegularValueChanged != null && RegularValueChanged.CanExecute(e.NewValue))
-                    RegularValueChanged.Execute(e.NewValue);
+                if (obj.DragValueChanged != null && obj.DragValueChanged.CanExecute(e.NewValue))
+                    obj.DragValueChanged.Execute(e.NewValue);
+                obj.valueChangedWhileDragging = true;
             }
         }
 

+ 16 - 8
src/PixiEditorPrototype/Models/ActionAccumulator.cs

@@ -8,6 +8,8 @@ namespace PixiEditorPrototype.Models
     internal class ActionAccumulator
     {
         private bool executing = false;
+        private bool applying = false;
+
         private List<IAction> queuedActions = new();
         private DocumentChangeTracker tracker;
         private DocumentUpdater documentUpdater;
@@ -20,24 +22,30 @@ namespace PixiEditorPrototype.Models
 
         public void AddAction(IAction action)
         {
+            if (applying)
+                return;
             queuedActions.Add(action);
             TryExecuteAccumulatedActions();
         }
 
         public async void TryExecuteAccumulatedActions()
         {
-            if (executing)
+            if (executing || queuedActions.Count == 0)
                 return;
             executing = true;
-            var toExecute = queuedActions;
-            queuedActions = new List<IAction>();
-
-            var result = await tracker.ProcessActions(toExecute);
-            foreach (IChangeInfo? info in result)
+            while (queuedActions.Count > 0)
             {
-                documentUpdater.ApplyChangeFromChangeInfo(info);
-            }
+                var toExecute = queuedActions;
+                queuedActions = new List<IAction>();
 
+                var result = await tracker.ProcessActions(toExecute);
+                applying = true;
+                foreach (IChangeInfo? info in result)
+                {
+                    documentUpdater.ApplyChangeFromChangeInfo(info);
+                }
+                applying = false;
+            }
 
             executing = false;
         }

+ 3 - 12
src/PixiEditorPrototype/ViewModels/StructureMemberViewModel.cs

@@ -26,7 +26,6 @@ namespace PixiEditorPrototype.ViewModels
         public float Opacity
         {
             get => member.Opacity;
-            set => SetOpacity(value);
         }
 
         public Guid GuidValue
@@ -41,8 +40,6 @@ namespace PixiEditorPrototype.ViewModels
 
         public RelayCommand EndOpacityUpdateCommand { get; }
 
-        public RelayCommand SetOpacityCommand { get; }
-
         public void RaisePropertyChanged(string name)
         {
             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
@@ -56,7 +53,6 @@ namespace PixiEditorPrototype.ViewModels
             MoveDownCommand = new(_ => Document.StructureHelper.MoveStructureMember(GuidValue, false));
             UpdateOpacityCommand = new(UpdateOpacity);
             EndOpacityUpdateCommand = new(EndOpacityUpdate);
-            SetOpacityCommand = new((value) => { if (value != null) SetOpacity((float)(double)value); });
         }
 
         private void EndOpacityUpdate(object? opacity)
@@ -66,14 +62,9 @@ namespace PixiEditorPrototype.ViewModels
 
         private void UpdateOpacity(object? opacity)
         {
-            if (opacity != null)
-                Document.ActionAccumulator.AddAction(new OpacityChange_Action(GuidValue, (float)(double)opacity));
-        }
-
-        private void SetOpacity(float value)
-        {
-            //Document.ActionAccumulator.AddAction(new OpacityChange_Action(GuidValue, value));
-            //Document.ActionAccumulator.AddAction(new EndOpacityChange_Action());
+            if (opacity == null || opacity is not double value)
+                throw new Exception("Can't update opacity");
+            Document.ActionAccumulator.AddAction(new OpacityChange_Action(GuidValue, (float)value));
         }
     }
 }

+ 2 - 2
src/PixiEditorPrototype/Views/DocumentView.xaml

@@ -20,13 +20,13 @@
                     <Button Margin="5" Command="{Binding DeleteStructureMemberCommand}" Width="80">Delete</Button>
                 </StackPanel>
                 <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" HorizontalAlignment="Center">
-                    <Slider Width="100" Minimum="0" Maximum="1" SmallChange="0.01" LargeChange="0.1" IsSnapToTickEnabled="True" TickFrequency="0.01" 
+                    <Slider Width="100" Minimum="0" Maximum="1" SmallChange="0.01" LargeChange="0.1" IsSnapToTickEnabled="True" TickFrequency="0.01" x:Name="opacitySlider"
                             Value="{Binding SelectedStructureMember.Opacity, Mode=OneWay}">
                         <i:Interaction.Behaviors>
                             <behaviors:SliderUpdateBehavior
                                 DragValueChanged="{Binding SelectedStructureMember.UpdateOpacityCommand}"
                                 DragEnded="{Binding SelectedStructureMember.EndOpacityUpdateCommand}"
-                                RegularValueChanged="{Binding SelectedStructureMember.SetOpacityCommand}"/>
+                                ValueFromSlider="{Binding ElementName=opacitySlider, Path=Value}"/>
                         </i:Interaction.Behaviors>
                     </Slider>
                     <TextBlock Text="{Binding SelectedStructureMember.Opacity, StringFormat=N2}" TextAlignment="Center" d:Text="1.00" Width="30"></TextBlock>