feat: support top and bottom icon button.

This commit is contained in:
rabbitism
2024-01-27 15:09:38 +08:00
parent cfbf58e9aa
commit b46eb8c456
5 changed files with 97 additions and 37 deletions

View File

@@ -1,8 +1,10 @@
<ResourceDictionary
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="clr-namespace:Ursa.Themes.Semi.Converters"
xmlns:u="https://irihi.tech/ursa">
<!-- Add Resources Here -->
<converters:BooleansToOpacityConverter x:Key="OpacityConverter" />
<ControlTheme x:Key="{x:Type u:IconButton}" TargetType="u:IconButton">
<Setter Property="Background" Value="{DynamicResource ButtonDefaultBackground}" />
<Setter Property="Foreground" Value="{DynamicResource ButtonDefaultPrimaryForeground}" />
@@ -32,7 +34,8 @@
<Grid
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
ColumnDefinitions="Auto, Auto">
ColumnDefinitions="Auto, Auto"
RowDefinitions="Auto, Auto">
<Panel
Name="PART_IconRoot"
Grid.Column="0"
@@ -49,7 +52,7 @@
<ContentPresenter
Content="{TemplateBinding Icon}"
ContentTemplate="{TemplateBinding IconTemplate}"
IsVisible="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=!IsLoading}" />
Opacity="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=!IsLoading, Converter={StaticResource OpacityConverter}}" />
<u:LoadingIcon
Classes="Small"
Foreground="{TemplateBinding Foreground}"
@@ -58,6 +61,8 @@
<ContentPresenter
Name="PART_ContentPresenter"
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="{TemplateBinding Content}" />
</Grid>
</Border>
@@ -106,10 +111,48 @@
<Style Selector="^:right">
<Style Selector="^ /template/ Panel#PART_IconRoot">
<Setter Property="Grid.Column" Value="1" />
<Setter Property="Grid.Row" Value="0" />
<Setter Property="Margin" Value="8 0 0 0" />
</Style>
<Style Selector="^ /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Grid.Column" Value="0" />
<Setter Property="Grid.Row" Value="0" />
</Style>
</Style>
<Style Selector="^:left">
<Style Selector="^ /template/ Panel#PART_IconRoot">
<Setter Property="Grid.Column" Value="0" />
<Setter Property="Grid.Row" Value="0" />
<Setter Property="Margin" Value="0 0 8 0" />
</Style>
<Style Selector="^ /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Grid.Column" Value="1" />
<Setter Property="Grid.Row" Value="0" />
</Style>
</Style>
<Style Selector="^:top">
<Style Selector="^ /template/ Panel#PART_IconRoot">
<Setter Property="Grid.Column" Value="0" />
<Setter Property="Grid.Row" Value="0" />
<Setter Property="Margin" Value="0 0 0 4" />
</Style>
<Style Selector="^ /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Grid.Column" Value="0" />
<Setter Property="Grid.Row" Value="1" />
</Style>
</Style>
<Style Selector="^:bottom">
<Style Selector="^ /template/ Panel#PART_IconRoot">
<Setter Property="Grid.Column" Value="0" />
<Setter Property="Grid.Row" Value="1" />
<Setter Property="Margin" Value="0 4 0 0" />
</Style>
<Style Selector="^ /template/ ContentPresenter#PART_ContentPresenter">
<Setter Property="Grid.Column" Value="0" />
<Setter Property="Grid.Row" Value="0" />
</Style>
</Style>

View File

@@ -0,0 +1,21 @@
using System.Globalization;
using Avalonia.Data.Converters;
namespace Ursa.Themes.Semi.Converters;
public class BooleansToOpacityConverter: IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is bool b)
{
return b? 1.0: 0.0;
}
return 1;
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

View File

@@ -3,5 +3,7 @@
public enum IconPlacement
{
Left,
Top,
Right,
Bottom,
}

View File

@@ -3,14 +3,18 @@ using Avalonia.Controls;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates;
using Avalonia.Layout;
using Ursa.Common;
namespace Ursa.Controls;
[PseudoClasses(PC_Right)]
[PseudoClasses(PC_Right, PC_Left, PC_Top, PC_Bottom)]
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 static readonly StyledProperty<object?> IconProperty = AvaloniaProperty.Register<IconButton, object?>(
nameof(Icon));
@@ -64,6 +68,9 @@ public class IconButton: Button
private void SetPlacement(IconPlacement placement)
{
PseudoClasses.Set(PC_Left, placement == IconPlacement.Left);
PseudoClasses.Set(PC_Right, placement == IconPlacement.Right);
PseudoClasses.Set(PC_Top, placement == IconPlacement.Top);
PseudoClasses.Set(PC_Bottom, placement == IconPlacement.Bottom);
}
}