Merge branch 'feature/checkbox' into release/5.0

This commit is contained in:
chinboy
2025-10-17 11:15:18 +08:00
4 changed files with 35 additions and 82 deletions
@@ -38,6 +38,9 @@ internal class CheckBoxIndicator : TemplatedControl
public static readonly StyledProperty<double> TristateMarkSizeProperty =
AvaloniaProperty.Register<CheckBoxIndicator, double>(nameof(TristateMarkSize));
public static readonly StyledProperty<ITransform?> CheckedMarkRenderTransformProperty =
AvaloniaProperty.Register<CheckBoxIndicator, ITransform?>(nameof (CheckedMarkRenderTransform));
public CheckBoxIndicatorState State
{
@@ -62,6 +65,12 @@ internal class CheckBoxIndicator : TemplatedControl
get => GetValue(TristateMarkSizeProperty);
set => SetValue(TristateMarkSizeProperty, value);
}
public ITransform? CheckedMarkRenderTransform
{
get => GetValue(CheckedMarkRenderTransformProperty);
set => SetValue(CheckedMarkRenderTransformProperty, value);
}
#endregion
@@ -86,8 +95,7 @@ internal class CheckBoxIndicator : TemplatedControl
}
#endregion
private Icon? _checkedMark;
private IDisposable? _borderThicknessDisposable;
private WaveSpiritDecorator? _waveSpiritDecorator;
@@ -124,7 +132,9 @@ internal class CheckBoxIndicator : TemplatedControl
Transitions = [
TransitionUtils.CreateTransition<SolidColorBrushTransition>(BackgroundProperty),
TransitionUtils.CreateTransition<SolidColorBrushTransition>(BorderBrushProperty),
TransitionUtils.CreateTransition<SolidColorBrushTransition>(TristateMarkBrushProperty)
TransitionUtils.CreateTransition<SolidColorBrushTransition>(TristateMarkBrushProperty),
TransitionUtils.CreateTransition<TransformOperationsTransition>(CheckedMarkRenderTransformProperty, SharedTokenKey.MotionDurationMid,
new BackEaseOut())
];
}
}
@@ -133,31 +143,7 @@ internal class CheckBoxIndicator : TemplatedControl
Transitions = null;
}
}
private void ConfigureCheckedMarkTransitions(bool force)
{
if (IsMotionEnabled)
{
if (_checkedMark != null)
{
if (force || _checkedMark.Transitions == null)
{
_checkedMark.Transitions = [
TransitionUtils.CreateTransition<TransformOperationsTransition>(RenderTransformProperty, SharedTokenKey.MotionDurationMid,
new BackEaseOut()),
];
}
}
}
else
{
if (_checkedMark != null)
{
_checkedMark.Transitions = null;
}
}
}
private void UpdatePseudoClasses()
{
PseudoClasses.Set(StdPseudoClass.Checked, State == CheckBoxIndicatorState.Checked);
@@ -187,7 +173,6 @@ internal class CheckBoxIndicator : TemplatedControl
if (e.Property == IsMotionEnabledProperty)
{
ConfigureTransitions(true);
ConfigureCheckedMarkTransitions(true);
}
}
}
@@ -207,26 +192,8 @@ internal class CheckBoxIndicator : TemplatedControl
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
_checkedMark = e.NameScope.Find<Icon>(CheckBoxIndicatorThemeConstants.CheckedMarkPart);
if (_checkedMark != null)
{
_checkedMark.Loaded += HandleCheckedMarkLoaded;
_checkedMark.Unloaded += HandleCheckedMarkUnLoaded;
}
_waveSpiritDecorator = e.NameScope.Find<WaveSpiritDecorator>(CheckBoxIndicatorThemeConstants.WaveSpiritPart);
}
private void HandleCheckedMarkLoaded(object? sender, RoutedEventArgs e)
{
ConfigureCheckedMarkTransitions(false);
}
private void HandleCheckedMarkUnLoaded(object? sender, RoutedEventArgs e)
{
if (_checkedMark != null)
{
_checkedMark.Transitions = null;
}
_waveSpiritDecorator = e.NameScope.Find<WaveSpiritDecorator>(WaveSpiritDecorator.WaveSpiritPart);
}
}
@@ -7,7 +7,7 @@
<Setter Property="Template">
<ControlTemplate>
<Panel>
<atom:WaveSpiritDecorator Name="{x:Static atom:CheckBoxIndicatorThemeConstants.WaveSpiritPart}"
<atom:WaveSpiritDecorator Name="{x:Static atom:WaveSpiritDecorator.WaveSpiritPart}"
CornerRadius="{TemplateBinding CornerRadius}"/>
<Border Name="Frame"
BorderThickness="{TemplateBinding BorderThickness}"
@@ -15,13 +15,15 @@
Background="{TemplateBinding Background}"
CornerRadius="{TemplateBinding CornerRadius}">
<Panel>
<atom:Icon Name="{x:Static atom:CheckBoxIndicatorThemeConstants.CheckedMarkPart}"
<atom:Icon Name="CheckedMark"
IconInfo="{atom:IconInfoProvider CheckBoldOutlined}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
NormalFilledBrush="{TemplateBinding CheckedMarkBrush}"
RenderTransform="{TemplateBinding CheckedMarkRenderTransform}"
RenderTransformOrigin="{x:Static RelativePoint.Center}"
IsVisible="False"/>
<Rectangle Name="{x:Static atom:CheckBoxIndicatorThemeConstants.TristateMarkPart}"
<Rectangle Name="TristateMark"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Fill="{TemplateBinding TristateMarkBrush}"
@@ -39,20 +41,21 @@
<Setter Property="WaveType" Value="RoundRectWave"/>
</Style>
<Style Selector="^ /template/ atom|Icon#PART_CheckedMark">
<Setter Property="CheckedMarkRenderTransform" Value="scale(0.1)"/>
<Style Selector="^ /template/ atom|Icon#CheckedMark">
<Setter Property="Width" Value="{DynamicResource {x:Static atom:CheckBoxTokenKey.CheckedMarkSize}}" />
<Setter Property="Height" Value="{DynamicResource {x:Static atom:CheckBoxTokenKey.CheckedMarkSize}}" />
<Setter Property="RenderTransform" Value="scale(0.1)"/>
</Style>
<Style Selector="^[State=Checked]">
<Style Selector="^ /template/ atom|Icon#PART_CheckedMark">
<Setter Property="CheckedMarkRenderTransform" Value="scale(1.0)"/>
<Style Selector="^ /template/ atom|Icon#CheckedMark">
<Setter Property="IsVisible" Value="True" />
<Setter Property="RenderTransform" Value="scale(1.0)"/>
</Style>
</Style>
<Style Selector="^[State=Indeterminate]">
<Style Selector="^ /template/ Rectangle#PART_TristateMark">
<Style Selector="^ /template/ Rectangle#TristateMark">
<Setter Property="IsVisible" Value="True" />
</Style>
</Style>
@@ -8,7 +8,7 @@
<ControlTheme x:Key="{x:Type atom:CheckBox}" TargetType="atom:CheckBox">
<Setter Property="Template">
<ControlTemplate>
<Border Name="{x:Static atom:CheckBoxThemeConstants.FramePart}"
<Border Name="Frame"
Padding="0, 1, 0, 1">
<DockPanel LastChildFill="True">
<atom:CheckBoxIndicator Name="Indicator"
@@ -17,11 +17,11 @@
IsWaveSpiritEnabled="{TemplateBinding IsWaveSpiritEnabled}"
IsEnabled="{TemplateBinding IsEnabled}"
State="{TemplateBinding IsChecked, Converter={StaticResource CheckBoxIndicatorStateConverter}}" />
<atom:TextBlock Name="{x:Static atom:CheckBoxThemeConstants.LabelTextPart}"
VerticalAlignment="Center"
Text="{TemplateBinding Content}"
FontSize="{TemplateBinding FontSize}"
IsVisible="{TemplateBinding Content, Converter={x:Static ObjectConverters.IsNotNull}}" />
<ContentPresenter Name="ContentPresenter"
VerticalAlignment="Center"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
IsVisible="{TemplateBinding Content, Converter={x:Static ObjectConverters.IsNotNull}}"/>
</DockPanel>
</Border>
</ControlTemplate>
@@ -36,15 +36,14 @@
Value="{DynamicResource {x:Static atom:SharedTokenKey.EnableWaveSpirit}}" />
<Setter Property="IsMotionEnabled" Value="{DynamicResource {x:Static atom:SharedTokenKey.EnableMotion}}" />
<Style Selector="^ /template/ atom|TextBlock#PART_LabelText">
<Style Selector="^ /template/ ContentPresenter#ContentPresenter">
<Setter Property="Margin" Value="{DynamicResource {x:Static atom:CheckBoxTokenKey.TextMargin}}" />
</Style>
<Style Selector="^:disabled">
<Setter Property="Foreground" Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorTextDisabled}}" />
</Style>
<!-- BuildIndicatorStyle 开始 -->
<Style Selector="^ /template/ atom|CheckBoxIndicator#Indicator">
<Setter Property="Width" Value="{DynamicResource {x:Static atom:CheckBoxTokenKey.CheckIndicatorSize}}" />
<Setter Property="Height" Value="{DynamicResource {x:Static atom:CheckBoxTokenKey.CheckIndicatorSize}}" />
@@ -106,7 +105,5 @@
</Style>
</Style>
<!-- BuildIndicatorStyle 结束 -->
</ControlTheme>
</ResourceDictionary>
@@ -1,14 +0,0 @@
namespace AtomUI.Controls.Themes;
internal static class CheckBoxIndicatorThemeConstants
{
public const string CheckedMarkPart = "PART_CheckedMark";
public const string TristateMarkPart = "PART_TristateMark";
public const string WaveSpiritPart = "PART_WaveSpirit";
}
internal static class CheckBoxThemeConstants
{
public const string FramePart = "PART_Frame";
public const string LabelTextPart = "PART_LabelText";
}