From 75c10992a9071f6cd8b1b9e179aa77f5655bfa10 Mon Sep 17 00:00:00 2001 From: Splitwirez Date: Sat, 4 Jul 2020 11:51:50 -0400 Subject: [PATCH 1/4] Added ToggleSwitch dragging --- src/Avalonia.Controls/ToggleSwitch.cs | 97 ++++++++++++++++++++ src/Avalonia.Themes.Fluent/ToggleSwitch.xaml | 12 +-- 2 files changed, 103 insertions(+), 6 deletions(-) diff --git a/src/Avalonia.Controls/ToggleSwitch.cs b/src/Avalonia.Controls/ToggleSwitch.cs index 4b42c574cf..15e22d4d36 100644 --- a/src/Avalonia.Controls/ToggleSwitch.cs +++ b/src/Avalonia.Controls/ToggleSwitch.cs @@ -14,6 +14,17 @@ namespace Avalonia.Controls { OffContentProperty.Changed.AddClassHandler((x, e) => x.OffContentChanged(e)); OnContentProperty.Changed.AddClassHandler((x, e) => x.OnContentChanged(e)); + IsCheckedProperty.Changed.AddClassHandler((x, e) => + { + if ((e.NewValue != null) && (e.NewValue is bool val)) + x.UpdateKnobPos(val); + }); + + BoundsProperty.Changed.AddClassHandler((x, e) => + { + if (x.IsChecked != null) + x.UpdateKnobPos(x.IsChecked.Value); + }); } /// @@ -131,6 +142,92 @@ namespace Avalonia.Controls return result; } + + + Panel _knobsPanel; + Panel _switchKnob; + bool _knobsPanelPressed = false; + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) + { + base.OnApplyTemplate(e); + + _switchKnob = e.NameScope.Find("SwitchKnob"); + _knobsPanel = e.NameScope.Find("MovingKnobs"); + + _knobsPanel.PointerPressed += KnobsPanel_PointerPressed; + _knobsPanel.PointerReleased += KnobsPanel_PointerReleased; + _knobsPanel.PointerMoved += KnobsPanel_PointerMoved; + + if (IsChecked.HasValue) + UpdateKnobPos(IsChecked.Value); + } + + Point _switchStartPoint = new Point(); + double _initLeft = -1; + private void KnobsPanel_PointerPressed(object sender, Input.PointerPressedEventArgs e) + { + _switchStartPoint = e.GetPosition(_switchKnob); + _initLeft = Canvas.GetLeft(_knobsPanel); + _isDragging = false; + _knobsPanelPressed = true; + } + + private void KnobsPanel_PointerReleased(object sender, Input.PointerReleasedEventArgs e) + { + if (_isDragging) + { + bool shouldBecomeChecked = Canvas.GetLeft(_knobsPanel) >= (_switchKnob.Bounds.Width / 2); + _knobsPanel.ClearValue(Canvas.LeftProperty); + + PseudoClasses.Set(":dragging", false); + + if (shouldBecomeChecked == IsChecked) + UpdateKnobPos(shouldBecomeChecked); + else + IsChecked = shouldBecomeChecked; + } + else + base.Toggle(); + + _isDragging = false; + + _knobsPanelPressed = false; + } + + bool _isDragging = false; + private void KnobsPanel_PointerMoved(object sender, Input.PointerEventArgs e) + { + if (_knobsPanelPressed) + { + var difference = e.GetPosition(_switchKnob) - _switchStartPoint; + + if ((!_isDragging) && (System.Math.Abs(difference.X) > 3)) + { + _isDragging = true; + PseudoClasses.Set(":dragging", true); + } + + if (_isDragging) + Canvas.SetLeft(_knobsPanel, System.Math.Min(_switchKnob.Bounds.Width, System.Math.Max(0, (_initLeft + difference.X)))); + } + } + + protected override void Toggle() + { + if ((_switchKnob != null) && (!_switchKnob.IsPointerOver)) + base.Toggle(); + } + + protected void UpdateKnobPos(bool value) + { + if ((_switchKnob != null) && (_knobsPanel != null)) + { + if (value) + Canvas.SetLeft(_knobsPanel, _switchKnob.Bounds.Width); + else + Canvas.SetLeft(_knobsPanel, 0); + } + } } } diff --git a/src/Avalonia.Themes.Fluent/ToggleSwitch.xaml b/src/Avalonia.Themes.Fluent/ToggleSwitch.xaml index 88266ac979..a8e848ec33 100644 --- a/src/Avalonia.Themes.Fluent/ToggleSwitch.xaml +++ b/src/Avalonia.Themes.Fluent/ToggleSwitch.xaml @@ -156,8 +156,8 @@ - - + - + - - @@ -264,10 +259,6 @@ - - From 773f3a3584b218c4c3580e2accd34cb474172d9e Mon Sep 17 00:00:00 2001 From: Splitwirez Date: Tue, 7 Jul 2020 13:51:45 -0400 Subject: [PATCH 3/4] Just code style things --- src/Avalonia.Controls/ToggleSwitch.cs | 35 +++++++++++++++++++++------ 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/src/Avalonia.Controls/ToggleSwitch.cs b/src/Avalonia.Controls/ToggleSwitch.cs index 15e22d4d36..74c2408449 100644 --- a/src/Avalonia.Controls/ToggleSwitch.cs +++ b/src/Avalonia.Controls/ToggleSwitch.cs @@ -10,6 +10,12 @@ namespace Avalonia.Controls /// public class ToggleSwitch : ToggleButton { + Panel _knobsPanel; + Panel _switchKnob; + bool _knobsPanelPressed = false; + Point _switchStartPoint = new Point(); + double _initLeft = -1; + static ToggleSwitch() { OffContentProperty.Changed.AddClassHandler((x, e) => x.OffContentChanged(e)); @@ -17,13 +23,17 @@ namespace Avalonia.Controls IsCheckedProperty.Changed.AddClassHandler((x, e) => { if ((e.NewValue != null) && (e.NewValue is bool val)) + { x.UpdateKnobPos(val); + } }); BoundsProperty.Changed.AddClassHandler((x, e) => { if (x.IsChecked != null) + { x.UpdateKnobPos(x.IsChecked.Value); + } }); } @@ -144,9 +154,6 @@ namespace Avalonia.Controls } - Panel _knobsPanel; - Panel _switchKnob; - bool _knobsPanelPressed = false; protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { base.OnApplyTemplate(e); @@ -159,11 +166,11 @@ namespace Avalonia.Controls _knobsPanel.PointerMoved += KnobsPanel_PointerMoved; if (IsChecked.HasValue) + { UpdateKnobPos(IsChecked.Value); + } } - - Point _switchStartPoint = new Point(); - double _initLeft = -1; + private void KnobsPanel_PointerPressed(object sender, Input.PointerPressedEventArgs e) { _switchStartPoint = e.GetPosition(_switchKnob); @@ -178,16 +185,22 @@ namespace Avalonia.Controls { bool shouldBecomeChecked = Canvas.GetLeft(_knobsPanel) >= (_switchKnob.Bounds.Width / 2); _knobsPanel.ClearValue(Canvas.LeftProperty); - + PseudoClasses.Set(":dragging", false); if (shouldBecomeChecked == IsChecked) + { UpdateKnobPos(shouldBecomeChecked); + } else + { IsChecked = shouldBecomeChecked; + } } else + { base.Toggle(); + } _isDragging = false; @@ -208,14 +221,18 @@ namespace Avalonia.Controls } if (_isDragging) + { Canvas.SetLeft(_knobsPanel, System.Math.Min(_switchKnob.Bounds.Width, System.Math.Max(0, (_initLeft + difference.X)))); + } } } protected override void Toggle() { if ((_switchKnob != null) && (!_switchKnob.IsPointerOver)) + { base.Toggle(); + } } protected void UpdateKnobPos(bool value) @@ -223,9 +240,13 @@ namespace Avalonia.Controls if ((_switchKnob != null) && (_knobsPanel != null)) { if (value) + { Canvas.SetLeft(_knobsPanel, _switchKnob.Bounds.Width); + } else + { Canvas.SetLeft(_knobsPanel, 0); + } } } } From ee709082fb6d4305f742de1475bf3725ccc56c97 Mon Sep 17 00:00:00 2001 From: Splitwirez Date: Wed, 8 Jul 2020 09:23:55 -0400 Subject: [PATCH 4/4] Just more code style things --- src/Avalonia.Controls/ToggleSwitch.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Avalonia.Controls/ToggleSwitch.cs b/src/Avalonia.Controls/ToggleSwitch.cs index 74c2408449..c32f2d8102 100644 --- a/src/Avalonia.Controls/ToggleSwitch.cs +++ b/src/Avalonia.Controls/ToggleSwitch.cs @@ -10,11 +10,12 @@ namespace Avalonia.Controls /// public class ToggleSwitch : ToggleButton { - Panel _knobsPanel; - Panel _switchKnob; - bool _knobsPanelPressed = false; - Point _switchStartPoint = new Point(); - double _initLeft = -1; + private Panel _knobsPanel; + private Panel _switchKnob; + private bool _knobsPanelPressed = false; + private Point _switchStartPoint = new Point(); + private double _initLeft = -1; + private bool _isDragging = false; static ToggleSwitch() { @@ -207,7 +208,6 @@ namespace Avalonia.Controls _knobsPanelPressed = false; } - bool _isDragging = false; private void KnobsPanel_PointerMoved(object sender, Input.PointerEventArgs e) { if (_knobsPanelPressed)