From e730e15d66b68a625651579634ca3d94bdb79e71 Mon Sep 17 00:00:00 2001 From: robloo Date: Thu, 27 Jan 2022 11:20:54 -0500 Subject: [PATCH] Remove SplitButton.cs after cherry-pick --- .../SplitButton/SplitButton.cs | 735 ------------------ 1 file changed, 735 deletions(-) delete mode 100644 src/Avalonia.Controls/SplitButton/SplitButton.cs diff --git a/src/Avalonia.Controls/SplitButton/SplitButton.cs b/src/Avalonia.Controls/SplitButton/SplitButton.cs deleted file mode 100644 index 5c75a8d09d..0000000000 --- a/src/Avalonia.Controls/SplitButton/SplitButton.cs +++ /dev/null @@ -1,735 +0,0 @@ -using System; -using System.Reactive.Disposables; -using System.Windows.Input; -using Avalonia.Controls.Metadata; -using Avalonia.Controls.Primitives; -using Avalonia.Input; -using Avalonia.Interactivity; -using Avalonia.LogicalTree; - -namespace Avalonia.Controls -{ - /// - /// A button with primary and secondary parts that can each be pressed separately. - /// The primary part behaves like a and the secondary part opens a flyout. - /// - [PseudoClasses( - pcDisabled, - pcSecondaryButtonRight, - pcSecondaryButtonSpan, - pcCheckedFlyoutOpen, - pcFlyoutOpen, - pcCheckedTouchPressed, - pcChecked, - pcCheckedPrimaryPressed, - pcCheckedPrimaryPointerOver, - pcCheckedSecondaryPressed, - pcCheckedSecondaryPointerOver, - pcTouchPressed, - pcPrimaryPressed, - pcPrimaryPointerOver, - pcSecondaryPressed, - pcSecondaryPointerOver)] - public class SplitButton : ContentControl, ICommandSource - { - private const string pcDisabled = ":disabled"; - - private const string pcSecondaryButtonRight = ":secondary-button-right"; - private const string pcSecondaryButtonSpan = ":secondary-button-span"; - - private const string pcCheckedFlyoutOpen = ":checked-flyout-open"; - private const string pcFlyoutOpen = ":flyout-open"; - - private const string pcCheckedTouchPressed = ":checked-touch-pressed"; - private const string pcChecked = ":checked"; - private const string pcCheckedPrimaryPressed = ":checked-primary-pressed"; - private const string pcCheckedPrimaryPointerOver = ":checked-primary-pointerover"; - private const string pcCheckedSecondaryPressed = ":checked-secondary-pressed"; - private const string pcCheckedSecondaryPointerOver = ":checked-secondary-pointerover"; - - private const string pcTouchPressed = ":touch-pressed"; - private const string pcPrimaryPressed = ":primary-pressed"; - private const string pcPrimaryPointerOver = ":primary-pointerover"; - private const string pcSecondaryPressed = ":secondary-pressed"; - private const string pcSecondaryPointerOver = ":secondary-pointerover"; - - /// - /// Raised when the user presses the primary part of the . - /// - public event EventHandler Click - { - add => AddHandler(ClickEvent, value); - remove => RemoveHandler(ClickEvent, value); - } - - /// - /// Defines the event. - /// - public static readonly RoutedEvent ClickEvent = - RoutedEvent.Register( - nameof(Click), - RoutingStrategies.Bubble); - - /// - /// Defines the property. - /// - public static readonly DirectProperty CommandProperty = - AvaloniaProperty.RegisterDirect( - nameof(Command), - splitButton => splitButton.Command, - (splitButton, command) => splitButton.Command = command, - enableDataValidation: true); - - /// - /// Defines the property. - /// - public static readonly StyledProperty CommandParameterProperty = - AvaloniaProperty.Register( - nameof(CommandParameter)); - - /// - /// Defines the property - /// - public static readonly StyledProperty FlyoutProperty = - AvaloniaProperty.Register( - nameof(Flyout)); - - private ICommand _Command; - - private Button _primaryButton = null; - private Button _secondaryButton = null; - - private bool _commandCanExecute = true; - protected bool _hasLoaded = false; - private bool _isAttachedToLogicalTree = false; - private bool _isFlyoutOpen = false; - private bool _isKeyDown = false; - private PointerType _lastPointerType = PointerType.Mouse; - - private CompositeDisposable _buttonPropertyChangedDisposable; - private IDisposable _flyoutPropertyChangedDisposable; - - //////////////////////////////////////////////////////////////////////// - // Constructor / Destructors - //////////////////////////////////////////////////////////////////////// - - /// - /// Initializes a new instance of the class. - /// - public SplitButton() - { - } - - //////////////////////////////////////////////////////////////////////// - // Properties - //////////////////////////////////////////////////////////////////////// - - /// - /// Gets or sets the invoked when the primary part is pressed. - /// - public ICommand Command - { - get => _Command; - set => SetAndRaise(CommandProperty, ref _Command, value); - } - - /// - /// Gets or sets a parameter to be passed to the . - /// - public object CommandParameter - { - get => GetValue(CommandParameterProperty); - set => SetValue(CommandParameterProperty, value); - } - - /// - /// Gets or sets the that is shown when the secondary part is pressed. - /// - public FlyoutBase Flyout - { - get => GetValue(FlyoutProperty); - set => SetValue(FlyoutProperty, value); - } - - /// - /// Gets a value indicating whether the button is currently checked. - /// - /// - /// This property exists only for the derived and is - /// unused (set to false) within . Doing this allows the - /// two controls to share a default style. - /// - internal virtual bool InternalIsChecked => false; - - /// - protected override bool IsEnabledCore => base.IsEnabledCore && _commandCanExecute; - - //////////////////////////////////////////////////////////////////////// - // Methods - //////////////////////////////////////////////////////////////////////// - - /// - public void CanExecuteChanged(object sender, EventArgs e) - { - var canExecute = Command == null || Command.CanExecute(CommandParameter); - - if (canExecute != _commandCanExecute) - { - _commandCanExecute = canExecute; - UpdateIsEffectivelyEnabled(); - } - } - - /// - /// Updates the visual state of the control by applying latest PseudoClasses. - /// - protected void UpdatePseudoClasses() - { - // Place the secondary button - // - // In WinUI, the span of the secondary button is changed to full-width for touch-based - // devices in certain conditions. The full reasoning for this is unknown. Some theories - // include: - // - // My guess is that the design team at MS decided that it's a better experience - // for touch users to make them select from the drop down rather than the shortcut - // top level button, so touch basically just turns this into a drop down button. - // Whether that's ideal or not is going is a subjective opinion. - // - // For Avalonia, it may not always make sense to disable the primary button like that - // on touch-first platforms. Users and developers would normally expect a control to - // function the same on all platforms. Therefore, this functionality is disabled here - // but could be re-enabled in the future if more reasons become known. - // - // Finally, these are mutually exclusive PseudoClasses handled separately from - // SetExclusivePseudoClass(). They must be applied in addition to the others. - /* - if (_lastPointerType == PointerType.Touch || _isKeyDown) - { - PseudoClasses.Set(pcSecondaryButtonSpan, true); - PseudoClasses.Set(pcSecondaryButtonRight, false); - } - else - { - PseudoClasses.Set(pcSecondaryButtonSpan, false); - PseudoClasses.Set(pcSecondaryButtonRight, true); - } - */ - - // Change the visual state - if (!IsEffectivelyEnabled) - { - SetExclusivePseudoClass(pcDisabled); - } - else if (_primaryButton != null && _secondaryButton != null) - { - if (_isFlyoutOpen) - { - if (InternalIsChecked) - { - SetExclusivePseudoClass(pcCheckedFlyoutOpen); - } - else - { - SetExclusivePseudoClass(pcFlyoutOpen); - } - } - // SplitButton and ToggleSplitButton share a template -- this section is driving the checked states for ToggleSplitButton. - else if (InternalIsChecked) - { - if (_lastPointerType == PointerType.Touch || _isKeyDown) - { - if (_primaryButton.IsPressed || _secondaryButton.IsPressed || _isKeyDown) - { - SetExclusivePseudoClass(pcCheckedTouchPressed); - } - else - { - SetExclusivePseudoClass(pcChecked); - } - } - else if (_primaryButton.IsPressed) - { - SetExclusivePseudoClass(pcCheckedPrimaryPressed); - } - else if (_primaryButton.IsPointerOver) - { - SetExclusivePseudoClass(pcCheckedPrimaryPointerOver); - } - else if (_secondaryButton.IsPressed) - { - SetExclusivePseudoClass(pcCheckedSecondaryPressed); - } - else if (_secondaryButton.IsPointerOver) - { - SetExclusivePseudoClass(pcCheckedSecondaryPointerOver); - } - else - { - SetExclusivePseudoClass(pcChecked); - } - } - else - { - if (_lastPointerType == PointerType.Touch || _isKeyDown) - { - if (_primaryButton.IsPressed || _secondaryButton.IsPressed || _isKeyDown) - { - SetExclusivePseudoClass(pcTouchPressed); - } - else - { - // Calling without a parameter is treated as ':normal' and will clear all other - // PseudoClasses returning to the default state - SetExclusivePseudoClass(); - } - } - else if (_primaryButton.IsPressed) - { - SetExclusivePseudoClass(pcPrimaryPressed); - } - else if (_primaryButton.IsPointerOver) - { - SetExclusivePseudoClass(pcPrimaryPointerOver); - } - else if (_secondaryButton.IsPressed) - { - SetExclusivePseudoClass(pcSecondaryPressed); - } - else if (_secondaryButton.IsPointerOver) - { - SetExclusivePseudoClass(pcSecondaryPointerOver); - } - else - { - // Calling without a parameter is treated as ':normal' and will clear all other - // PseudoClasses returning to the default state - SetExclusivePseudoClass(); - } - } - } - - // Local function to enable the specified PseudoClass and disable all others - // This more closely matches the VisualStateManager of WinUI where the default style originated - void SetExclusivePseudoClass(string pseudoClass = "") - { - PseudoClasses.Set(pcDisabled, pseudoClass == pcDisabled); - - PseudoClasses.Set(pcCheckedFlyoutOpen, pseudoClass == pcCheckedFlyoutOpen); - PseudoClasses.Set(pcFlyoutOpen, pseudoClass == pcFlyoutOpen); - - PseudoClasses.Set(pcCheckedTouchPressed, pseudoClass == pcCheckedTouchPressed); - PseudoClasses.Set(pcChecked, pseudoClass == pcChecked); - PseudoClasses.Set(pcCheckedPrimaryPressed, pseudoClass == pcCheckedPrimaryPressed); - PseudoClasses.Set(pcCheckedPrimaryPointerOver, pseudoClass == pcCheckedPrimaryPointerOver); - PseudoClasses.Set(pcCheckedSecondaryPressed, pseudoClass == pcCheckedSecondaryPressed); - PseudoClasses.Set(pcCheckedSecondaryPointerOver, pseudoClass == pcCheckedSecondaryPointerOver); - - PseudoClasses.Set(pcTouchPressed, pseudoClass == pcTouchPressed); - PseudoClasses.Set(pcPrimaryPressed, pseudoClass == pcPrimaryPressed); - PseudoClasses.Set(pcPrimaryPointerOver, pseudoClass == pcPrimaryPointerOver); - PseudoClasses.Set(pcSecondaryPressed, pseudoClass == pcSecondaryPressed); - PseudoClasses.Set(pcSecondaryPointerOver, pseudoClass == pcSecondaryPointerOver); - } - } - - /// - /// Opens the secondary button's flyout. - /// - protected void OpenFlyout() - { - if (Flyout != null) - { - Flyout.ShowAt(this); - } - } - - /// - /// Closes the secondary button's flyout. - /// - protected void CloseFlyout() - { - if (Flyout != null) - { - Flyout.Hide(); - } - } - - /// - /// Registers all flyout events. - /// - /// The flyout to connect events to. - private void RegisterFlyoutEvents(FlyoutBase flyout) - { - if (flyout != null) - { - flyout.Opened += Flyout_Opened; - flyout.Closed += Flyout_Closed; - - _flyoutPropertyChangedDisposable = flyout.GetPropertyChangedObservable(FlyoutBase.PlacementProperty).Subscribe(Flyout_PlacementPropertyChanged); - } - } - - /// - /// Explicitly unregisters all flyout events. - /// - /// The flyout to disconnect events from. - private void UnregisterFlyoutEvents(FlyoutBase flyout) - { - if (flyout != null) - { - flyout.Opened -= Flyout_Opened; - flyout.Closed -= Flyout_Closed; - - _flyoutPropertyChangedDisposable?.Dispose(); - _flyoutPropertyChangedDisposable = null; - } - } - - /// - /// Explicitly unregisters all events related to the two buttons in OnApplyTemplate(). - /// - private void UnregisterEvents() - { - _buttonPropertyChangedDisposable?.Dispose(); - _buttonPropertyChangedDisposable = null; - - if (_primaryButton != null) - { - _primaryButton.Click -= PrimaryButton_Click; - - _primaryButton.PointerEnter -= Button_PointerEvent; - _primaryButton.PointerLeave -= Button_PointerEvent; - _primaryButton.PointerPressed -= Button_PointerEvent; - _primaryButton.PointerReleased -= Button_PointerEvent; - _primaryButton.PointerCaptureLost -= Button_PointerCaptureLost; - } - - if (_secondaryButton != null) - { - _secondaryButton.Click -= SecondaryButton_Click; - - _secondaryButton.PointerEnter -= Button_PointerEvent; - _secondaryButton.PointerLeave -= Button_PointerEvent; - _secondaryButton.PointerPressed -= Button_PointerEvent; - _secondaryButton.PointerReleased -= Button_PointerEvent; - _secondaryButton.PointerCaptureLost -= Button_PointerCaptureLost; - } - } - - //////////////////////////////////////////////////////////////////////// - // OnEvent Overridable Methods - //////////////////////////////////////////////////////////////////////// - - /// - protected override void OnApplyTemplate(TemplateAppliedEventArgs e) - { - UnregisterEvents(); - UnregisterFlyoutEvents(Flyout); - - _primaryButton = e.NameScope.Find