chore: Add SplitButton styles and demo.
This commit is contained in:
1 parent
3577b46e52
commit
fffb4d9902
5 files changed
+343
No files matched your search
@@ -6,6 +6,7 @@
|
||||
"demoItemList": [
|
||||
[ "Brush", "BrushDemo", "Brush.Brush", "", "" ],
|
||||
[ "Button", "ButtonDemo", "Brush.ButtonClick", "", "" ],
|
||||
[ "SplitButton", "SplitButtonDemo", "Brush.ButtonClick", "", "" ],
|
||||
[ "RepeatButton", "RepeatButtonDemo", "Brush.RepeatButton", "", "" ],
|
||||
[ "ToggleButton", "ToggleButtonDemo", "Brush.Toggle", "", "" ],
|
||||
[ "ToggleSwitch", "ToggleSwitchDemo", "Brush.Toggle", "", "" ],
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||
x:Class="HandyControlDemo.UserControl.SplitButtonDemo"
|
||||
Background="{DynamicResource RegionBrush}">
|
||||
<ScrollViewer>
|
||||
<hc:UniformSpacingPanel ChildWrapping="Wrap"
|
||||
Spacing="32"
|
||||
Margin="32">
|
||||
<hc:UniformSpacingPanel Orientation="Vertical"
|
||||
Spacing="16">
|
||||
<TextBlock Text="SplitButton (Default)"
|
||||
Theme="{StaticResource TextBlockSubTitleBold}" />
|
||||
<WrapPanel>
|
||||
<SplitButton Content="Default"
|
||||
Margin="5">
|
||||
<SplitButton.Flyout>
|
||||
<MenuFlyout>
|
||||
<MenuItem Header="Item 1" />
|
||||
<MenuItem Header="Item 2" />
|
||||
<MenuItem Header="Item 3" />
|
||||
</MenuFlyout>
|
||||
</SplitButton.Flyout>
|
||||
</SplitButton>
|
||||
<SplitButton Content="Disabled"
|
||||
IsEnabled="False"
|
||||
Margin="5" />
|
||||
<SplitButton Content="Calendar"
|
||||
Margin="5"
|
||||
hc:IconElement.Geometry="{StaticResource CalendarGeometry}">
|
||||
<SplitButton.Flyout>
|
||||
<MenuFlyout>
|
||||
<MenuItem Header="Today" />
|
||||
<MenuItem Header="Tomorrow" />
|
||||
</MenuFlyout>
|
||||
</SplitButton.Flyout>
|
||||
</SplitButton>
|
||||
</WrapPanel>
|
||||
|
||||
<TextBlock Text="SplitButton.Small"
|
||||
Theme="{StaticResource TextBlockSubTitleBold}" />
|
||||
<WrapPanel>
|
||||
<SplitButton Content="Default"
|
||||
Margin="5"
|
||||
Theme="{StaticResource SplitButton.Small}">
|
||||
<SplitButton.Flyout>
|
||||
<MenuFlyout>
|
||||
<MenuItem Header="Item 1" />
|
||||
<MenuItem Header="Item 2" />
|
||||
</MenuFlyout>
|
||||
</SplitButton.Flyout>
|
||||
</SplitButton>
|
||||
<SplitButton Content="Disabled"
|
||||
IsEnabled="False"
|
||||
Margin="5"
|
||||
Theme="{StaticResource SplitButton.Small}" />
|
||||
<SplitButton Content="Clock"
|
||||
Margin="5"
|
||||
hc:IconElement.Geometry="{StaticResource ClockGeometry}"
|
||||
Theme="{StaticResource SplitButton.Small}">
|
||||
<SplitButton.Flyout>
|
||||
<MenuFlyout>
|
||||
<MenuItem Header="Now" />
|
||||
<MenuItem Header="Later" />
|
||||
</MenuFlyout>
|
||||
</SplitButton.Flyout>
|
||||
</SplitButton>
|
||||
</WrapPanel>
|
||||
</hc:UniformSpacingPanel>
|
||||
|
||||
<hc:UniformSpacingPanel Orientation="Vertical"
|
||||
Spacing="16">
|
||||
<TextBlock Text="ToggleSplitButton"
|
||||
Theme="{StaticResource TextBlockSubTitleBold}" />
|
||||
<WrapPanel>
|
||||
<ToggleSplitButton Content="Toggle"
|
||||
Margin="5">
|
||||
<ToggleSplitButton.Flyout>
|
||||
<MenuFlyout>
|
||||
<MenuItem Header="Option A" />
|
||||
<MenuItem Header="Option B" />
|
||||
</MenuFlyout>
|
||||
</ToggleSplitButton.Flyout>
|
||||
</ToggleSplitButton>
|
||||
<ToggleSplitButton Content="Checked"
|
||||
IsChecked="True"
|
||||
Margin="5">
|
||||
<ToggleSplitButton.Flyout>
|
||||
<MenuFlyout>
|
||||
<MenuItem Header="Option A" />
|
||||
<MenuItem Header="Option B" />
|
||||
</MenuFlyout>
|
||||
</ToggleSplitButton.Flyout>
|
||||
</ToggleSplitButton>
|
||||
<ToggleSplitButton Content="Disabled"
|
||||
IsEnabled="False"
|
||||
Margin="5" />
|
||||
</WrapPanel>
|
||||
|
||||
<TextBlock Text="ToggleSplitButton.Small"
|
||||
Theme="{StaticResource TextBlockSubTitleBold}" />
|
||||
<WrapPanel>
|
||||
<ToggleSplitButton Content="Toggle"
|
||||
Margin="5"
|
||||
Theme="{StaticResource ToggleSplitButton.Small}">
|
||||
<ToggleSplitButton.Flyout>
|
||||
<MenuFlyout>
|
||||
<MenuItem Header="Option A" />
|
||||
<MenuItem Header="Option B" />
|
||||
</MenuFlyout>
|
||||
</ToggleSplitButton.Flyout>
|
||||
</ToggleSplitButton>
|
||||
<ToggleSplitButton Content="Checked"
|
||||
IsChecked="True"
|
||||
Margin="5"
|
||||
Theme="{StaticResource ToggleSplitButton.Small}" />
|
||||
<ToggleSplitButton Content="Disabled"
|
||||
IsEnabled="False"
|
||||
Margin="5"
|
||||
Theme="{StaticResource ToggleSplitButton.Small}" />
|
||||
</WrapPanel>
|
||||
</hc:UniformSpacingPanel>
|
||||
</hc:UniformSpacingPanel>
|
||||
</ScrollViewer>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace HandyControlDemo.UserControl;
|
||||
|
||||
public partial class SplitButtonDemo : Avalonia.Controls.UserControl
|
||||
{
|
||||
public SplitButtonDemo()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@
|
||||
<MergeResourceInclude Source="avares://HandyControl/Themes/Styles/UserControl.axaml" />
|
||||
<MergeResourceInclude Source="avares://HandyControl/Themes/Styles/Window.axaml" />
|
||||
<MergeResourceInclude Source="avares://HandyControl/Themes/Styles/Button.axaml" />
|
||||
<MergeResourceInclude Source="avares://HandyControl/Themes/Styles/SplitButton.axaml" />
|
||||
<MergeResourceInclude Source="avares://HandyControl/Themes/Styles/HyperlinkButton.axaml" />
|
||||
<MergeResourceInclude Source="avares://HandyControl/Themes/Styles/RepeatButton.axaml" />
|
||||
<MergeResourceInclude Source="avares://HandyControl/Themes/Styles/ToggleButton.axaml" />
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
<ResourceDictionary xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
x:ClassModifier="internal"
|
||||
xmlns:hc="clr-namespace:HandyControl.Controls">
|
||||
|
||||
<!-- Inner button theme used by SplitButton's PART_PrimaryButton / PART_SecondaryButton.
|
||||
Reacts to its own pointer/pressed states; outer SplitButton can also overlay state via Tag. -->
|
||||
<ControlTheme x:Key="SplitButtonComponent"
|
||||
TargetType="Button">
|
||||
<Setter Property="HorizontalContentAlignment"
|
||||
Value="Center" />
|
||||
<Setter Property="VerticalContentAlignment"
|
||||
Value="Center" />
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate>
|
||||
<Border x:Name="border"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
CornerRadius="{TemplateBinding CornerRadius}">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
Margin="{TemplateBinding Padding}">
|
||||
<Path Width="{TemplateBinding hc:IconElement.Width}"
|
||||
Height="{TemplateBinding hc:IconElement.Height}"
|
||||
Fill="{TemplateBinding Foreground}"
|
||||
IsVisible="{Binding Path=(hc:IconElement.Geometry), RelativeSource={RelativeSource TemplatedParent}, Converter={x:Static ObjectConverters.IsNotNull}}"
|
||||
Stretch="Uniform"
|
||||
Data="{TemplateBinding hc:IconElement.Geometry}" />
|
||||
<ContentPresenter RecognizesAccessKey="True"
|
||||
VerticalAlignment="Center"
|
||||
Content="{TemplateBinding Content}"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
IsVisible="{Binding $self.Content, Converter={x:Static ObjectConverters.IsNotNull}}"
|
||||
Margin="{Binding Path=(hc:IconElement.Geometry), RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource GeometrySpacingConverter}, ConverterParameter='6,0,0,0'}" />
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
|
||||
<Style Selector="^:pointerover /template/ Border#border">
|
||||
<Setter Property="Background"
|
||||
Value="{DynamicResource SecondaryRegionBrush}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^:pressed /template/ Border#border">
|
||||
<Setter Property="Background"
|
||||
Value="{DynamicResource BorderBrush}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[Tag=flyout-open] /template/ Border#border">
|
||||
<Setter Property="Background"
|
||||
Value="{DynamicResource BorderBrush}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[Tag=checked] /template/ Border#border">
|
||||
<Setter Property="Background"
|
||||
Value="{DynamicResource PrimaryBrush}" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="^[Tag=checked]">
|
||||
<Setter Property="Foreground"
|
||||
Value="{DynamicResource TextIconBrush}" />
|
||||
</Style>
|
||||
</ControlTheme>
|
||||
|
||||
<!-- SplitButton base: HC default look -->
|
||||
<ControlTheme x:Key="SplitButtonBaseStyle"
|
||||
TargetType="SplitButton">
|
||||
<Setter Property="Height"
|
||||
Value="{StaticResource DefaultControlHeight}" />
|
||||
<Setter Property="Padding"
|
||||
Value="{StaticResource DefaultControlPadding}" />
|
||||
<Setter Property="HorizontalAlignment"
|
||||
Value="Left" />
|
||||
<Setter Property="VerticalAlignment"
|
||||
Value="Center" />
|
||||
<Setter Property="HorizontalContentAlignment"
|
||||
Value="Center" />
|
||||
<Setter Property="VerticalContentAlignment"
|
||||
Value="Center" />
|
||||
<Setter Property="Background"
|
||||
Value="{DynamicResource RegionBrush}" />
|
||||
<Setter Property="Foreground"
|
||||
Value="{DynamicResource PrimaryTextBrush}" />
|
||||
<Setter Property="BorderBrush"
|
||||
Value="{DynamicResource BorderBrush}" />
|
||||
<Setter Property="BorderThickness"
|
||||
Value="1" />
|
||||
<Setter Property="hc:BorderElement.CornerRadius"
|
||||
Value="{StaticResource DefaultCornerRadius}" />
|
||||
<Setter Property="CornerRadius"
|
||||
Value="{Binding $self.(hc:BorderElement.CornerRadius)}" />
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate>
|
||||
<Grid ColumnDefinitions="*,Auto,Auto">
|
||||
<Button x:Name="PART_PrimaryButton"
|
||||
Grid.Column="0"
|
||||
Theme="{StaticResource SplitButtonComponent}"
|
||||
Foreground="{TemplateBinding Foreground}"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness, Converter={StaticResource ThicknessSplitConverter}, ConverterParameter='1,1,0,1'}"
|
||||
Content="{TemplateBinding Content}"
|
||||
ContentTemplate="{TemplateBinding ContentTemplate}"
|
||||
Command="{TemplateBinding Command}"
|
||||
CommandParameter="{TemplateBinding CommandParameter}"
|
||||
CornerRadius="{TemplateBinding CornerRadius, Converter={StaticResource CornerRadiusSplitConverter}, ConverterParameter='1,0,0,1'}"
|
||||
FontFamily="{TemplateBinding FontFamily}"
|
||||
FontSize="{TemplateBinding FontSize}"
|
||||
FontWeight="{TemplateBinding FontWeight}"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
hc:IconElement.Geometry="{TemplateBinding hc:IconElement.Geometry}"
|
||||
hc:IconElement.Width="{TemplateBinding hc:IconElement.Width}"
|
||||
hc:IconElement.Height="{TemplateBinding hc:IconElement.Height}"
|
||||
Focusable="False"
|
||||
KeyboardNavigation.IsTabStop="False" />
|
||||
|
||||
<Border x:Name="SeparatorBorder"
|
||||
Grid.Column="1"
|
||||
Width="1"
|
||||
Background="{TemplateBinding BorderBrush}" />
|
||||
|
||||
<Button x:Name="PART_SecondaryButton"
|
||||
Grid.Column="2"
|
||||
Theme="{StaticResource SplitButtonComponent}"
|
||||
MinWidth="28"
|
||||
Foreground="{TemplateBinding Foreground}"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness, Converter={StaticResource ThicknessSplitConverter}, ConverterParameter='0,1,1,1'}"
|
||||
CornerRadius="{TemplateBinding CornerRadius, Converter={StaticResource CornerRadiusSplitConverter}, ConverterParameter='0,1,1,0'}"
|
||||
Padding="0"
|
||||
HorizontalContentAlignment="Center"
|
||||
VerticalContentAlignment="Center"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Focusable="False"
|
||||
KeyboardNavigation.IsTabStop="False">
|
||||
<Path Width="8"
|
||||
Height="5"
|
||||
Stretch="Uniform"
|
||||
Fill="{TemplateBinding Foreground}"
|
||||
Data="M1939 486L2029 576L1024 1581L19 576L109 486L1024 1401L1939 486Z" />
|
||||
</Button>
|
||||
|
||||
<Border Name="CheckedMask"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="3"
|
||||
Margin="-1"
|
||||
CornerRadius="{TemplateBinding CornerRadius}"
|
||||
BorderThickness="4"
|
||||
BorderBrush="{DynamicResource DarkMaskBrush}"
|
||||
IsHitTestVisible="False"
|
||||
IsVisible="False" />
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
|
||||
<Style Selector="^:disabled">
|
||||
<Setter Property="Opacity"
|
||||
Value="0.4" />
|
||||
</Style>
|
||||
|
||||
<!-- :checked only triggers for ToggleSplitButton (SplitButton.InternalIsChecked is always false) -->
|
||||
<Style Selector="^:checked /template/ Border#CheckedMask">
|
||||
<Setter Property="IsVisible"
|
||||
Value="True" />
|
||||
</Style>
|
||||
|
||||
<!-- Mirror SplitButton pseudo-state into the secondary inner button via Tag,
|
||||
so :flyout-open visually highlights only the dropdown side. -->
|
||||
<Style Selector="^:flyout-open /template/ Button#PART_SecondaryButton">
|
||||
<Setter Property="Tag"
|
||||
Value="flyout-open" />
|
||||
</Style>
|
||||
</ControlTheme>
|
||||
|
||||
<ControlTheme x:Key="{x:Type SplitButton}"
|
||||
BasedOn="{StaticResource SplitButtonBaseStyle}"
|
||||
TargetType="SplitButton" />
|
||||
|
||||
<ControlTheme x:Key="SplitButton.Small"
|
||||
BasedOn="{StaticResource SplitButtonBaseStyle}"
|
||||
TargetType="SplitButton">
|
||||
<Setter Property="Height"
|
||||
Value="20" />
|
||||
<Setter Property="Padding"
|
||||
Value="6,1" />
|
||||
<Setter Property="hc:IconElement.Height"
|
||||
Value="12" />
|
||||
</ControlTheme>
|
||||
|
||||
<!-- ToggleSplitButton uses StyleKeyOverride => typeof(SplitButton), so it inherits the
|
||||
SplitButton default theme automatically. The :checked dark mask is defined in
|
||||
SplitButtonBaseStyle and only triggers when InternalIsChecked == true (i.e. on
|
||||
ToggleSplitButton instances). -->
|
||||
|
||||
<ControlTheme x:Key="ToggleSplitButton.Small"
|
||||
BasedOn="{StaticResource SplitButton.Small}"
|
||||
TargetType="ToggleSplitButton" />
|
||||
</ResourceDictionary>
|
||||
Reference in new issue
Block a user