feat: add implementation.

This commit is contained in:
rabbitism
2024-02-18 18:10:43 +08:00
parent e286f3fece
commit 3b7bb99c84
3 changed files with 92 additions and 13 deletions

View File

@@ -13,8 +13,14 @@
mc:Ignorable="d"> mc:Ignorable="d">
<StackPanel Margin="20"> <StackPanel Margin="20">
<TextBlock Text="Accept all keys" /> <TextBlock Text="Accept all keys" />
<u:KeyGestureInput HorizontalAlignment="Left" Width="500" /> <u:KeyGestureInput Width="300" HorizontalAlignment="Left" />
<TextBlock Text="Accept only A,B and C" /> <TextBlock Text="Accept only A,B and C" />
<u:KeyGestureInput HorizontalAlignment="Left" AcceptableKeys="{Binding AcceptableKeys}" Width="500" /> <u:KeyGestureInput
Width="300"
HorizontalAlignment="Left"
AcceptableKeys="{Binding AcceptableKeys}"
Classes="ClearButton"
InnerLeftContent="Attack"
InnerRightContent="Default" />
</StackPanel> </StackPanel>
</UserControl> </UserControl>

View File

@@ -2,6 +2,7 @@
xmlns="https://github.com/avaloniaui" xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="using:Avalonia.Controls.Converters" xmlns:converters="using:Avalonia.Controls.Converters"
xmlns:ursaConverters="using:Ursa.Converters"
xmlns:u="https://irihi.tech/ursa"> xmlns:u="https://irihi.tech/ursa">
<converters:PlatformKeyGestureConverter x:Key="KeyGestureConverter" /> <converters:PlatformKeyGestureConverter x:Key="KeyGestureConverter" />
@@ -12,7 +13,7 @@
<Setter Property="BorderBrush" Value="{DynamicResource KeyGestureInputBorderBrush}" /> <Setter Property="BorderBrush" Value="{DynamicResource KeyGestureInputBorderBrush}" />
<Setter Property="BorderThickness" Value="{DynamicResource KeyGestureInputBorderThickness}" /> <Setter Property="BorderThickness" Value="{DynamicResource KeyGestureInputBorderThickness}" />
<Setter Property="CornerRadius" Value="{DynamicResource KeyGestureInputCornerRadius}" /> <Setter Property="CornerRadius" Value="{DynamicResource KeyGestureInputCornerRadius}" />
<Setter Property="Padding" Value="8 0" />
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate TargetType="u:KeyGestureInput"> <ControlTemplate TargetType="u:KeyGestureInput">
<Border <Border
@@ -23,11 +24,41 @@
BorderBrush="{TemplateBinding BorderBrush}" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"> CornerRadius="{TemplateBinding CornerRadius}">
<SelectableTextBlock <Panel VerticalAlignment="Stretch" Margin="{TemplateBinding Padding}">
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" <DockPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" <ContentPresenter
Text="{TemplateBinding Gesture, Content="{TemplateBinding InnerLeftContent}"
Converter={StaticResource KeyGestureConverter}}" /> Padding="{TemplateBinding Padding, Converter={x:Static ursaConverters:ThicknessIncludeConverter.Right}}"
DockPanel.Dock="Left"
VerticalAlignment="Stretch"
VerticalContentAlignment="Center"
Foreground="{DynamicResource TextBoxInnerForeground}"
IsVisible="{Binding Path=InnerLeftContent, RelativeSource={RelativeSource TemplatedParent},
Converter={x:Static ObjectConverters.IsNotNull}}" />
<ContentPresenter
Content="{TemplateBinding InnerRightContent}"
DockPanel.Dock="Right"
Padding="{TemplateBinding Padding, Converter={x:Static ursaConverters:ThicknessIncludeConverter.Left}}"
VerticalAlignment="Stretch"
VerticalContentAlignment="Center"
Foreground="{DynamicResource TextBoxInnerForeground}"
IsVisible="{Binding Path=InnerRightContent, RelativeSource={RelativeSource TemplatedParent},
Converter={x:Static ObjectConverters.IsNotNull}}" />
<SelectableTextBlock
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Text="{TemplateBinding Gesture,
Converter={StaticResource KeyGestureConverter}}" />
<Button
Name="PART_ClearButton"
Margin="0,0,8,0"
HorizontalAlignment="Right"
Command="{Binding $parent[u:KeyGestureInput].Clear}"
Focusable="False"
IsVisible="False"
Theme="{DynamicResource InputClearButton}" />
</DockPanel>
</Panel>
</Border> </Border>
</ControlTemplate> </ControlTemplate>
</Setter> </Setter>
@@ -45,5 +76,13 @@
<Setter Property="Background" Value="{DynamicResource KeyGestureInputPressedBackground}" /> <Setter Property="Background" Value="{DynamicResource KeyGestureInputPressedBackground}" />
<Setter Property="BorderBrush" Value="{DynamicResource KeyGestureInputFocusBorderBrush}" /> <Setter Property="BorderBrush" Value="{DynamicResource KeyGestureInputFocusBorderBrush}" />
</Style> </Style>
<Style Selector="^:not(:empty).clearButton, ^:not(:empty).ClearButton">
<Style Selector="^:focus /template/ Button#PART_ClearButton">
<Setter Property="IsVisible" Value="True" />
</Style>
<Style Selector="^:pointerover /template/ Button#PART_ClearButton">
<Setter Property="IsVisible" Value="True" />
</Style>
</Style>
</ControlTheme> </ControlTheme>
</ResourceDictionary> </ResourceDictionary>

View File

@@ -1,23 +1,29 @@
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Converters; using Avalonia.Controls.Converters;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Layout; using Avalonia.Layout;
using Irihi.Avalonia.Shared.Contracts;
namespace Ursa.Controls; namespace Ursa.Controls;
public class KeyGestureInput: TemplatedControl [PseudoClasses(PC_Empty)]
public class KeyGestureInput: TemplatedControl, IClearControl, IInnerContentControl
{ {
public const string PC_Empty = ":empty";
static KeyGestureInput() static KeyGestureInput()
{ {
InputElement.FocusableProperty.OverrideDefaultValue<KeyGestureInput>(true); FocusableProperty.OverrideDefaultValue<KeyGestureInput>(true);
GestureProperty.Changed.AddClassHandler<KeyGestureInput, KeyGesture?>((x, e) =>
x.PseudoClasses.Set(PC_Empty, e.NewValue.Value is null));
} }
public static readonly StyledProperty<KeyGesture> GestureProperty = AvaloniaProperty.Register<KeyGestureInput, KeyGesture>( public static readonly StyledProperty<KeyGesture?> GestureProperty = AvaloniaProperty.Register<KeyGestureInput, KeyGesture?>(
nameof(Gesture)); nameof(Gesture));
public KeyGesture Gesture public KeyGesture? Gesture
{ {
get => GetValue(GestureProperty); get => GetValue(GestureProperty);
set => SetValue(GestureProperty, value); set => SetValue(GestureProperty, value);
@@ -60,7 +66,30 @@ public class KeyGestureInput: TemplatedControl
get => GetValue(VerticalContentAlignmentProperty); get => GetValue(VerticalContentAlignmentProperty);
set => SetValue(VerticalContentAlignmentProperty, value); set => SetValue(VerticalContentAlignmentProperty, value);
} }
public static readonly StyledProperty<object?> InnerLeftContentProperty = AvaloniaProperty.Register<KeyGestureInput, object?>(
nameof(InnerLeftContent));
public object? InnerLeftContent
{
get => GetValue(InnerLeftContentProperty);
set => SetValue(InnerLeftContentProperty, value);
}
public static readonly StyledProperty<object?> InnerRightContentProperty = AvaloniaProperty.Register<KeyGestureInput, object?>(
nameof(InnerRightContent));
public object? InnerRightContent
{
get => GetValue(InnerRightContentProperty);
set => SetValue(InnerRightContentProperty, value);
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
PseudoClasses.Set(PC_Empty, Gesture is null);
}
protected override void OnKeyDown(KeyEventArgs e) protected override void OnKeyDown(KeyEventArgs e)
{ {
@@ -94,4 +123,9 @@ public class KeyGestureInput: TemplatedControl
Gesture = gesture; Gesture = gesture;
e.Handled = true; e.Handled = true;
} }
public void Clear()
{
SetCurrentValue(GestureProperty, null);
}
} }