From 965d209035eec2f3bf5347a97635ce8cc17228f1 Mon Sep 17 00:00:00 2001 From: polarboy Date: Fri, 26 Jul 2024 22:34:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E7=A6=81=E7=94=A8=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=E5=92=8C=E9=80=89=E6=8B=A9checkbox=E5=92=8Cradio?= =?UTF-8?q?=E7=9A=84=E6=95=B0=E6=8D=AE=E5=85=B3=E8=81=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ShowCase/MenuShowCase.axaml | 2 + src/AtomUI.Controls/Flyouts/FlyoutHost.cs | 30 ++++----- src/AtomUI.Controls/Menu/ContextMenuTheme.cs | 1 - src/AtomUI.Controls/Menu/MenuItem.cs | 9 ++- src/AtomUI.Controls/Menu/MenuItemTheme.cs | 9 +++ .../RadioButton/RadioButton.cs | 66 +++++++++---------- 6 files changed, 63 insertions(+), 54 deletions(-) diff --git a/Samples/AtomUI.Demo.Desktop/ShowCase/MenuShowCase.axaml b/Samples/AtomUI.Demo.Desktop/ShowCase/MenuShowCase.axaml index bb285aef1..44ba2f8cf 100644 --- a/Samples/AtomUI.Demo.Desktop/ShowCase/MenuShowCase.axaml +++ b/Samples/AtomUI.Demo.Desktop/ShowCase/MenuShowCase.axaml @@ -22,6 +22,7 @@ + @@ -72,6 +73,7 @@ Icon="{atom:IconProvider Kind=CheckOutlined}" /> + diff --git a/src/AtomUI.Controls/Flyouts/FlyoutHost.cs b/src/AtomUI.Controls/Flyouts/FlyoutHost.cs index e0b415cc0..e592ddb81 100644 --- a/src/AtomUI.Controls/Flyouts/FlyoutHost.cs +++ b/src/AtomUI.Controls/Flyouts/FlyoutHost.cs @@ -1,6 +1,4 @@ -using System.Reactive.Disposables; -using AtomUI.Data; -using AtomUI.Styling; +using AtomUI.Styling; using AtomUI.Utils; using Avalonia; using Avalonia.Controls; @@ -8,7 +6,6 @@ using Avalonia.Controls.Diagnostics; using Avalonia.Controls.Primitives.PopupPositioning; using Avalonia.Input; using Avalonia.Input.Raw; -using Avalonia.LogicalTree; using Avalonia.Metadata; using Avalonia.Threading; @@ -146,7 +143,6 @@ public class FlyoutHost : Control } private bool _initialized = false; - private CompositeDisposable? _compositeDisposable; private DispatcherTimer? _mouseEnterDelayTimer; private DispatcherTimer? _mouseLeaveDelayTimer; @@ -171,7 +167,6 @@ public class FlyoutHost : Control protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) { base.OnAttachedToVisualTree(e); - _compositeDisposable = new CompositeDisposable(); SetupTriggerHandler(); SetupFlyoutProperties(); } @@ -179,7 +174,6 @@ public class FlyoutHost : Control protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e) { base.OnDetachedFromVisualTree(e); - _compositeDisposable?.Dispose(); StopMouseLeaveTimer(); StopMouseEnterTimer(); } @@ -187,12 +181,12 @@ public class FlyoutHost : Control private void SetupFlyoutProperties() { if (Flyout is not null) { - _compositeDisposable?.Add(BindUtils.RelayBind(this, PlacementProperty, Flyout)); - _compositeDisposable?.Add(BindUtils.RelayBind(this, PlacementAnchorProperty, Flyout)); - _compositeDisposable?.Add(BindUtils.RelayBind(this, PlacementGravityProperty, Flyout)); - _compositeDisposable?.Add(BindUtils.RelayBind(this, IsShowArrowProperty, Flyout)); - _compositeDisposable?.Add(BindUtils.RelayBind(this, IsPointAtCenterProperty, Flyout)); - _compositeDisposable?.Add(BindUtils.RelayBind(this, MarginToAnchorProperty, Flyout)); + BindUtils.RelayBind(this, PlacementProperty, Flyout); + BindUtils.RelayBind(this, PlacementAnchorProperty, Flyout); + BindUtils.RelayBind(this, PlacementGravityProperty, Flyout); + BindUtils.RelayBind(this, IsShowArrowProperty, Flyout); + BindUtils.RelayBind(this, IsPointAtCenterProperty, Flyout); + BindUtils.RelayBind(this, MarginToAnchorProperty, Flyout); } } @@ -202,22 +196,22 @@ public class FlyoutHost : Control return; } if (Trigger == FlyoutTriggerType.Hover) { - _compositeDisposable?.Add(IsPointerOverProperty.Changed.Subscribe(args => + IsPointerOverProperty.Changed.Subscribe(args => { if (args.Sender == AnchorTarget) { HandleAnchorTargetHover(args); } - })); + }); } else if (Trigger == FlyoutTriggerType.Focus) { - _compositeDisposable?.Add(IsFocusedProperty.Changed.Subscribe(args => + IsFocusedProperty.Changed.Subscribe(args => { if (args.Sender == AnchorTarget) { HandleAnchorTargetFocus(args); } - })); + }); } else if (Trigger == FlyoutTriggerType.Click) { var inputManager = AvaloniaLocator.Current.GetService()!; - _compositeDisposable?.Add(inputManager.Process.Subscribe(HandleAnchorTargetClick)); + inputManager.Process.Subscribe(HandleAnchorTargetClick); } } diff --git a/src/AtomUI.Controls/Menu/ContextMenuTheme.cs b/src/AtomUI.Controls/Menu/ContextMenuTheme.cs index a92db7ece..4e142783b 100644 --- a/src/AtomUI.Controls/Menu/ContextMenuTheme.cs +++ b/src/AtomUI.Controls/Menu/ContextMenuTheme.cs @@ -1,6 +1,5 @@ using AtomUI.Styling; using AtomUI.Utils; -using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Presenters; using Avalonia.Controls.Templates; diff --git a/src/AtomUI.Controls/Menu/MenuItem.cs b/src/AtomUI.Controls/Menu/MenuItem.cs index 81dec20c9..051f17f87 100644 --- a/src/AtomUI.Controls/Menu/MenuItem.cs +++ b/src/AtomUI.Controls/Menu/MenuItem.cs @@ -108,10 +108,15 @@ public class MenuItem : AvaloniaMenuItem, IControlCustomStyle _togglePresenter.Presenter.IsVisible = false; } } else if (ToggleType == MenuItemToggleType.CheckBox) { - _togglePresenter.Content = new CheckBox(); + var checkbox = new CheckBox(); + BindUtils.RelayBind(this, IsCheckedProperty, checkbox, CheckBox.IsCheckedProperty); + _togglePresenter.Content = checkbox; _togglePresenter.IsVisible = true; } else if (ToggleType == MenuItemToggleType.Radio) { - _togglePresenter.Content = new RadioButton(); + var radioButton = new RadioButton(); + BindUtils.RelayBind(this, IsCheckedProperty, radioButton, RadioButton.IsCheckedProperty); + BindUtils.RelayBind(this, GroupNameProperty, radioButton, RadioButton.GroupNameProperty); + _togglePresenter.Content = radioButton; _togglePresenter.IsVisible = true; } } diff --git a/src/AtomUI.Controls/Menu/MenuItemTheme.cs b/src/AtomUI.Controls/Menu/MenuItemTheme.cs index 719c1982d..1bccc3099 100644 --- a/src/AtomUI.Controls/Menu/MenuItemTheme.cs +++ b/src/AtomUI.Controls/Menu/MenuItemTheme.cs @@ -79,6 +79,7 @@ internal class MenuItemTheme : ControlTheme VerticalAlignment = VerticalAlignment.Center, IsVisible = false }; + CreateTemplateParentBinding(togglePresenter, ContentControl.IsEnabledProperty, MenuItem.IsEnabledProperty); Grid.SetColumn(togglePresenter, 0); togglePresenter.RegisterInNameScope(scope); @@ -202,6 +203,7 @@ internal class MenuItemTheme : ControlTheme BuildMenuIndicatorStyle(); BuildMenuIconStyle(); Add(commonStyle); + BuildDisabledStyle(); } private void BuildCommonStyle(Style commonStyle) @@ -264,4 +266,11 @@ internal class MenuItemTheme : ControlTheme } Add(hasIconStyle); } + + private void BuildDisabledStyle() + { + var disabledStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Disabled)); + disabledStyle.Add(MenuItem.ForegroundProperty, MenuResourceKey.ItemDisabledColor); + Add(disabledStyle); + } } \ No newline at end of file diff --git a/src/AtomUI.Controls/RadioButton/RadioButton.cs b/src/AtomUI.Controls/RadioButton/RadioButton.cs index cc1b6cda6..802d666a3 100644 --- a/src/AtomUI.Controls/RadioButton/RadioButton.cs +++ b/src/AtomUI.Controls/RadioButton/RadioButton.cs @@ -1,5 +1,4 @@ using AtomUI.Controls.Utils; -using AtomUI.Data; using AtomUI.Media; using AtomUI.Styling; using AtomUI.Utils; @@ -7,10 +6,8 @@ using Avalonia; using Avalonia.Animation; using Avalonia.Controls; using Avalonia.Controls.Primitives; -using Avalonia.Data; using Avalonia.Input; using Avalonia.Layout; -using Avalonia.LogicalTree; using Avalonia.Media; using Avalonia.Rendering; @@ -18,98 +15,98 @@ namespace AtomUI.Controls; using AvaloniaRadioButton = Avalonia.Controls.RadioButton; -public partial class RadioButton : AvaloniaRadioButton, - ICustomHitTest, - IWaveAdornerInfoProvider, - IControlCustomStyle +public class RadioButton : AvaloniaRadioButton, + ICustomHitTest, + IWaveAdornerInfoProvider, + IControlCustomStyle { internal static readonly StyledProperty RadioSizeProperty = AvaloniaProperty.Register(nameof(RadioSize), 0); - + internal static readonly StyledProperty PaddingInlineProperty = AvaloniaProperty.Register(nameof(PaddingInline), 0); - + internal static readonly StyledProperty RadioBorderBrushProperty = AvaloniaProperty.Register(nameof(RadioBorderBrush)); - + internal static readonly StyledProperty RadioInnerBackgroundProperty = AvaloniaProperty.Register(nameof(RadioInnerBackground)); - + internal static readonly StyledProperty RadioBackgroundProperty = AvaloniaProperty.Register(nameof(RadioBackground)); - + internal static readonly StyledProperty RadioBorderThicknessProperty = AvaloniaProperty.Register(nameof(RadioBorderThickness)); - + internal static readonly StyledProperty RadioDotEffectSizeProperty = AvaloniaProperty.Register(nameof(RadioDotEffectSize)); - + internal static readonly StyledProperty DotSizeValueProperty = AvaloniaProperty.Register( nameof(DotSizeValue)); - + internal static readonly StyledProperty DotPaddingProperty = AvaloniaProperty.Register( nameof(DotPadding)); - + internal double RadioSize { get => GetValue(RadioSizeProperty); set => SetValue(RadioSizeProperty, value); } - + internal double PaddingInline { get => GetValue(PaddingInlineProperty); set => SetValue(PaddingInlineProperty, value); } - + internal IBrush? RadioBorderBrush { get => GetValue(RadioBorderBrushProperty); set => SetValue(RadioBorderBrushProperty, value); } - + internal IBrush? RadioInnerBackground { get => GetValue(RadioInnerBackgroundProperty); set => SetValue(RadioInnerBackgroundProperty, value); } - + internal IBrush? RadioBackground { get => GetValue(RadioBackgroundProperty); set => SetValue(RadioBackgroundProperty, value); } - + internal Thickness RadioBorderThickness { get => GetValue(RadioBorderThicknessProperty); set => SetValue(RadioBorderThicknessProperty, value); } - + internal double RadioDotEffectSize { get => GetValue(RadioDotEffectSizeProperty); set => SetValue(RadioDotEffectSizeProperty, value); } - + internal double DotSizeValue { get => GetValue(DotSizeValueProperty); set => SetValue(DotSizeValueProperty, value); } - + internal double DotPadding { get => GetValue(DotPaddingProperty); set => SetValue(DotPaddingProperty, value); } - + private IPen? _cachedPen; private ControlStyleState _styleState; private IControlCustomStyle _customStyle; - + static RadioButton() { AffectsRender( @@ -130,7 +127,7 @@ public partial class RadioButton : AvaloniaRadioButton, base.OnPropertyChanged(e); _customStyle.HandlePropertyChangedForStyle(e); } - + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { base.OnApplyTemplate(e); @@ -180,14 +177,13 @@ public partial class RadioButton : AvaloniaRadioButton, var dotDiameter = RadioDotEffectSize / 2; context.DrawEllipse(RadioInnerBackground, null, radioRect.Center, dotDiameter, dotDiameter); } - } public bool HitTest(Point point) { return true; } - + #region IControlCustomStyle 实现 void IControlCustomStyle.CollectStyleState() @@ -218,6 +214,7 @@ public partial class RadioButton : AvaloniaRadioButton, } else { targetValue = DotSizeValue * 0.6; } + return targetValue; } @@ -227,7 +224,8 @@ public partial class RadioButton : AvaloniaRadioButton, { AnimationUtils.CreateTransition(RadioBorderBrushProperty), AnimationUtils.CreateTransition(RadioDotEffectSizeProperty), - AnimationUtils.CreateTransition(RadioBackgroundProperty, GlobalResourceKey.MotionDurationFast) + AnimationUtils.CreateTransition(RadioBackgroundProperty, + GlobalResourceKey.MotionDurationFast) }; } @@ -243,7 +241,7 @@ public partial class RadioButton : AvaloniaRadioButton, var offsetX = RadioSize + PaddingInline; return new Rect(offsetX, 0d, DesiredSize.Width - offsetX, DesiredSize.Height); } - + void IControlCustomStyle.HandlePropertyChangedForStyle(AvaloniaPropertyChangedEventArgs e) { if (e.Property == IsPointerOverProperty || @@ -253,7 +251,8 @@ public partial class RadioButton : AvaloniaRadioButton, if (VisualRoot is not null) { RadioDotEffectSize = CalculateDotSize(IsEnabled, IsChecked.HasValue && IsChecked.Value); } - if (e.Property == IsCheckedProperty && + + if (e.Property == IsCheckedProperty && _styleState.HasFlag(ControlStyleState.Enabled) && _styleState.HasFlag(ControlStyleState.On)) { WaveSpiritAdorner.ShowWaveAdorner(this, WaveType.CircleWave); @@ -265,10 +264,11 @@ public partial class RadioButton : AvaloniaRadioButton, { return RadioRect(); } - + public CornerRadius WaveBorderRadius() { return new CornerRadius(RadioSize / 2); } + #endregion } \ No newline at end of file