Use KeySymbol for AccessKey (#20662)
* Change AccessText.AccessKey to a string * Use KeySymbol for AccessKey * Update API suppressions * Fix tests
This commit is contained in:
committed by
GitHub
parent
d9a6ae517f
commit
2185ce04e7
@@ -1219,6 +1219,12 @@
|
|||||||
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
|
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
|
||||||
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
|
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
|
||||||
</Suppression>
|
</Suppression>
|
||||||
|
<Suppression>
|
||||||
|
<DiagnosticId>CP0002</DiagnosticId>
|
||||||
|
<Target>M:Avalonia.Controls.Primitives.AccessText.get_AccessKey</Target>
|
||||||
|
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
|
||||||
|
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
|
||||||
|
</Suppression>
|
||||||
<Suppression>
|
<Suppression>
|
||||||
<DiagnosticId>CP0002</DiagnosticId>
|
<DiagnosticId>CP0002</DiagnosticId>
|
||||||
<Target>M:Avalonia.Controls.Primitives.OverlayPopupHost.ConfigurePosition(Avalonia.Visual,Avalonia.Controls.PlacementMode,Avalonia.Point,Avalonia.Controls.Primitives.PopupPositioning.PopupAnchor,Avalonia.Controls.Primitives.PopupPositioning.PopupGravity,Avalonia.Controls.Primitives.PopupPositioning.PopupPositionerConstraintAdjustment,System.Nullable{Avalonia.Rect})</Target>
|
<Target>M:Avalonia.Controls.Primitives.OverlayPopupHost.ConfigurePosition(Avalonia.Visual,Avalonia.Controls.PlacementMode,Avalonia.Point,Avalonia.Controls.Primitives.PopupPositioning.PopupAnchor,Avalonia.Controls.Primitives.PopupPositioning.PopupGravity,Avalonia.Controls.Primitives.PopupPositioning.PopupPositionerConstraintAdjustment,System.Nullable{Avalonia.Rect})</Target>
|
||||||
@@ -2131,6 +2137,12 @@
|
|||||||
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
|
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
|
||||||
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
|
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
|
||||||
</Suppression>
|
</Suppression>
|
||||||
|
<Suppression>
|
||||||
|
<DiagnosticId>CP0002</DiagnosticId>
|
||||||
|
<Target>M:Avalonia.Controls.Primitives.AccessText.get_AccessKey</Target>
|
||||||
|
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
|
||||||
|
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
|
||||||
|
</Suppression>
|
||||||
<Suppression>
|
<Suppression>
|
||||||
<DiagnosticId>CP0002</DiagnosticId>
|
<DiagnosticId>CP0002</DiagnosticId>
|
||||||
<Target>M:Avalonia.Controls.Primitives.OverlayPopupHost.ConfigurePosition(Avalonia.Visual,Avalonia.Controls.PlacementMode,Avalonia.Point,Avalonia.Controls.Primitives.PopupPositioning.PopupAnchor,Avalonia.Controls.Primitives.PopupPositioning.PopupGravity,Avalonia.Controls.Primitives.PopupPositioning.PopupPositionerConstraintAdjustment,System.Nullable{Avalonia.Rect})</Target>
|
<Target>M:Avalonia.Controls.Primitives.OverlayPopupHost.ConfigurePosition(Avalonia.Visual,Avalonia.Controls.PlacementMode,Avalonia.Point,Avalonia.Controls.Primitives.PopupPositioning.PopupAnchor,Avalonia.Controls.Primitives.PopupPositioning.PopupGravity,Avalonia.Controls.Primitives.PopupPositioning.PopupPositionerConstraintAdjustment,System.Nullable{Avalonia.Rect})</Target>
|
||||||
|
|||||||
@@ -122,9 +122,11 @@ namespace Avalonia.Input
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="accessKey">The access key.</param>
|
/// <param name="accessKey">The access key.</param>
|
||||||
/// <param name="element">The input element.</param>
|
/// <param name="element">The input element.</param>
|
||||||
public void Register(char accessKey, IInputElement element)
|
public void Register(string accessKey, IInputElement element)
|
||||||
{
|
{
|
||||||
var key = NormalizeKey(accessKey.ToString());
|
ArgumentException.ThrowIfNullOrEmpty(accessKey);
|
||||||
|
|
||||||
|
var key = NormalizeKey(accessKey);
|
||||||
|
|
||||||
// remove dead elements with matching key
|
// remove dead elements with matching key
|
||||||
for (var i = _registrations.Count - 1; i >= 0; i--)
|
for (var i = _registrations.Count - 1; i >= 0; i--)
|
||||||
@@ -224,7 +226,7 @@ namespace Avalonia.Input
|
|||||||
MainMenu?.IsOpen != true)
|
MainMenu?.IsOpen != true)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
e.Handled = ProcessKey(e.Key.ToString(), e.Source as IInputElement);
|
e.Handled = ProcessKey(e.KeySymbol, e.Source as IInputElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -287,8 +289,11 @@ namespace Avalonia.Input
|
|||||||
/// <param name="key">The access key to process.</param>
|
/// <param name="key">The access key to process.</param>
|
||||||
/// <param name="element">The element to get the targets which are in scope.</param>
|
/// <param name="element">The element to get the targets which are in scope.</param>
|
||||||
/// <returns>If there matches <c>true</c>, otherwise <c>false</c>.</returns>
|
/// <returns>If there matches <c>true</c>, otherwise <c>false</c>.</returns>
|
||||||
protected bool ProcessKey(string key, IInputElement? element)
|
protected bool ProcessKey(string? key, IInputElement? element)
|
||||||
{
|
{
|
||||||
|
if (string.IsNullOrEmpty(key))
|
||||||
|
return false;
|
||||||
|
|
||||||
key = NormalizeKey(key);
|
key = NormalizeKey(key);
|
||||||
var senderInfo = GetTargetForElement(element, key);
|
var senderInfo = GetTargetForElement(element, key);
|
||||||
// Find the possible targets matching the access key
|
// Find the possible targets matching the access key
|
||||||
@@ -503,20 +508,11 @@ namespace Avalonia.Input
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal class AccessKeyPressedEventArgs : RoutedEventArgs
|
internal class AccessKeyPressedEventArgs : RoutedEventArgs
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The constructor for AccessKeyPressed event args
|
|
||||||
/// </summary>
|
|
||||||
public AccessKeyPressedEventArgs()
|
|
||||||
{
|
|
||||||
RoutedEvent = AccessKeyHandler.AccessKeyPressedEvent;
|
|
||||||
Key = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor for AccessKeyPressed event args
|
/// Constructor for AccessKeyPressed event args
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key"></param>
|
/// <param name="key"></param>
|
||||||
public AccessKeyPressedEventArgs(string key) : this()
|
public AccessKeyPressedEventArgs(string key)
|
||||||
{
|
{
|
||||||
RoutedEvent = AccessKeyHandler.AccessKeyPressedEvent;
|
RoutedEvent = AccessKeyHandler.AccessKeyPressedEvent;
|
||||||
Key = key;
|
Key = key;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace Avalonia.Input
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="accessKey">The access key.</param>
|
/// <param name="accessKey">The access key.</param>
|
||||||
/// <param name="element">The input element.</param>
|
/// <param name="element">The input element.</param>
|
||||||
void Register(char accessKey, IInputElement element);
|
void Register(string accessKey, IInputElement element);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unregisters the access keys associated with the input element.
|
/// Unregisters the access keys associated with the input element.
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace Avalonia.Automation.Peers
|
|||||||
{
|
{
|
||||||
if (Owner.HeaderPresenter?.Child is AccessText accessText)
|
if (Owner.HeaderPresenter?.Child is AccessText accessText)
|
||||||
{
|
{
|
||||||
result = accessText.AccessKey.ToString();
|
result = accessText.AccessKey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using Avalonia.Reactive;
|
|||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
using Avalonia.Media.TextFormatting;
|
using Avalonia.Media.TextFormatting;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace Avalonia.Controls.Primitives
|
namespace Avalonia.Controls.Primitives
|
||||||
{
|
{
|
||||||
@@ -42,7 +43,7 @@ namespace Avalonia.Controls.Primitives
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the access key.
|
/// Gets the access key.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public char AccessKey
|
public string? AccessKey
|
||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
private set;
|
private set;
|
||||||
@@ -93,7 +94,7 @@ namespace Avalonia.Controls.Primitives
|
|||||||
base.OnAttachedToVisualTree(e);
|
base.OnAttachedToVisualTree(e);
|
||||||
_accessKeys = (e.Root as TopLevel)?.AccessKeyHandler;
|
_accessKeys = (e.Root as TopLevel)?.AccessKeyHandler;
|
||||||
|
|
||||||
if (_accessKeys != null && AccessKey != 0)
|
if (_accessKeys != null && !string.IsNullOrEmpty(AccessKey))
|
||||||
{
|
{
|
||||||
_accessKeys.Register(AccessKey, this);
|
_accessKeys.Register(AccessKey, this);
|
||||||
}
|
}
|
||||||
@@ -104,7 +105,7 @@ namespace Avalonia.Controls.Primitives
|
|||||||
{
|
{
|
||||||
base.OnDetachedFromVisualTree(e);
|
base.OnDetachedFromVisualTree(e);
|
||||||
|
|
||||||
if (_accessKeys != null && AccessKey != 0)
|
if (_accessKeys != null && !string.IsNullOrEmpty(AccessKey))
|
||||||
{
|
{
|
||||||
_accessKeys.Unregister(this);
|
_accessKeys.Unregister(this);
|
||||||
_accessKeys = null;
|
_accessKeys = null;
|
||||||
@@ -153,7 +154,7 @@ namespace Avalonia.Controls.Primitives
|
|||||||
/// <param name="text">The new text.</param>
|
/// <param name="text">The new text.</param>
|
||||||
private void TextChanged(string? text)
|
private void TextChanged(string? text)
|
||||||
{
|
{
|
||||||
var key = (char)0;
|
string? key = null;
|
||||||
|
|
||||||
if (text != null)
|
if (text != null)
|
||||||
{
|
{
|
||||||
@@ -161,13 +162,14 @@ namespace Avalonia.Controls.Primitives
|
|||||||
|
|
||||||
if (underscore != -1 && underscore < text.Length - 1)
|
if (underscore != -1 && underscore < text.Length - 1)
|
||||||
{
|
{
|
||||||
key = text[underscore + 1];
|
var rune = Rune.GetRuneAt(text, underscore + 1);
|
||||||
|
key = rune.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessKey = key;
|
AccessKey = key;
|
||||||
|
|
||||||
if (_accessKeys != null && AccessKey != 0)
|
if (_accessKeys != null && !string.IsNullOrEmpty(AccessKey))
|
||||||
{
|
{
|
||||||
_accessKeys.Register(AccessKey, this);
|
_accessKeys.Register(AccessKey, this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ namespace Avalonia.Base.UnitTests.Input
|
|||||||
root.KeyUp += (s, e) => events.Add($"KeyUp {e.Key}");
|
root.KeyUp += (s, e) => events.Add($"KeyUp {e.Key}");
|
||||||
|
|
||||||
KeyDown(root, Key.LeftAlt);
|
KeyDown(root, Key.LeftAlt);
|
||||||
KeyDown(root, Key.A, KeyModifiers.Alt);
|
KeyDown(root, Key.A, "a", KeyModifiers.Alt);
|
||||||
KeyUp(root, Key.A, KeyModifiers.Alt);
|
KeyUp(root, Key.A, "a", KeyModifiers.Alt);
|
||||||
KeyUp(root, Key.LeftAlt);
|
KeyUp(root, Key.LeftAlt);
|
||||||
|
|
||||||
Assert.Equal(new[]
|
Assert.Equal(new[]
|
||||||
@@ -48,8 +48,8 @@ namespace Avalonia.Base.UnitTests.Input
|
|||||||
root.KeyUp += (s, e) => events.Add($"KeyUp {e.Key}");
|
root.KeyUp += (s, e) => events.Add($"KeyUp {e.Key}");
|
||||||
|
|
||||||
KeyDown(root, Key.LeftAlt);
|
KeyDown(root, Key.LeftAlt);
|
||||||
KeyDown(root, Key.A, KeyModifiers.Alt);
|
KeyDown(root, Key.A, "a", KeyModifiers.Alt);
|
||||||
KeyUp(root, Key.A, KeyModifiers.Alt);
|
KeyUp(root, Key.A, "a", KeyModifiers.Alt);
|
||||||
KeyUp(root, Key.LeftAlt);
|
KeyUp(root, Key.LeftAlt);
|
||||||
|
|
||||||
Assert.Equal(new[]
|
Assert.Equal(new[]
|
||||||
@@ -122,13 +122,13 @@ namespace Avalonia.Base.UnitTests.Input
|
|||||||
var events = new List<string>();
|
var events = new List<string>();
|
||||||
|
|
||||||
target.SetOwner(root);
|
target.SetOwner(root);
|
||||||
target.Register('A', button);
|
target.Register("A", button);
|
||||||
root.KeyDown += (s, e) => events.Add($"KeyDown {e.Key}");
|
root.KeyDown += (s, e) => events.Add($"KeyDown {e.Key}");
|
||||||
root.KeyUp += (s, e) => events.Add($"KeyUp {e.Key}");
|
root.KeyUp += (s, e) => events.Add($"KeyUp {e.Key}");
|
||||||
|
|
||||||
KeyDown(root, Key.LeftAlt);
|
KeyDown(root, Key.LeftAlt);
|
||||||
KeyDown(root, Key.A, KeyModifiers.Alt);
|
KeyDown(root, Key.A, "a", KeyModifiers.Alt);
|
||||||
KeyUp(root, Key.A, KeyModifiers.Alt);
|
KeyUp(root, Key.A, "a", KeyModifiers.Alt);
|
||||||
KeyUp(root, Key.LeftAlt);
|
KeyUp(root, Key.LeftAlt);
|
||||||
|
|
||||||
// This differs from WPF which doesn't raise the `A` key event, but matches UWP.
|
// This differs from WPF which doesn't raise the `A` key event, but matches UWP.
|
||||||
@@ -141,8 +141,12 @@ namespace Avalonia.Base.UnitTests.Input
|
|||||||
}, events);
|
}, events);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public void Should_Raise_AccessKey_For_Registered_Access_Key()
|
[InlineData("A", Key.A, "a")]
|
||||||
|
[InlineData("A", Key.Q, "a")]
|
||||||
|
[InlineData("é", Key.D2, "é")]
|
||||||
|
[InlineData("2", Key.D2, "2")]
|
||||||
|
public void Should_Raise_AccessKey_For_Registered_Access_Key_Matching_KeySymbol(string registered, Key key, string keySymbol)
|
||||||
{
|
{
|
||||||
using (UnitTestApplication.Start(TestServices.RealFocus))
|
using (UnitTestApplication.Start(TestServices.RealFocus))
|
||||||
{
|
{
|
||||||
@@ -154,22 +158,51 @@ namespace Avalonia.Base.UnitTests.Input
|
|||||||
KeyboardDevice.Instance?.SetFocusedElement(button, NavigationMethod.Unspecified, KeyModifiers.None);
|
KeyboardDevice.Instance?.SetFocusedElement(button, NavigationMethod.Unspecified, KeyModifiers.None);
|
||||||
|
|
||||||
target.SetOwner(root);
|
target.SetOwner(root);
|
||||||
target.Register('A', button);
|
target.Register(registered, button);
|
||||||
button.AddHandler(AccessKeyHandler.AccessKeyEvent, (s, e) => ++raised);
|
button.AddHandler(AccessKeyHandler.AccessKeyEvent, (s, e) => ++raised);
|
||||||
|
|
||||||
KeyDown(root, Key.LeftAlt);
|
KeyDown(root, Key.LeftAlt);
|
||||||
Assert.Equal(0, raised);
|
Assert.Equal(0, raised);
|
||||||
|
|
||||||
KeyDown(root, Key.A, KeyModifiers.Alt);
|
KeyDown(root, key, keySymbol, KeyModifiers.Alt);
|
||||||
Assert.Equal(1, raised);
|
Assert.Equal(1, raised);
|
||||||
|
|
||||||
KeyUp(root, Key.A, KeyModifiers.Alt);
|
KeyUp(root, key, keySymbol, KeyModifiers.Alt);
|
||||||
KeyUp(root, Key.LeftAlt);
|
KeyUp(root, Key.LeftAlt);
|
||||||
|
|
||||||
Assert.Equal(1, raised);
|
Assert.Equal(1, raised);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Should_Not_Raise_AccessKey_For_Registered_Access_Key_Not_Matching_KeySymbol()
|
||||||
|
{
|
||||||
|
using (UnitTestApplication.Start(TestServices.RealFocus))
|
||||||
|
{
|
||||||
|
var button = new Button();
|
||||||
|
var root = new TestRoot(button);
|
||||||
|
var target = new AccessKeyHandler();
|
||||||
|
var raised = 0;
|
||||||
|
|
||||||
|
KeyboardDevice.Instance?.SetFocusedElement(button, NavigationMethod.Unspecified, KeyModifiers.None);
|
||||||
|
|
||||||
|
target.SetOwner(root);
|
||||||
|
target.Register("A", button);
|
||||||
|
button.AddHandler(AccessKeyHandler.AccessKeyEvent, (_, _) => ++raised);
|
||||||
|
|
||||||
|
KeyDown(root, Key.LeftAlt);
|
||||||
|
Assert.Equal(0, raised);
|
||||||
|
|
||||||
|
KeyDown(root, Key.A, "q", KeyModifiers.Alt);
|
||||||
|
Assert.Equal(0, raised);
|
||||||
|
|
||||||
|
KeyUp(root, Key.A, "q", KeyModifiers.Alt);
|
||||||
|
KeyUp(root, Key.LeftAlt);
|
||||||
|
|
||||||
|
Assert.Equal(0, raised);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(false, 0)]
|
[InlineData(false, 0)]
|
||||||
[InlineData(true, 1)]
|
[InlineData(true, 1)]
|
||||||
@@ -185,16 +218,16 @@ namespace Avalonia.Base.UnitTests.Input
|
|||||||
KeyboardDevice.Instance?.SetFocusedElement(button, NavigationMethod.Unspecified, KeyModifiers.None);
|
KeyboardDevice.Instance?.SetFocusedElement(button, NavigationMethod.Unspecified, KeyModifiers.None);
|
||||||
|
|
||||||
target.SetOwner(root);
|
target.SetOwner(root);
|
||||||
target.Register('A', button);
|
target.Register("A", button);
|
||||||
button.AddHandler(AccessKeyHandler.AccessKeyEvent, (s, e) => ++raised);
|
button.AddHandler(AccessKeyHandler.AccessKeyEvent, (s, e) => ++raised);
|
||||||
|
|
||||||
KeyDown(root, Key.LeftAlt);
|
KeyDown(root, Key.LeftAlt);
|
||||||
Assert.Equal(0, raised);
|
Assert.Equal(0, raised);
|
||||||
|
|
||||||
KeyDown(root, Key.A, KeyModifiers.Alt);
|
KeyDown(root, Key.A, "a", KeyModifiers.Alt);
|
||||||
Assert.Equal(expected, raised);
|
Assert.Equal(expected, raised);
|
||||||
|
|
||||||
KeyUp(root, Key.A, KeyModifiers.Alt);
|
KeyUp(root, Key.A, "a", KeyModifiers.Alt);
|
||||||
KeyUp(root, Key.LeftAlt);
|
KeyUp(root, Key.LeftAlt);
|
||||||
Assert.Equal(expected, raised);
|
Assert.Equal(expected, raised);
|
||||||
}
|
}
|
||||||
@@ -223,22 +256,24 @@ namespace Avalonia.Base.UnitTests.Input
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void KeyDown(IInputElement target, Key key, KeyModifiers modifiers = KeyModifiers.None)
|
private static void KeyDown(IInputElement target, Key key, string? keySymbol = null, KeyModifiers modifiers = KeyModifiers.None)
|
||||||
{
|
{
|
||||||
target.RaiseEvent(new KeyEventArgs
|
target.RaiseEvent(new KeyEventArgs
|
||||||
{
|
{
|
||||||
RoutedEvent = InputElement.KeyDownEvent,
|
RoutedEvent = InputElement.KeyDownEvent,
|
||||||
Key = key,
|
Key = key,
|
||||||
|
KeySymbol = keySymbol,
|
||||||
KeyModifiers = modifiers,
|
KeyModifiers = modifiers,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void KeyUp(IInputElement target, Key key, KeyModifiers modifiers = KeyModifiers.None)
|
private static void KeyUp(IInputElement target, Key key, string? keySymbol = null, KeyModifiers modifiers = KeyModifiers.None)
|
||||||
{
|
{
|
||||||
target.RaiseEvent(new KeyEventArgs
|
target.RaiseEvent(new KeyEventArgs
|
||||||
{
|
{
|
||||||
RoutedEvent = InputElement.KeyUpEvent,
|
RoutedEvent = InputElement.KeyUpEvent,
|
||||||
Key = key,
|
Key = key,
|
||||||
|
KeySymbol = keySymbol,
|
||||||
KeyModifiers = modifiers,
|
KeyModifiers = modifiers,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -345,16 +345,17 @@ namespace Avalonia.Controls.UnitTests
|
|||||||
|
|
||||||
Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded, TestContext.Current.CancellationToken);
|
Dispatcher.UIThread.RunJobs(DispatcherPriority.Loaded, TestContext.Current.CancellationToken);
|
||||||
|
|
||||||
var accessKey = Key.A;
|
const Key accessKey = Key.A;
|
||||||
|
const string accessKeySymbol = "a";
|
||||||
target.CommandParameter = true;
|
target.CommandParameter = true;
|
||||||
|
|
||||||
RaiseAccessKey(root, accessKey);
|
RaiseAccessKey(root, accessKey, accessKeySymbol);
|
||||||
|
|
||||||
Assert.Equal(1, raised);
|
Assert.Equal(1, raised);
|
||||||
|
|
||||||
target.CommandParameter = false;
|
target.CommandParameter = false;
|
||||||
|
|
||||||
RaiseAccessKey(root, accessKey);
|
RaiseAccessKey(root, accessKey, accessKeySymbol);
|
||||||
|
|
||||||
Assert.Equal(1, raised);
|
Assert.Equal(1, raised);
|
||||||
|
|
||||||
@@ -379,30 +380,32 @@ namespace Avalonia.Controls.UnitTests
|
|||||||
return topLevel;
|
return topLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RaiseAccessKey(IInputElement target, Key accessKey)
|
static void RaiseAccessKey(IInputElement target, Key accessKey, string keySymbol)
|
||||||
{
|
{
|
||||||
KeyDown(target, Key.LeftAlt);
|
KeyDown(target, Key.LeftAlt);
|
||||||
KeyDown(target, accessKey, KeyModifiers.Alt);
|
KeyDown(target, accessKey, keySymbol, KeyModifiers.Alt);
|
||||||
KeyUp(target, accessKey, KeyModifiers.Alt);
|
KeyUp(target, accessKey, keySymbol, KeyModifiers.Alt);
|
||||||
KeyUp(target, Key.LeftAlt);
|
KeyUp(target, Key.LeftAlt, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void KeyDown(IInputElement target, Key key, KeyModifiers modifiers = KeyModifiers.None)
|
static void KeyDown(IInputElement target, Key key, string? keySymbol = null, KeyModifiers modifiers = KeyModifiers.None)
|
||||||
{
|
{
|
||||||
target.RaiseEvent(new KeyEventArgs
|
target.RaiseEvent(new KeyEventArgs
|
||||||
{
|
{
|
||||||
RoutedEvent = InputElement.KeyDownEvent,
|
RoutedEvent = InputElement.KeyDownEvent,
|
||||||
Key = key,
|
Key = key,
|
||||||
|
KeySymbol = keySymbol,
|
||||||
KeyModifiers = modifiers,
|
KeyModifiers = modifiers,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static void KeyUp(IInputElement target, Key key, KeyModifiers modifiers = KeyModifiers.None)
|
static void KeyUp(IInputElement target, Key key, string? keySymbol = null, KeyModifiers modifiers = KeyModifiers.None)
|
||||||
{
|
{
|
||||||
target.RaiseEvent(new KeyEventArgs
|
target.RaiseEvent(new KeyEventArgs
|
||||||
{
|
{
|
||||||
RoutedEvent = InputElement.KeyUpEvent,
|
RoutedEvent = InputElement.KeyUpEvent,
|
||||||
Key = key,
|
Key = key,
|
||||||
|
KeySymbol = keySymbol,
|
||||||
KeyModifiers = modifiers,
|
KeyModifiers = modifiers,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -718,10 +718,10 @@ namespace Avalonia.Controls.UnitTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(Key.A, 1)]
|
[InlineData(Key.A, "a", 1)]
|
||||||
[InlineData(Key.L, 2)]
|
[InlineData(Key.L, "l", 2)]
|
||||||
[InlineData(Key.D, 0)]
|
[InlineData(Key.D, "d", 0)]
|
||||||
public void Should_TabControl_Recognizes_AccessKey(Key accessKey, int selectedTabIndex)
|
public void Should_TabControl_Recognizes_AccessKey(Key accessKey, string accessKeySymbol, int selectedTabIndex)
|
||||||
{
|
{
|
||||||
var ah = new AccessKeyHandler();
|
var ah = new AccessKeyHandler();
|
||||||
var kd = new KeyboardDevice();
|
var kd = new KeyboardDevice();
|
||||||
@@ -760,8 +760,8 @@ namespace Avalonia.Controls.UnitTests
|
|||||||
ApplyTemplate(tabControl);
|
ApplyTemplate(tabControl);
|
||||||
|
|
||||||
KeyDown(root, Key.LeftAlt);
|
KeyDown(root, Key.LeftAlt);
|
||||||
KeyDown(root, accessKey, KeyModifiers.Alt);
|
KeyDown(root, accessKey, accessKeySymbol, KeyModifiers.Alt);
|
||||||
KeyUp(root, accessKey, KeyModifiers.Alt);
|
KeyUp(root, accessKey, accessKeySymbol, KeyModifiers.Alt);
|
||||||
KeyUp(root, Key.LeftAlt);
|
KeyUp(root, Key.LeftAlt);
|
||||||
|
|
||||||
Assert.Equal(selectedTabIndex, tabControl.SelectedIndex);
|
Assert.Equal(selectedTabIndex, tabControl.SelectedIndex);
|
||||||
@@ -788,22 +788,24 @@ namespace Avalonia.Controls.UnitTests
|
|||||||
return topLevel;
|
return topLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void KeyDown(IInputElement target, Key key, KeyModifiers modifiers = KeyModifiers.None)
|
static void KeyDown(IInputElement target, Key key, string? keySymbol = null, KeyModifiers modifiers = KeyModifiers.None)
|
||||||
{
|
{
|
||||||
target.RaiseEvent(new KeyEventArgs
|
target.RaiseEvent(new KeyEventArgs
|
||||||
{
|
{
|
||||||
RoutedEvent = InputElement.KeyDownEvent,
|
RoutedEvent = InputElement.KeyDownEvent,
|
||||||
Key = key,
|
Key = key,
|
||||||
|
KeySymbol = keySymbol,
|
||||||
KeyModifiers = modifiers,
|
KeyModifiers = modifiers,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static void KeyUp(IInputElement target, Key key, KeyModifiers modifiers = KeyModifiers.None)
|
static void KeyUp(IInputElement target, Key key, string? keySymbol = null, KeyModifiers modifiers = KeyModifiers.None)
|
||||||
{
|
{
|
||||||
target.RaiseEvent(new KeyEventArgs
|
target.RaiseEvent(new KeyEventArgs
|
||||||
{
|
{
|
||||||
RoutedEvent = InputElement.KeyUpEvent,
|
RoutedEvent = InputElement.KeyUpEvent,
|
||||||
Key = key,
|
Key = key,
|
||||||
|
KeySymbol = keySymbol,
|
||||||
KeyModifiers = modifiers,
|
KeyModifiers = modifiers,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user