Merge pull request #112 from irihitech/issue/107

KeyGestureInput update.
This commit is contained in:
Zhang Dian
2024-02-19 16:49:57 +08:00
committed by GitHub
3 changed files with 98 additions and 15 deletions

View File

@@ -13,8 +13,15 @@
mc:Ignorable="d">
<StackPanel Margin="20">
<TextBlock Text="Accept all keys" />
<u:KeyGestureInput HorizontalAlignment="Left" Width="500" />
<u:KeyGestureInput HorizontalAlignment="Left" />
<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" />
<u:KeyGestureInput HorizontalAlignment="Stretch" HorizontalContentAlignment="Left" />
</StackPanel>
</UserControl>

View File

@@ -2,17 +2,19 @@
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="using:Avalonia.Controls.Converters"
xmlns:ursaConverters="using:Ursa.Converters"
xmlns:u="https://irihi.tech/ursa">
<converters:PlatformKeyGestureConverter x:Key="KeyGestureConverter" />
<ControlTheme x:Key="{x:Type u:KeyGestureInput}" TargetType="u:KeyGestureInput">
<Setter Property="Width" Value="{DynamicResource KeyGestureInputWidth}" />
<Setter Property="Height" Value="{DynamicResource KeyGestureInputHeight}" />
<Setter Property="MinWidth" Value="{DynamicResource KeyGestureInputWidth}" />
<Setter Property="MinHeight" Value="{DynamicResource KeyGestureInputHeight}" />
<Setter Property="Background" Value="{DynamicResource KeyGestureInputBackground}" />
<Setter Property="BorderBrush" Value="{DynamicResource KeyGestureInputBorderBrush}" />
<Setter Property="BorderThickness" Value="{DynamicResource KeyGestureInputBorderThickness}" />
<Setter Property="CornerRadius" Value="{DynamicResource KeyGestureInputCornerRadius}" />
<Setter Property="HorizontalContentAlignment" Value="Center"></Setter>
<Setter Property="Padding" Value="8 0" />
<Setter Property="Template">
<ControlTemplate TargetType="u:KeyGestureInput">
<Border
@@ -23,11 +25,43 @@
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<SelectableTextBlock
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Text="{TemplateBinding Gesture,
Converter={StaticResource KeyGestureConverter}}" />
<Panel VerticalAlignment="Stretch" Margin="{TemplateBinding Padding}">
<Grid ColumnDefinitions="Auto, *, Auto" >
<ContentPresenter Grid.Column="0"
Content="{TemplateBinding InnerLeftContent}"
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
Grid.Column="2"
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
Grid.Column="1"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Text="{TemplateBinding Gesture,
Converter={StaticResource KeyGestureConverter}}" />
<Button Grid.Column="0" Grid.ColumnSpan="3"
Name="PART_ClearButton"
Margin="0,0,8,0"
HorizontalAlignment="Right"
Command="{Binding $parent[u:KeyGestureInput].Clear}"
Focusable="False"
IsVisible="False"
Theme="{DynamicResource InputClearButton}" />
</Grid>
</Panel>
</Border>
</ControlTemplate>
</Setter>
@@ -45,5 +79,13 @@
<Setter Property="Background" Value="{DynamicResource KeyGestureInputPressedBackground}" />
<Setter Property="BorderBrush" Value="{DynamicResource KeyGestureInputFocusBorderBrush}" />
</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>
</ResourceDictionary>

View File

@@ -1,23 +1,29 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Converters;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Layout;
using Irihi.Avalonia.Shared.Contracts;
namespace Ursa.Controls;
public class KeyGestureInput: TemplatedControl
[PseudoClasses(PC_Empty)]
public class KeyGestureInput: TemplatedControl, IClearControl, IInnerContentControl
{
public const string PC_Empty = ":empty";
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));
public KeyGesture Gesture
public KeyGesture? Gesture
{
get => GetValue(GestureProperty);
set => SetValue(GestureProperty, value);
@@ -60,7 +66,30 @@ public class KeyGestureInput: TemplatedControl
get => GetValue(VerticalContentAlignmentProperty);
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)
{
@@ -94,4 +123,9 @@ public class KeyGestureInput: TemplatedControl
Gesture = gesture;
e.Handled = true;
}
public void Clear()
{
SetCurrentValue(GestureProperty, null);
}
}