Refactor Collapse use axaml theme

This commit is contained in:
CHINBOY
2025-06-13 17:26:08 +08:00
parent 155ab370df
commit 901cd9eecb
10 changed files with 255 additions and 450 deletions
@@ -13,6 +13,7 @@
<ResourceInclude Source="CheckBox/Themes/CheckBoxTheme.axaml" />
<ResourceInclude Source="ComboBox/Themes/ComboBoxThemes.axaml" />
<ResourceInclude Source="Calendar/Themes/CalendarThemes.axaml" />
<ResourceInclude Source="Collapse/Themes/CollapseItemThemes.axaml" />
<ResourceInclude Source="RadioButton/Themes/RadioButtonTheme.axaml" />
<ResourceInclude Source="Pagination/Themes/PaginationThemes.axaml" />
<ResourceInclude Source="ScrollBar/Themes/ScrollBarThemes.axaml" />
+2 -1
View File
@@ -1,4 +1,5 @@
using System.Reactive.Disposables;
using AtomUI.Controls.Themes;
using AtomUI.Data;
using AtomUI.Theme;
using AtomUI.Theme.Data;
@@ -30,7 +31,7 @@ public enum CollapseExpandIconPosition
End
}
[TemplatePart(CollapseTheme.ItemsPresenterPart, typeof(ItemsPresenter))]
[TemplatePart(CollapseThemeConstants.ItemsPresenterPart, typeof(ItemsPresenter))]
public class Collapse : SelectingItemsControl,
IMotionAwareControl,
IControlSharedTokenResourcesHost,
+45 -3
View File
@@ -1,9 +1,12 @@
using System.Diagnostics;
using AtomUI.Controls.Themes;
using AtomUI.Controls.Utils;
using AtomUI.IconPkg;
using AtomUI.IconPkg.AntDesign;
using AtomUI.MotionScene;
using AtomUI.Reflection;
using Avalonia;
using Avalonia.Animation;
using Avalonia.Animation.Easings;
using Avalonia.Automation.Peers;
using Avalonia.Controls;
@@ -233,9 +236,9 @@ public class CollapseItem : HeaderedContentControl,
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
_motionActor = e.NameScope.Find<MotionActorControl>(CollapseItemTheme.ContentMotionActorPart);
_headerDecorator = e.NameScope.Find<Border>(CollapseItemTheme.HeaderDecoratorPart);
_expandButton = e.NameScope.Find<IconButton>(CollapseItemTheme.ExpandButtonPart);
_motionActor = e.NameScope.Find<MotionActorControl>(CollapseItemThemeConstants.ContentMotionActorPart);
_headerDecorator = e.NameScope.Find<Border>(CollapseItemThemeConstants.HeaderDecoratorPart);
_expandButton = e.NameScope.Find<IconButton>(CollapseItemThemeConstants.ExpandButtonPart);
// 必须放在这里,因为依赖 _motionActor 是否设置
_tempAnimationDisabled = true;
@@ -245,6 +248,7 @@ public class CollapseItem : HeaderedContentControl,
{
_expandButton.Click += (sender, args) => { IsSelected = !IsSelected; };
}
ConfigureTransitions();
}
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
@@ -292,6 +296,10 @@ public class CollapseItem : HeaderedContentControl,
SetupDefaultExpandIcon();
}
}
else if (change.Property == IsMotionEnabledProperty)
{
ConfigureTransitions();
}
}
private void HandleSelectedChanged()
@@ -359,4 +367,38 @@ public class CollapseItem : HeaderedContentControl,
return false;
}
private void ConfigureTransitions()
{
if (IsMotionEnabled)
{
if (_headerDecorator != null)
{
_headerDecorator.Transitions ??= new Transitions()
{
TransitionUtils.CreateTransition<ThicknessTransition>(Border.BorderThicknessProperty)
};
}
if (_expandButton != null)
{
_expandButton.Transitions ??= new Transitions()
{
TransitionUtils.CreateTransition<TransformOperationsTransition>(Visual.RenderTransformProperty)
};
}
}
else
{
if (_headerDecorator != null)
{
_headerDecorator.Transitions?.Clear();
}
if (_expandButton != null)
{
_expandButton.Transitions?.Clear();
}
}
}
}
@@ -1,386 +0,0 @@
using AtomUI.Controls.Utils;
using AtomUI.IconPkg;
using AtomUI.MotionScene;
using AtomUI.Theme;
using AtomUI.Theme.Styling;
using AtomUI.Utils;
using Avalonia;
using Avalonia.Animation;
using Avalonia.Controls;
using Avalonia.Controls.Documents;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.Data;
using Avalonia.Data.Converters;
using Avalonia.Input;
using Avalonia.Layout;
using Avalonia.Media;
using Avalonia.Media.Transformation;
using Avalonia.Styling;
namespace AtomUI.Controls;
[ControlThemeProvider]
internal class CollapseItemTheme : BaseControlTheme
{
public const string MainLayoutPart = "PART_MainLayout";
public const string ExpandButtonPart = "PART_ExpandButton";
public const string HeaderPresenterPart = "PART_HeaderPresenter";
public const string HeaderDecoratorPart = "PART_HeaderDecorator";
public const string ContentPresenterPart = "PART_ContentPresenter";
public const string AddOnContentPresenterPart = "PART_AddOnContentPresenter";
public const string ContentMotionActorPart = "PART_ContentMotionActor";
public CollapseItemTheme() : base(typeof(CollapseItem))
{
}
protected override IControlTemplate BuildControlTemplate()
{
return new FuncControlTemplate<CollapseItem>((collapseItem, scope) =>
{
var mainLayout = new DockPanel
{
Name = MainLayoutPart,
LastChildFill = true
};
BuildHeader(collapseItem, mainLayout, scope);
var motionActor = new MotionActorControl
{
Name = ContentMotionActorPart
};
motionActor.SetCurrentValue(Visual.IsVisibleProperty, false);
var contentPresenter = new ContentPresenter
{
Name = ContentPresenterPart
};
motionActor.Child = contentPresenter;
CreateTemplateParentBinding(contentPresenter, ContentPresenter.ContentProperty,
ContentControl.ContentProperty,
BindingMode.Default,
new FuncValueConverter<object?, object?>(
o =>
{
if (o is string str)
{
return new TextBlock
{
Text = str,
VerticalAlignment = VerticalAlignment.Center
};
}
return o;
}));
CreateTemplateParentBinding(contentPresenter, ContentPresenter.ContentTemplateProperty,
ContentControl.ContentTemplateProperty);
CreateTemplateParentBinding(contentPresenter, ContentPresenter.BorderThicknessProperty,
CollapseItem.ContentBorderThicknessProperty);
mainLayout.Children.Add(motionActor);
motionActor.RegisterInNameScope(scope);
contentPresenter.RegisterInNameScope(scope);
return mainLayout;
});
}
private void BuildHeader(CollapseItem collapseItem, DockPanel layout, INameScope scope)
{
var headerDecorator = new Border
{
Name = HeaderDecoratorPart
};
headerDecorator.RegisterInNameScope(scope);
DockPanel.SetDock(headerDecorator, Dock.Top);
CreateTemplateParentBinding(headerDecorator, Border.BorderThicknessProperty,
CollapseItem.HeaderBorderThicknessProperty);
var headerLayout = new Grid
{
ColumnDefinitions = new ColumnDefinitions
{
new(GridLength.Auto),
new(GridLength.Star),
new(GridLength.Auto),
new(GridLength.Auto)
}
};
var expandButton = new IconButton
{
Name = ExpandButtonPart,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
};
expandButton.RegisterInNameScope(scope);
CreateTemplateParentBinding(expandButton, IconButton.IconProperty, CollapseItem.ExpandIconProperty);
CreateTemplateParentBinding(expandButton, Visual.IsVisibleProperty, CollapseItem.IsShowExpandIconProperty);
CreateTemplateParentBinding(expandButton, InputElement.IsEnabledProperty, InputElement.IsEnabledProperty);
headerLayout.Children.Add(expandButton);
var headerPresenter = new ContentPresenter
{
Name = HeaderPresenterPart,
HorizontalAlignment = HorizontalAlignment.Stretch,
HorizontalContentAlignment = HorizontalAlignment.Left,
VerticalContentAlignment = VerticalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
Margin = new Thickness(0, 1, 0, 0)
};
CreateTemplateParentBinding(headerPresenter, ContentPresenter.ContentProperty,
HeaderedContentControl.HeaderProperty);
CreateTemplateParentBinding(headerPresenter, ContentPresenter.ContentTemplateProperty,
HeaderedContentControl.HeaderTemplateProperty);
Grid.SetColumn(headerPresenter, 1);
headerPresenter.RegisterInNameScope(scope);
headerLayout.Children.Add(headerPresenter);
var addContentPresenter = new ContentPresenter
{
Name = AddOnContentPresenterPart,
VerticalAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Left
};
CreateTemplateParentBinding(addContentPresenter, ContentPresenter.ContentProperty,
CollapseItem.AddOnContentProperty);
CreateTemplateParentBinding(addContentPresenter, ContentPresenter.ContentTemplateProperty,
CollapseItem.AddOnContentTemplateProperty);
Grid.SetColumn(addContentPresenter, 2);
headerLayout.Children.Add(addContentPresenter);
headerDecorator.Child = headerLayout;
layout.Children.Add(headerDecorator);
}
protected override void BuildStyles()
{
BuildCommonStyle();
BuildTriggerStyle();
BuildTriggerPositionStyle();
BuildSizeTypeStyle();
BuildSelectedStyle();
BuildBorderlessStyle();
BuildGhostStyle();
BuildDisabledStyle();
BuildAddOnContentStyle();
}
private void BuildCommonStyle()
{
var commonStyle = new Style(selector => selector.Nesting());
commonStyle.Add(CollapseItem.MotionDurationProperty, SharedTokenKey.MotionDurationSlow);
{
var decoratorStyle = new Style(selector => selector.Nesting().Template().Name(HeaderDecoratorPart));
decoratorStyle.Add(Border.BackgroundProperty, CollapseTokenKey.HeaderBg);
decoratorStyle.Add(Border.BorderBrushProperty, SharedTokenKey.ColorBorder);
commonStyle.Add(decoratorStyle);
}
var contentPresenterStyle = new Style(selector => selector.Nesting().Template().Name(ContentPresenterPart));
contentPresenterStyle.Add(ContentPresenter.BorderBrushProperty, SharedTokenKey.ColorBorder);
commonStyle.Add(contentPresenterStyle);
var headerPresenter = new Style(selector => selector.Nesting().Template().Name(HeaderPresenterPart));
headerPresenter.Add(ContentPresenter.ForegroundProperty, SharedTokenKey.ColorTextHeading);
commonStyle.Add(headerPresenter);
{
// ExpandIcon
var expandButtonStyle =
new Style(selector => selector.Nesting().Template().Name(ExpandButtonPart));
expandButtonStyle.Add(IconButton.IconWidthProperty, SharedTokenKey.IconSizeSM);
expandButtonStyle.Add(IconButton.IconHeightProperty, SharedTokenKey.IconSizeSM);
expandButtonStyle.Add(IconButton.DisabledIconBrushProperty, SharedTokenKey.ColorTextDisabled);
commonStyle.Add(expandButtonStyle);
}
// 动画相关
var isMotionEnabledStyle = new Style(selector => selector.Nesting().PropertyEquals(CollapseItem.IsMotionEnabledProperty, true));
{
var decoratorStyle = new Style(selector => selector.Nesting().Template().Name(HeaderDecoratorPart));
decoratorStyle.Add(Border.TransitionsProperty, new SetterValueFactory<Transitions>(() => new Transitions
{
TransitionUtils.CreateTransition<ThicknessTransition>(Border.BorderThicknessProperty)
}));
isMotionEnabledStyle.Add(decoratorStyle);
var expandButtonStyle =
new Style(selector => selector.Nesting().Template().Name(ExpandButtonPart));
expandButtonStyle.Add(IconButton.TransitionsProperty, new SetterValueFactory<Transitions>(() => new Transitions()
{
TransitionUtils.CreateTransition<TransformOperationsTransition>(Visual.RenderTransformProperty)
}));
isMotionEnabledStyle.Add(expandButtonStyle);
}
commonStyle.Add(isMotionEnabledStyle);
Add(commonStyle);
}
private void BuildSelectedStyle()
{
var selectedStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Selected));
// Expand Button
var expandButtonStyle = new Style(selector => selector.Nesting().Template().Name(ExpandButtonPart));
expandButtonStyle.Add(Visual.RenderTransformProperty, new SetterValueFactory<ITransform>(() =>
{
var transformOptions = new TransformOperations.Builder(1);
transformOptions.AppendRotate(MathUtils.Deg2Rad(90));
return transformOptions.Build();
}));
selectedStyle.Add(expandButtonStyle);
Add(selectedStyle);
}
private void BuildSizeTypeStyle()
{
var largeSizeStyle =
new Style(selector => selector.Nesting().PropertyEquals(CollapseItem.SizeTypeProperty, SizeType.Large));
{
var decoratorStyle = new Style(selector => selector.Nesting().Template().Name(HeaderDecoratorPart));
decoratorStyle.Add(Decorator.PaddingProperty, CollapseTokenKey.CollapseHeaderPaddingLG);
decoratorStyle.Add(TextElement.FontSizeProperty, SharedTokenKey.FontSizeLG);
decoratorStyle.Add(TextBlock.LineHeightProperty, SharedTokenKey.FontHeightLG);
largeSizeStyle.Add(decoratorStyle);
}
{
var contentPresenterStyle = new Style(selector => selector.Nesting().Template().Name(ContentPresenterPart));
contentPresenterStyle.Add(ContentPresenter.PaddingProperty,
CollapseTokenKey.CollapseContentPaddingLG);
largeSizeStyle.Add(contentPresenterStyle);
}
Add(largeSizeStyle);
var middleSizeStyle =
new Style(selector => selector.Nesting().PropertyEquals(CollapseItem.SizeTypeProperty, SizeType.Middle));
{
var decoratorStyle = new Style(selector => selector.Nesting().Template().Name(HeaderDecoratorPart));
decoratorStyle.Add(Decorator.PaddingProperty, CollapseTokenKey.HeaderPadding);
decoratorStyle.Add(TextElement.FontSizeProperty, SharedTokenKey.FontSize);
decoratorStyle.Add(TextBlock.LineHeightProperty, SharedTokenKey.FontHeight);
middleSizeStyle.Add(decoratorStyle);
}
{
var contentPresenterStyle = new Style(selector => selector.Nesting().Template().Name(ContentPresenterPart));
contentPresenterStyle.Add(ContentPresenter.PaddingProperty, CollapseTokenKey.ContentPadding);
middleSizeStyle.Add(contentPresenterStyle);
}
Add(middleSizeStyle);
var smallSizeStyle =
new Style(selector => selector.Nesting().PropertyEquals(CollapseItem.SizeTypeProperty, SizeType.Small));
{
var decoratorStyle = new Style(selector => selector.Nesting().Template().Name(HeaderDecoratorPart));
decoratorStyle.Add(Decorator.PaddingProperty, CollapseTokenKey.CollapseHeaderPaddingSM);
decoratorStyle.Add(TextElement.FontSizeProperty, SharedTokenKey.FontSize);
decoratorStyle.Add(TextBlock.LineHeightProperty, SharedTokenKey.FontHeight);
smallSizeStyle.Add(decoratorStyle);
}
{
var contentPresenterStyle = new Style(selector => selector.Nesting().Template().Name(ContentPresenterPart));
contentPresenterStyle.Add(ContentPresenter.PaddingProperty,
CollapseTokenKey.CollapseContentPaddingSM);
smallSizeStyle.Add(contentPresenterStyle);
}
Add(smallSizeStyle);
}
private void BuildTriggerStyle()
{
var headerTriggerHandleStyle = new Style(selector => selector.Nesting()
.PropertyEquals(
CollapseItem.TriggerTypeProperty,
CollapseTriggerType.Header));
var headerDecoratorStyle = new Style(selector => selector.Nesting().Template().Name(HeaderDecoratorPart));
headerDecoratorStyle.Add(InputElement.CursorProperty, new SetterValueFactory<Cursor>(() => new Cursor(StandardCursorType.Hand)));
headerTriggerHandleStyle.Add(headerDecoratorStyle);
Add(headerTriggerHandleStyle);
var iconTriggerHandleStyle =
new Style(selector => selector.Nesting()
.PropertyEquals(CollapseItem.TriggerTypeProperty, CollapseTriggerType.Icon));
var expandButtonStyle = new Style(selector => selector.Nesting().Template().Name(ExpandButtonPart));
expandButtonStyle.Add(InputElement.CursorProperty, new SetterValueFactory<Cursor>(() => new Cursor(StandardCursorType.Hand)));
iconTriggerHandleStyle.Add(expandButtonStyle);
Add(iconTriggerHandleStyle);
}
private void BuildTriggerPositionStyle()
{
var startPositionStyle = new Style(selector => selector.Nesting()
.PropertyEquals(
CollapseItem.ExpandIconPositionProperty,
CollapseExpandIconPosition.Start));
{
var expandButtonStyle = new Style(selector => selector.Nesting().Template().Name(ExpandButtonPart));
expandButtonStyle.Add(Grid.ColumnProperty, 0);
expandButtonStyle.Add(Layoutable.MarginProperty, CollapseTokenKey.LeftExpandButtonMargin);
startPositionStyle.Add(expandButtonStyle);
}
Add(startPositionStyle);
var endPositionStyle = new Style(selector => selector.Nesting()
.PropertyEquals(
CollapseItem.ExpandIconPositionProperty,
CollapseExpandIconPosition.End));
{
var expandButtonStyle = new Style(selector => selector.Nesting().Template().Name(ExpandButtonPart));
expandButtonStyle.Add(Grid.ColumnProperty, 3);
expandButtonStyle.Add(Layoutable.MarginProperty, CollapseTokenKey.RightExpandButtonMargin);
endPositionStyle.Add(expandButtonStyle);
}
Add(endPositionStyle);
}
private void BuildBorderlessStyle()
{
var borderlessStyle =
new Style(selector => selector.Nesting().PropertyEquals(CollapseItem.IsBorderlessProperty, true));
var contentPresenterStyle = new Style(selector => selector.Nesting().Template().Name(ContentPresenterPart));
contentPresenterStyle.Add(ContentPresenter.BackgroundProperty, CollapseTokenKey.HeaderBg);
borderlessStyle.Add(contentPresenterStyle);
Add(borderlessStyle);
}
private void BuildGhostStyle()
{
var ghostStyle =
new Style(selector => selector.Nesting().PropertyEquals(CollapseItem.IsGhostStyleProperty, true));
var decoratorStyle = new Style(selector => selector.Nesting().Template().Name(HeaderDecoratorPart));
decoratorStyle.Add(Border.BackgroundProperty, CollapseTokenKey.ContentBg);
ghostStyle.Add(decoratorStyle);
Add(ghostStyle);
}
private void BuildDisabledStyle()
{
var disabledStyle =
new Style(selector => selector.Nesting().Class(StdPseudoClass.Disabled));
disabledStyle.Add(TemplatedControl.ForegroundProperty, SharedTokenKey.ColorTextDisabled);
var headerContentPresenterStyle = new Style(selector => selector.Nesting().Template().Name(HeaderDecoratorPart)
.Descendant().OfType<ContentPresenter>());
headerContentPresenterStyle.Add(ContentPresenter.ForegroundProperty, SharedTokenKey.ColorTextDisabled);
disabledStyle.Add(headerContentPresenterStyle);
Add(disabledStyle);
}
private void BuildAddOnContentStyle()
{
var addOnContentStyle = new Style(selector => selector.Nesting().Template().Name(AddOnContentPresenterPart)
.Descendant().OfType<Icon>());
addOnContentStyle.Add(Layoutable.WidthProperty, SharedTokenKey.IconSize);
addOnContentStyle.Add(Layoutable.HeightProperty, SharedTokenKey.IconSize);
Add(addOnContentStyle);
}
}
@@ -1,58 +0,0 @@
using AtomUI.Theme;
using AtomUI.Theme.Styling;
using Avalonia.Controls;
using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.Styling;
namespace AtomUI.Controls;
[ControlThemeProvider]
internal class CollapseTheme : BaseControlTheme
{
public const string FramePart = "PART_Frame";
public const string ItemsPresenterPart = "PART_ItemsPresenter";
public CollapseTheme() : base(typeof(Collapse))
{
}
protected override IControlTemplate BuildControlTemplate()
{
return new FuncControlTemplate<Collapse>((collapse, scope) =>
{
var frame = new Border
{
Name = FramePart,
ClipToBounds = true
};
var itemsPresenter = new ItemsPresenter
{
Name = ItemsPresenterPart
};
itemsPresenter.RegisterInNameScope(scope);
frame.Child = itemsPresenter;
CreateTemplateParentBinding(itemsPresenter, ItemsPresenter.ItemsPanelProperty,
ItemsControl.ItemsPanelProperty);
CreateTemplateParentBinding(frame, Border.BorderThicknessProperty,
Collapse.EffectiveBorderThicknessProperty);
CreateTemplateParentBinding(frame, Border.BorderBrushProperty,
TemplatedControl.BorderBrushProperty);
CreateTemplateParentBinding(frame, Border.CornerRadiusProperty,
TemplatedControl.CornerRadiusProperty);
return frame;
});
}
protected override void BuildStyles()
{
var commonStyle = new Style(selector => selector.Nesting());
commonStyle.Add(TemplatedControl.BorderBrushProperty, SharedTokenKey.ColorBorder);
commonStyle.Add(TemplatedControl.CornerRadiusProperty, CollapseTokenKey.CollapsePanelBorderRadius);
Add(commonStyle);
}
}
@@ -0,0 +1,159 @@
<ResourceDictionary
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:atom="https://atomui.net">
<atom:StringToTextBlockConverter x:Key="StringToTextBlockConverter" VerticalAlignment="Center" />
<ControlTheme x:Key="{x:Type atom:CollapseItem}" TargetType="atom:CollapseItem">
<Setter Property="Template">
<ControlTemplate>
<DockPanel Name="{x:Static atom:CollapseItemThemeConstants.MainLayoutPart}"
LastChildFill="True">
<Border Name="{x:Static atom:CollapseItemThemeConstants.HeaderDecoratorPart}"
DockPanel.Dock="Top"
BorderThickness="{TemplateBinding HeaderBorderThickness}">
<Grid ColumnDefinitions="Auto, *, Auto, Auto">
<atom:IconButton
Name="{x:Static atom:CollapseItemThemeConstants.ExpandButtonPart}"
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Icon="{TemplateBinding ExpandIcon}"
IsVisible="{TemplateBinding IsShowExpandIcon}"
IsEnabled="{TemplateBinding IsEnabled}" />
<ContentPresenter Name="{x:Static atom:CollapseItemThemeConstants.HeaderPresenterPart}"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Center"
Margin="0, 1, 0, 0"
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}"
Grid.Column="1" />
<ContentPresenter
Name="{x:Static atom:CollapseItemThemeConstants.AddOnContentPresenterPart}"
HorizontalAlignment="Left"
VerticalAlignment="Center"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Center"
Content="{TemplateBinding AddOnContent}"
ContentTemplate="{TemplateBinding AddOnContentTemplate}"
Grid.Column="2" />
</Grid>
</Border>
<atom:MotionActorControl Name="{x:Static atom:CollapseItemThemeConstants.ContentMotionActorPart}">
<ContentPresenter Name="{x:Static atom:CollapseItemThemeConstants.ContentPresenterPart}"
Content="{TemplateBinding Content, Converter={StaticResource StringToTextBlockConverter}}"
ContentTemplate="{TemplateBinding ContentTemplate}"
BorderThickness="{TemplateBinding ContentBorderThickness}" />
</atom:MotionActorControl>
</DockPanel>
</ControlTemplate>
</Setter>
<Setter Property="MotionDuration" Value="{DynamicResource {x:Static atom:SharedTokenKey.MotionDurationSlow}}" />
<Style Selector="^ /template/ Border#PART_HeaderDecorator">
<Setter Property="Background" Value="{DynamicResource {x:Static atom:CollapseTokenKey.HeaderBg}}" />
<Setter Property="BorderBrush" Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorBorder}}" />
</Style>
<Style Selector="^ /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="BorderBrush" Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorBorder}}" />
</Style>
<Style Selector="^ /template/ ContentPresenter#PART_HeaderPresenter">
<Setter Property="Foreground" Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorTextHeading}}" />
</Style>
<Style Selector="^ /template/ atom|IconButton#PART_ExpandButton">
<Setter Property="IconWidth" Value="{DynamicResource {x:Static atom:SharedTokenKey.IconSizeSM}}" />
<Setter Property="IconHeight" Value="{DynamicResource {x:Static atom:SharedTokenKey.IconSizeSM}}" />
<Setter Property="DisabledIconBrush" Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorTextDisabled}}" />
</Style>
<Style Selector="^:selected">
<Style Selector="^ /template/ atom|IconButton#PART_ExpandButton">
<Setter Property="RenderTransform" Value="rotate(90deg)" />
</Style>
</Style>
<Style Selector="^[SizeType=Large]">
<Style Selector="^ /template/ Border#PART_HeaderDecorator">
<Setter Property="Padding" Value="{DynamicResource {x:Static atom:CollapseTokenKey.CollapseHeaderPaddingLG}}" />
<Setter Property="TextElement.FontSize" Value="{DynamicResource {x:Static atom:SharedTokenKey.FontSizeLG}}" />
<Setter Property="TextBlock.LineHeight" Value="{DynamicResource {x:Static atom:SharedTokenKey.FontHeightLG}}" />
</Style>
<Style Selector="^ /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Padding" Value="{DynamicResource {x:Static atom:CollapseTokenKey.CollapseContentPaddingLG}}" />
</Style>
</Style>
<Style Selector="^[SizeType=Middle]">
<Style Selector="^ /template/ Border#PART_HeaderDecorator">
<Setter Property="Padding" Value="{DynamicResource {x:Static atom:CollapseTokenKey.HeaderPadding}}" />
<Setter Property="TextElement.FontSize" Value="{DynamicResource {x:Static atom:SharedTokenKey.FontSize}}" />
<Setter Property="TextBlock.LineHeight" Value="{DynamicResource {x:Static atom:SharedTokenKey.FontHeight}}" />
</Style>
<Style Selector="^ /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Padding" Value="{DynamicResource {x:Static atom:CollapseTokenKey.ContentPadding}}" />
</Style>
</Style>
<Style Selector="^[SizeType=Small]">
<Style Selector="^ /template/ Border#PART_HeaderDecorator">
<Setter Property="Padding" Value="{DynamicResource {x:Static atom:CollapseTokenKey.CollapseHeaderPaddingSM}}" />
<Setter Property="TextElement.FontSize" Value="{DynamicResource {x:Static atom:SharedTokenKey.FontSize}}" />
<Setter Property="TextBlock.LineHeight" Value="{DynamicResource {x:Static atom:SharedTokenKey.FontHeight}}" />
</Style>
<Style Selector="^ /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Padding" Value="{DynamicResource {x:Static atom:CollapseTokenKey.CollapseContentPaddingSM}}" />
</Style>
</Style>
<Style Selector="^[TriggerType=Header]">
<Style Selector="^ /template/ Border#PART_HeaderDecorator">
<Setter Property="Cursor" Value="Hand" />
</Style>
</Style>
<Style Selector="^[TriggerType=Icon]">
<Style Selector="^ /template/ atom|IconButton#PART_ExpandButton">
<Setter Property="Cursor" Value="Hand" />
</Style>
</Style>
<Style Selector="^[ExpandIconPosition=Start]">
<Style Selector="^ /template/ atom|IconButton#PART_ExpandButton">
<Setter Property="Grid.Column" Value="0" />
<Setter Property="Margin" Value="{DynamicResource {x:Static atom:CollapseTokenKey.LeftExpandButtonMargin}}" />
</Style>
</Style>
<Style Selector="^[ExpandIconPosition=End]">
<Style Selector="^ /template/ atom|IconButton#PART_ExpandButton">
<Setter Property="Grid.Column" Value="3" />
<Setter Property="Margin" Value="{DynamicResource {x:Static atom:CollapseTokenKey.RightExpandButtonMargin}}" />
</Style>
</Style>
<Style Selector="^[IsBorderless=True]">
<Style Selector="^ /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Background" Value="{DynamicResource {x:Static atom:CollapseTokenKey.HeaderBg}}" />
</Style>
</Style>
<Style Selector="^[IsGhostStyle=True]">
<Style Selector="^ /template/ Border#PART_HeaderDecorator">
<Setter Property="Background" Value="{DynamicResource {x:Static atom:CollapseTokenKey.ContentBg}}" />
</Style>
</Style>
<Style Selector="^:disabled">
<Setter Property="Foreground" Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorTextDisabled}}" />
<Style Selector="^ /template/ Border#PART_HeaderDecorator ContentPresenter">
<Setter Property="Foreground" Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorTextDisabled}}" />
</Style>
</Style>
</ControlTheme>
</ResourceDictionary>
@@ -0,0 +1,7 @@
<ResourceDictionary xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceInclude Source="CollapseItemTheme.axaml"/>
<ResourceInclude Source="CollapseTheme.axaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
@@ -0,0 +1,22 @@
<ResourceDictionary
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:atom="https://atomui.net">
<ControlTheme x:Key="{x:Type atom:Collapse}" TargetType="atom:Collapse">
<Setter Property="Template">
<ControlTemplate>
<Border Name="{x:Static atom:CollapseThemeConstants.FramePart}"
BorderThickness="{TemplateBinding EffectiveBorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
CornerRadius="{TemplateBinding CornerRadius}"
ClipToBounds="True">
<ItemsPresenter Name="{x:Static atom:CollapseThemeConstants.ItemsPresenterPart}"
ItemsPanel="{TemplateBinding ItemsPanel}"/>
</Border>
</ControlTemplate>
</Setter>
<Setter Property="BorderBrush" Value="{DynamicResource {x:Static atom:SharedTokenKey.ColorBorder}}" />
<Setter Property="CornerRadius" Value="{DynamicResource {x:Static atom:CollapseTokenKey.CollapsePanelBorderRadius}}" />
</ControlTheme>
</ResourceDictionary>
@@ -0,0 +1,19 @@
namespace AtomUI.Controls.Themes;
internal static class CollapseThemeConstants
{
public const string FramePart = "PART_Frame";
public const string ItemsPresenterPart = "PART_ItemsPresenter";
}
internal static class CollapseItemThemeConstants
{
public const string MainLayoutPart = "PART_MainLayout";
public const string ExpandButtonPart = "PART_ExpandButton";
public const string HeaderPresenterPart = "PART_HeaderPresenter";
public const string HeaderDecoratorPart = "PART_HeaderDecorator";
public const string ContentPresenterPart = "PART_ContentPresenter";
public const string AddOnContentPresenterPart = "PART_AddOnContentPresenter";
public const string ContentMotionActorPart = "PART_ContentMotionActor";
}
@@ -22,8 +22,6 @@ namespace AtomUI.Theme
themes.Add(new AtomUI.Controls.CardTabStripItemTheme());
themes.Add(new AtomUI.Controls.CardTabStripTheme());
themes.Add(new AtomUI.Controls.CircleProgressTheme());
themes.Add(new AtomUI.Controls.CollapseItemTheme());
themes.Add(new AtomUI.Controls.CollapseTheme());
themes.Add(new AtomUI.Controls.ContextMenuTheme());
themes.Add(new AtomUI.Controls.DashboardProgressTheme());
themes.Add(new AtomUI.Controls.DatePickerFlyoutPresenterTheme());