Browse Source

MenuItem.InputGestureText -> InputGesture

Changed `MenuItem`'s `string InputGestureText` property to `KeyGesture InputGesture` and gave it a value converter in the default template, because the string representation of a key gesture depends on platform, and putting platform-specific behavior into `ToString` isn't a good idea.
pull/3602/head
Steven Kirk 6 years ago
parent
commit
022294ec7a
  1. 4
      samples/ControlCatalog/Pages/MenuPage.xaml
  2. 118
      src/Avalonia.Controls/Converters/PlatformKeyGestureConverter.cs
  3. 12
      src/Avalonia.Controls/MenuItem.cs
  4. 8
      src/Avalonia.Input/KeyGesture.cs
  5. 8
      src/Avalonia.Themes.Default/MenuItem.xaml
  6. 2
      src/Avalonia.Themes.Default/NativeMenuBar.xaml
  7. 2
      tests/Avalonia.Input.UnitTests/KeyGestureTests.cs

4
samples/ControlCatalog/Pages/MenuPage.xaml

@ -16,13 +16,13 @@
<TextBlock Classes="h3" Margin="4 8">Defined in XAML</TextBlock>
<Menu>
<MenuItem Header="_First">
<MenuItem Header="Standard _Menu Item" InputGestureText="Ctrl+A"/>
<MenuItem Header="Standard _Menu Item" InputGesture="Ctrl+A"/>
<Separator/>
<MenuItem Header="Menu with _Submenu">
<MenuItem Header="Submenu _1"/>
<MenuItem Header="Submenu _2"/>
</MenuItem>
<MenuItem Header="Menu Item with _Icon" InputGestureText="Ctrl+Shift+B">
<MenuItem Header="Menu Item with _Icon" InputGesture="Ctrl+Shift+B">
<MenuItem.Icon>
<Image Source="/Assets/github_icon.png"/>
</MenuItem.Icon>

118
src/Avalonia.Controls/Converters/PlatformKeyGestureConverter.cs

@ -0,0 +1,118 @@
using System;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Text;
using Avalonia.Data.Converters;
using Avalonia.Input;
namespace Avalonia.Controls.Converters
{
public class PlatformKeyGestureConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is null)
{
return null;
}
else if (value is KeyGesture gesture && targetType == typeof(string))
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return ToString(gesture, "Win");
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
return ToString(gesture, "Super");
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
return ToOSXString(gesture);
}
else
{
return gesture.ToString();
}
}
else
{
throw new NotSupportedException();
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
private static string ToString(KeyGesture gesture, string meta)
{
var s = new StringBuilder();
static void Plus(StringBuilder s)
{
if (s.Length > 0)
{
s.Append("+");
}
}
if (gesture.KeyModifiers.HasFlagCustom(KeyModifiers.Control))
{
s.Append("Ctrl");
}
if (gesture.KeyModifiers.HasFlagCustom(KeyModifiers.Shift))
{
Plus(s);
s.Append("Shift");
}
if (gesture.KeyModifiers.HasFlagCustom(KeyModifiers.Alt))
{
Plus(s);
s.Append("Alt");
}
if (gesture.KeyModifiers.HasFlagCustom(KeyModifiers.Meta))
{
Plus(s);
s.Append(meta);
}
Plus(s);
s.Append(gesture.Key);
return s.ToString();
}
private static string ToOSXString(KeyGesture gesture)
{
var s = new StringBuilder();
if (gesture.KeyModifiers.HasFlagCustom(KeyModifiers.Control))
{
s.Append('⌃');
}
if (gesture.KeyModifiers.HasFlagCustom(KeyModifiers.Alt))
{
s.Append('⌥');
}
if (gesture.KeyModifiers.HasFlagCustom(KeyModifiers.Shift))
{
s.Append('⇧');
}
if (gesture.KeyModifiers.HasFlagCustom(KeyModifiers.Meta))
{
s.Append('⌘');
}
s.Append(gesture.Key);
return s.ToString();
}
}
}

12
src/Avalonia.Controls/MenuItem.cs

@ -50,10 +50,10 @@ namespace Avalonia.Controls
AvaloniaProperty.Register<MenuItem, object>(nameof(Icon));
/// <summary>
/// Defines the <see cref="InputGestureText"/> property.
/// Defines the <see cref="InputGesture"/> property.
/// </summary>
public static readonly StyledProperty<string> InputGestureTextProperty =
AvaloniaProperty.Register<MenuItem, string>(nameof(InputGestureText));
public static readonly StyledProperty<KeyGesture> InputGestureProperty =
AvaloniaProperty.Register<MenuItem, KeyGesture>(nameof(InputGesture));
/// <summary>
/// Defines the <see cref="IsSelected"/> property.
@ -209,10 +209,10 @@ namespace Avalonia.Controls
/// Setting this property does not cause the input gesture to be handled by the menu item,
/// it simply displays the gesture text in the menu.
/// </remarks>
public string InputGestureText
public KeyGesture InputGesture
{
get { return GetValue(InputGestureTextProperty); }
set { SetValue(InputGestureTextProperty, value); }
get { return GetValue(InputGestureProperty); }
set { SetValue(InputGestureProperty, value); }
}
/// <summary>

8
src/Avalonia.Input/KeyGesture.cs

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace Avalonia.Input
@ -129,17 +130,17 @@ namespace Avalonia.Input
Plus(s);
s.Append("Shift");
}
if (KeyModifiers.HasFlagCustom(KeyModifiers.Alt))
{
Plus(s);
s.Append("Alt");
}
if (KeyModifiers.HasFlagCustom(KeyModifiers.Meta))
{
Plus(s);
s.Append("");
s.Append("Cmd");
}
Plus(s);
@ -167,6 +168,7 @@ namespace Avalonia.Input
}
if (modifier.Equals("cmd".AsSpan(), StringComparison.OrdinalIgnoreCase) ||
modifier.Equals("win".AsSpan(), StringComparison.OrdinalIgnoreCase) ||
modifier.Equals("⌘".AsSpan(), StringComparison.OrdinalIgnoreCase))
{
return KeyModifiers.Meta;

8
src/Avalonia.Themes.Default/MenuItem.xaml

@ -1,6 +1,10 @@
<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:Avalonia.Controls.Converters;assembly=Avalonia.Controls"
xmlns:sys="clr-namespace:System;assembly=netstandard">
<Styles.Resources>
<conv:PlatformKeyGestureConverter x:Key="KeyGestureConverter"/>
</Styles.Resources>
<Style Selector="MenuItem">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
@ -44,7 +48,7 @@
</ContentPresenter.DataTemplates>
</ContentPresenter>
<TextBlock Grid.Column="3"
Text="{TemplateBinding InputGestureText}"
Text="{TemplateBinding InputGesture, Converter={StaticResource KeyGestureConverter}}"
VerticalAlignment="Center"/>
<Path Name="rightArrow"
Data="M0,0L4,3.5 0,7z"

2
src/Avalonia.Themes.Default/NativeMenuBar.xaml

@ -13,7 +13,7 @@
<Menu.Styles>
<Style Selector="MenuItem">
<Setter Property="Header" Value="{Binding Header}"/>
<Setter Property="InputGestureText" Value="{Binding Gesture}"/>
<Setter Property="InputGesture" Value="{Binding Gesture}"/>
<Setter Property="Items" Value="{Binding Menu.Items}"/>
<Setter Property="Command" Value="{Binding Command}"/>
<Setter Property="CommandParameter" Value="{Binding CommandParameter}"/>

2
tests/Avalonia.Input.UnitTests/KeyGestureTests.cs

@ -21,7 +21,7 @@ namespace Avalonia.Input.UnitTests
new object[]{new KeyGesture(Key.A, KeyModifiers.Control | KeyModifiers.Shift), "Ctrl+Shift+A"},
new object[]{new KeyGesture(Key.A, KeyModifiers.Alt | KeyModifiers.Shift), "Shift+Alt+A"},
new object[]{new KeyGesture(Key.A, KeyModifiers.Control | KeyModifiers.Alt | KeyModifiers.Shift), "Ctrl+Shift+Alt+A"},
new object[]{new KeyGesture(Key.A, KeyModifiers.Meta | KeyModifiers.Shift), "Shift++A"},
new object[]{new KeyGesture(Key.A, KeyModifiers.Meta | KeyModifiers.Shift), "Shift+Cmd+A"},
};
[Theory]

Loading…
Cancel
Save