Răsfoiți Sursa

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.
Steven Kirk 5 ani în urmă
părinte
comite
022294ec7a

+ 2 - 2
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 - 0
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();
+        }
+    }
+}

+ 6 - 6
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>

+ 5 - 3
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;

+ 6 - 2
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"

+ 1 - 1
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}"/>

+ 1 - 1
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]