完成禁用样式和选择checkbox和radio的数据关联

This commit is contained in:
polarboy
2024-07-26 22:34:26 +08:00
parent 69b7195f44
commit 965d209035
6 changed files with 63 additions and 54 deletions
@@ -22,6 +22,7 @@
<atom:MenuSeparator />
<atom:MenuItem Header="Cut" InputGesture="Ctrl+X" />
</atom:MenuItem>
<atom:MenuItem Header="Disabled Item" IsEnabled="False" />
</atom:Menu>
</showcase:ShowCaseItem>
@@ -72,6 +73,7 @@
Icon="{atom:IconProvider Kind=CheckOutlined}" />
<atom:MenuSeparator />
<atom:MenuItem Header="Exit" />
<atom:MenuItem Header="Disabled" IsEnabled="False"/>
</atom:MenuItem>
</atom:Menu>
</showcase:ShowCaseItem>
+12 -18
View File
@@ -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<IInputManager>()!;
_compositeDisposable?.Add(inputManager.Process.Subscribe(HandleAnchorTargetClick));
inputManager.Process.Subscribe(HandleAnchorTargetClick);
}
}
@@ -1,6 +1,5 @@
using AtomUI.Styling;
using AtomUI.Utils;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Templates;
+7 -2
View File
@@ -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;
}
}
@@ -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);
}
}
+33 -33
View File
@@ -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<double> RadioSizeProperty =
AvaloniaProperty.Register<Button, double>(nameof(RadioSize), 0);
internal static readonly StyledProperty<double> PaddingInlineProperty =
AvaloniaProperty.Register<Button, double>(nameof(PaddingInline), 0);
internal static readonly StyledProperty<IBrush?> RadioBorderBrushProperty =
AvaloniaProperty.Register<Button, IBrush?>(nameof(RadioBorderBrush));
internal static readonly StyledProperty<IBrush?> RadioInnerBackgroundProperty =
AvaloniaProperty.Register<Button, IBrush?>(nameof(RadioInnerBackground));
internal static readonly StyledProperty<IBrush?> RadioBackgroundProperty =
AvaloniaProperty.Register<Button, IBrush?>(nameof(RadioBackground));
internal static readonly StyledProperty<Thickness> RadioBorderThicknessProperty =
AvaloniaProperty.Register<Button, Thickness>(nameof(RadioBorderThickness));
internal static readonly StyledProperty<double> RadioDotEffectSizeProperty =
AvaloniaProperty.Register<Button, double>(nameof(RadioDotEffectSize));
internal static readonly StyledProperty<double> DotSizeValueProperty =
AvaloniaProperty.Register<RadioButton, double>(
nameof(DotSizeValue));
internal static readonly StyledProperty<double> DotPaddingProperty =
AvaloniaProperty.Register<RadioButton, double>(
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<RadioButton>(
@@ -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<SolidColorBrushTransition>(RadioBorderBrushProperty),
AnimationUtils.CreateTransition<DoubleTransition>(RadioDotEffectSizeProperty),
AnimationUtils.CreateTransition<SolidColorBrushTransition>(RadioBackgroundProperty, GlobalResourceKey.MotionDurationFast)
AnimationUtils.CreateTransition<SolidColorBrushTransition>(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
}