diff --git a/src/Ursa.Themes.Semi/Controls/IconButton.axaml b/src/Ursa.Themes.Semi/Controls/IconButton.axaml index accf538..91c12b5 100644 --- a/src/Ursa.Themes.Semi/Controls/IconButton.axaml +++ b/src/Ursa.Themes.Semi/Controls/IconButton.axaml @@ -3,7 +3,16 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:converters="clr-namespace:Ursa.Themes.Semi.Converters" xmlns:u="https://irihi.tech/ursa"> - + + + + + + @@ -31,14 +40,13 @@ TextElement.FontSize="{TemplateBinding FontSize}" TextElement.FontWeight="{TemplateBinding FontWeight}" UseLayoutRounding="False"> - - + Orientation="Horizontal" + Spacing="{StaticResource IconButtonInnerSpacing}"> + @@ -51,7 +59,16 @@ + HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" + Opacity="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=!IsLoading, Converter={StaticResource OpacityConverter}}"> + + + + + + - + @@ -107,67 +122,41 @@ - - - - + - - + - - - - - - + + + + - - + - + \ No newline at end of file diff --git a/src/Ursa.Themes.Semi/Themes/Shared/IconButton.axaml b/src/Ursa.Themes.Semi/Themes/Shared/IconButton.axaml new file mode 100644 index 0000000..48b153b --- /dev/null +++ b/src/Ursa.Themes.Semi/Themes/Shared/IconButton.axaml @@ -0,0 +1,3 @@ + + 8 + \ No newline at end of file diff --git a/src/Ursa.Themes.Semi/Themes/Shared/_index.axaml b/src/Ursa.Themes.Semi/Themes/Shared/_index.axaml index 9d1bb41..9d42c27 100644 --- a/src/Ursa.Themes.Semi/Themes/Shared/_index.axaml +++ b/src/Ursa.Themes.Semi/Themes/Shared/_index.axaml @@ -11,6 +11,7 @@ + diff --git a/src/Ursa/Controls/Buttons/IconButton.cs b/src/Ursa/Controls/Buttons/IconButton.cs index 68b1e26..36c2aeb 100644 --- a/src/Ursa/Controls/Buttons/IconButton.cs +++ b/src/Ursa/Controls/Buttons/IconButton.cs @@ -7,17 +7,22 @@ using Ursa.Common; namespace Ursa.Controls; -[PseudoClasses(PC_Right, PC_Left, PC_Top, PC_Bottom, PC_Empty)] -public class IconButton: Button +[TemplatePart(PART_RootPanel, typeof(Panel))] +[PseudoClasses(PC_Right, PC_Left, PC_Top, PC_Bottom, PC_Empty, PC_EmptyContent)] +public class IconButton : Button { public const string PC_Right = ":right"; public const string PC_Left = ":left"; public const string PC_Top = ":top"; public const string PC_Bottom = ":bottom"; public const string PC_Empty = ":empty"; - - public static readonly StyledProperty IconProperty = AvaloniaProperty.Register( - nameof(Icon)); + public const string PC_EmptyContent = ":empty-content"; + public const string PART_RootPanel = "PART_RootPanel"; + + private Panel? _rootPanel; + + public static readonly StyledProperty IconProperty = + AvaloniaProperty.Register(nameof(Icon)); public object? Icon { @@ -25,8 +30,8 @@ public class IconButton: Button set => SetValue(IconProperty, value); } - public static readonly StyledProperty IconTemplateProperty = AvaloniaProperty.Register( - nameof(IconTemplate)); + public static readonly StyledProperty IconTemplateProperty = + AvaloniaProperty.Register(nameof(IconTemplate)); public IDataTemplate? IconTemplate { @@ -34,8 +39,8 @@ public class IconButton: Button set => SetValue(IconTemplateProperty, value); } - public static readonly StyledProperty IsLoadingProperty = AvaloniaProperty.Register( - nameof(IsLoading)); + public static readonly StyledProperty IsLoadingProperty = + AvaloniaProperty.Register(nameof(IsLoading)); public bool IsLoading { @@ -43,8 +48,8 @@ public class IconButton: Button set => SetValue(IsLoadingProperty, value); } - public static readonly StyledProperty IconPlacementProperty = AvaloniaProperty.Register( - nameof(IconPlacement), defaultValue: Position.Left); + public static readonly StyledProperty IconPlacementProperty = + AvaloniaProperty.Register(nameof(IconPlacement), defaultValue: Position.Left); public Position IconPlacement { @@ -57,16 +62,27 @@ public class IconButton: Button IconPlacementProperty.Changed.AddClassHandler((o, e) => { o.SetPlacement(e.NewValue.Value, o.Icon); + o.InvalidateRootPanel(); }); IconProperty.Changed.AddClassHandler((o, e) => { o.SetPlacement(o.IconPlacement, e.NewValue.Value); }); + ContentProperty.Changed.AddClassHandler((o, e) => o.SetEmptyContent()); + } + + private void InvalidateRootPanel() => _rootPanel?.InvalidateArrange(); + + private void SetEmptyContent() + { + PseudoClasses.Set(PC_EmptyContent, Presenter?.Content is null); } protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { base.OnApplyTemplate(e); + _rootPanel = e.NameScope.Find(PART_RootPanel); + SetEmptyContent(); SetPlacement(IconPlacement, Icon); } @@ -81,6 +97,7 @@ public class IconButton: Button PseudoClasses.Set(PC_Bottom, false); return; } + PseudoClasses.Set(PC_Empty, false); PseudoClasses.Set(PC_Left, placement == Position.Left); PseudoClasses.Set(PC_Right, placement == Position.Right);