From 553deb41fd7285fa5e50c361ecfd13c9891f3561 Mon Sep 17 00:00:00 2001 From: robloo Date: Mon, 30 Jan 2023 23:34:20 -0500 Subject: [PATCH] Switch SplitView.IsPaneOpen to a StyledProperty Includes other small formatting changes and updates --- src/Avalonia.Controls/SplitView.cs | 141 +++++++++++++++++++---------- 1 file changed, 92 insertions(+), 49 deletions(-) diff --git a/src/Avalonia.Controls/SplitView.cs b/src/Avalonia.Controls/SplitView.cs index 200f0df607..b45e0f2adb 100644 --- a/src/Avalonia.Controls/SplitView.cs +++ b/src/Avalonia.Controls/SplitView.cs @@ -1,15 +1,13 @@ -using Avalonia.Controls.Metadata; +using System; +using Avalonia.Controls.Metadata; +using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; +using Avalonia.Controls.Templates; using Avalonia.Input; using Avalonia.Interactivity; +using Avalonia.LogicalTree; using Avalonia.Media; using Avalonia.Metadata; -using Avalonia.VisualTree; -using System; -using Avalonia.Reactive; -using Avalonia.Controls.Presenters; -using Avalonia.Controls.Templates; -using Avalonia.LogicalTree; namespace Avalonia.Controls { @@ -54,10 +52,13 @@ namespace Avalonia.Controls internal SplitViewTemplateSettings() { } public static readonly StyledProperty ClosedPaneWidthProperty = - AvaloniaProperty.Register(nameof(ClosedPaneWidth), 0d); + AvaloniaProperty.Register(nameof(ClosedPaneWidth), + 0d); public static readonly StyledProperty PaneColumnGridLengthProperty = - AvaloniaProperty.Register(nameof(PaneColumnGridLength)); + AvaloniaProperty.Register( + nameof(PaneColumnGridLength)); public double ClosedPaneWidth { @@ -93,26 +94,34 @@ namespace Avalonia.Controls /// Defines the property /// public static readonly StyledProperty CompactPaneLengthProperty = - AvaloniaProperty.Register(nameof(CompactPaneLength), defaultValue: 48); + AvaloniaProperty.Register( + nameof(CompactPaneLength), + defaultValue: 48); /// /// Defines the property /// public static readonly StyledProperty DisplayModeProperty = - AvaloniaProperty.Register(nameof(DisplayMode), defaultValue: SplitViewDisplayMode.Overlay); + AvaloniaProperty.Register( + nameof(DisplayMode), + defaultValue: SplitViewDisplayMode.Overlay); /// /// Defines the property /// - public static readonly DirectProperty IsPaneOpenProperty = - AvaloniaProperty.RegisterDirect(nameof(IsPaneOpen), - x => x.IsPaneOpen, (x, v) => x.IsPaneOpen = v); + public static readonly StyledProperty IsPaneOpenProperty = + AvaloniaProperty.Register( + nameof(IsPaneOpen), + defaultValue: false, + coerce: CoerceIsPaneOpen); /// /// Defines the property /// public static readonly StyledProperty OpenPaneLengthProperty = - AvaloniaProperty.Register(nameof(OpenPaneLength), defaultValue: 320); + AvaloniaProperty.Register( + nameof(OpenPaneLength), + defaultValue: 320); /// /// Defines the property @@ -150,7 +159,6 @@ namespace Avalonia.Controls public static readonly StyledProperty TemplateSettingsProperty = AvaloniaProperty.Register(nameof(TemplateSettings)); - private bool _isPaneOpen; private Panel? _pane; private IDisposable? _pointerDisposable; @@ -169,7 +177,7 @@ namespace Avalonia.Controls PanePlacementProperty.Changed.AddClassHandler((x, v) => x.OnPanePlacementChanged(v)); DisplayModeProperty.Changed.AddClassHandler((x, v) => x.OnDisplayModeChanged(v)); - PaneProperty.Changed.AddClassHandler((x, e) => x.PaneChanged(e)); + PaneProperty.Changed.AddClassHandler((x, e) => x.OnPaneChanged(e)); } /// @@ -196,37 +204,8 @@ namespace Avalonia.Controls /// public bool IsPaneOpen { - get => _isPaneOpen; - set - { - if (value == _isPaneOpen) - { - return; - } - - if (value) - { - OnPaneOpening(EventArgs.Empty); - SetAndRaise(IsPaneOpenProperty, ref _isPaneOpen, value); - - PseudoClasses.Add(":open"); - PseudoClasses.Remove(":closed"); - OnPaneOpened(EventArgs.Empty); - } - else - { - SplitViewPaneClosingEventArgs args = new SplitViewPaneClosingEventArgs(false); - OnPaneClosing(args); - if (!args.Cancel) - { - SetAndRaise(IsPaneOpenProperty, ref _isPaneOpen, value); - - PseudoClasses.Add(":closed"); - PseudoClasses.Remove(":open"); - OnPaneClosed(EventArgs.Empty); - } - } - } + get => GetValue(IsPaneOpenProperty); + set => SetValue(IsPaneOpenProperty, value); } /// @@ -351,6 +330,30 @@ namespace Avalonia.Controls _pointerDisposable?.Dispose(); } + /// + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); + + if (change.Property == IsPaneOpenProperty) + { + bool isPaneOpen = change.GetNewValue(); + + if (isPaneOpen) + { + PseudoClasses.Add(":open"); + PseudoClasses.Remove(":closed"); + OnPaneOpened(EventArgs.Empty); + } + else + { + PseudoClasses.Add(":closed"); + PseudoClasses.Remove(":open"); + OnPaneClosed(EventArgs.Empty); + } + } + } + private void PointerPressedOutside(object? sender, PointerPressedEventArgs e) { if (!IsPaneOpen) @@ -485,7 +488,7 @@ namespace Avalonia.Controls PseudoClasses.Set(":lightdismiss", mode); } - private void PaneChanged(AvaloniaPropertyChangedEventArgs e) + private void OnPaneChanged(AvaloniaPropertyChangedEventArgs e) { if (e.OldValue is ILogical oldChild) { @@ -497,5 +500,45 @@ namespace Avalonia.Controls LogicalChildren.Add(newChild); } } + + /// + /// Called when the property has to be coerced. + /// + /// The value to coerce. + protected virtual bool OnCoerceIsPaneOpen(bool value) + { + if (value) + { + OnPaneOpening(EventArgs.Empty); + } + else + { + var eventArgs = new SplitViewPaneClosingEventArgs(false); + OnPaneClosing(eventArgs); + + if (eventArgs.Cancel) + { + return !value; + } + } + + return value; + } + + /// + /// Coerces/validates the property value. + /// + /// The instance. + /// The value to coerce. + /// The coerced/validated value. + private static bool CoerceIsPaneOpen(AvaloniaObject instance, bool value) + { + if (instance is SplitView splitView) + { + return splitView.OnCoerceIsPaneOpen(value); + } + + return value; + } } }