123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348 |
- using System;
- using Avalonia.Controls.Presenters;
- using Avalonia.Controls.Templates;
- using Avalonia.Input;
- using Avalonia.Input.Raw;
- using Avalonia.Platform;
- using Avalonia.UnitTests;
- using Xunit;
- using Factory = System.Func<int, System.Action<object>, Avalonia.Controls.Window, Avalonia.AvaloniaObject>;
- namespace Avalonia.Controls.UnitTests.Utils
- {
- public class HotKeyManagerTests : ScopedTestBase
- {
- [Fact]
- public void HotKeyManager_Should_Register_And_Unregister_Key_Binding()
- {
- using (AvaloniaLocator.EnterScope())
- {
- AvaloniaLocator.CurrentMutable
- .Bind<IWindowingPlatform>().ToConstant(new MockWindowingPlatform());
- var gesture1 = new KeyGesture(Key.A, KeyModifiers.Control);
- var gesture2 = new KeyGesture(Key.B, KeyModifiers.Control);
- var tl = new Window();
- var button = new Button();
- tl.Content = button;
- tl.Template = CreateWindowTemplate();
- tl.ApplyTemplate();
- tl.Presenter.ApplyTemplate();
- HotKeyManager.SetHotKey(button, gesture1);
- Assert.Equal(gesture1, tl.KeyBindings[0].Gesture);
- HotKeyManager.SetHotKey(button, gesture2);
- Assert.Equal(gesture2, tl.KeyBindings[0].Gesture);
- tl.Content = null;
- tl.Presenter.ApplyTemplate();
- Assert.Empty(tl.KeyBindings);
- tl.Content = button;
- tl.Presenter.ApplyTemplate();
- Assert.Equal(gesture2, tl.KeyBindings[0].Gesture);
- HotKeyManager.SetHotKey(button, null);
- Assert.Empty(tl.KeyBindings);
- }
- }
- [Theory]
- [MemberData(nameof(ElementsFactory), parameters: true)]
- public void HotKeyManager_Should_Use_CommandParameter(string factoryName, Factory factory)
- {
- using (AvaloniaLocator.EnterScope())
- {
- var target = new KeyboardDevice();
- var commandResult = 0;
- var expectedParameter = 1;
- AvaloniaLocator.CurrentMutable
- .Bind<IWindowingPlatform>().ToConstant(new MockWindowingPlatform());
- var gesture = new KeyGesture(Key.A, KeyModifiers.Control);
- var action = new Action<object>(parameter =>
- {
- if (parameter is int value)
- {
- commandResult = value;
- }
- });
- var root = new Window();
- var element = factory(expectedParameter, action, root);
- root.Template = CreateWindowTemplate();
- root.ApplyTemplate();
- root.Presenter.ApplyTemplate();
- HotKeyManager.SetHotKey(element, gesture);
- target.ProcessRawEvent(new RawKeyEventArgs(target,
- 0,
- root,
- RawKeyEventType.KeyDown,
- Key.A,
- RawInputModifiers.Control,
- PhysicalKey.A,
- "a"));
- Assert.True(expectedParameter == commandResult, $"{factoryName} HotKey did not carry the CommandParameter.");
- }
- }
- [Theory]
- [MemberData(nameof(ElementsFactory), parameters: true)]
- public void HotKeyManager_Should_Do_Not_Executed_When_IsEnabled_False(string factoryName, Factory factory)
- {
- using (AvaloniaLocator.EnterScope())
- {
- var target = new KeyboardDevice();
- var isExecuted = false;
- AvaloniaLocator.CurrentMutable
- .Bind<IWindowingPlatform>().ToConstant(new MockWindowingPlatform());
- var gesture = new KeyGesture(Key.A, KeyModifiers.Control);
- var action = new Action<object>(parameter =>
- {
- isExecuted = true;
- });
- var root = new Window();
- var element = factory(0, action, root) as InputElement;
- element.IsEnabled = false;
- root.Template = CreateWindowTemplate();
- root.ApplyTemplate();
- root.Presenter.ApplyTemplate();
- HotKeyManager.SetHotKey(element, gesture);
- target.ProcessRawEvent(new RawKeyEventArgs(target,
- 0,
- root,
- RawKeyEventType.KeyDown,
- Key.A,
- RawInputModifiers.Control,
- PhysicalKey.A,
- "a"));
- Assert.True(isExecuted == false, $"{factoryName} Execution raised when IsEnabled is false.");
- }
- }
- [Theory]
- [MemberData(nameof(ElementsFactory), parameters:false)]
- public void HotKeyManager_Should_Invoke_Event_Click_When_Command_Is_Null(string factoryName, Factory factory)
- {
- using (AvaloniaLocator.EnterScope())
- {
- var target = new KeyboardDevice();
- var clickExecutedCount = 0;
- AvaloniaLocator.CurrentMutable
- .Bind<IWindowingPlatform>().ToConstant(new MockWindowingPlatform());
- var gesture = new KeyGesture(Key.A, KeyModifiers.Control);
- void Clickable_Click(object sender, Interactivity.RoutedEventArgs e)
- {
- clickExecutedCount++;
- }
- var root = new Window();
- var element = factory(0, default, root) as InputElement;
- if (element is IClickableControl clickable)
- {
- clickable.Click += Clickable_Click;
- }
- root.Template = CreateWindowTemplate();
- root.ApplyTemplate();
- root.Presenter.ApplyTemplate();
- HotKeyManager.SetHotKey(element, gesture);
- target.ProcessRawEvent(new RawKeyEventArgs(target,
- 0,
- root,
- RawKeyEventType.KeyDown,
- Key.A,
- RawInputModifiers.Control,
- PhysicalKey.A,
- "a"));
- element.IsEnabled = false;
- target.ProcessRawEvent(new RawKeyEventArgs(target,
- 0,
- root,
- RawKeyEventType.KeyDown,
- Key.A,
- RawInputModifiers.Control,
- PhysicalKey.A,
- "a"));
- Assert.True(clickExecutedCount == 1, $"{factoryName} Execution raised when IsEnabled is false.");
- }
- }
- [Theory]
- [MemberData(nameof(ElementsFactory), parameters: true)]
- public void HotKeyManager_Should_Not_Invoke_Event_Click_When_Command_Is_Not_Null(string factoryName, Factory factory)
- {
- using (AvaloniaLocator.EnterScope())
- {
- var target = new KeyboardDevice();
- var clickExecutedCount = 0;
- var commandExecutedCount = 0;
- AvaloniaLocator.CurrentMutable
- .Bind<IWindowingPlatform>().ToConstant(new MockWindowingPlatform());
- var gesture = new KeyGesture(Key.A, KeyModifiers.Control);
- void DoExecute(object parameter)
- {
- commandExecutedCount++;
- }
- void Clickable_Click(object sender, Interactivity.RoutedEventArgs e)
- {
- clickExecutedCount++;
- }
- var root = new Window();
- var element = factory(0, DoExecute, root) as InputElement;
- if (element is IClickableControl clickable)
- {
- clickable.Click += Clickable_Click;
- }
- root.Template = CreateWindowTemplate();
- root.ApplyTemplate();
- root.Presenter.ApplyTemplate();
- HotKeyManager.SetHotKey(element, gesture);
- target.ProcessRawEvent(new RawKeyEventArgs(target,
- 0,
- root,
- RawKeyEventType.KeyDown,
- Key.A,
- RawInputModifiers.Control,
- PhysicalKey.A,
- "a"));
- element.IsEnabled = false;
- target.ProcessRawEvent(new RawKeyEventArgs(target,
- 0,
- root,
- RawKeyEventType.KeyDown,
- Key.A,
- RawInputModifiers.Control,
- PhysicalKey.A,
- "a"));
- Assert.True(commandExecutedCount == 1, $"{factoryName} Execution raised when IsEnabled is false.");
- Assert.True(clickExecutedCount == 0, $"{factoryName} Execution raised event Click.");
- }
- }
- public static TheoryData<string, Factory> ElementsFactory(bool withCommand) =>
- new TheoryData<string, Factory>()
- {
- {nameof(Button), withCommand ? MakeButton : MakeButtonWithoutCommand},
- {nameof(MenuItem),withCommand ? MakeMenu : MakeMenuWithoutCommand},
- };
- private static AvaloniaObject MakeMenu(int expectedParameter, Action<object> action, Window root)
- {
- var menuitem = new MenuItem()
- {
- Command = new Command(action),
- CommandParameter = expectedParameter,
- };
- var rootMenu = new Menu();
- rootMenu.Items.Add(menuitem);
- root.Content = rootMenu;
- return menuitem;
- }
- private static AvaloniaObject MakeButton(int expectedParameter, Action<object> action, Window root)
- {
- var button = new Button()
- {
- Command = new Command(action),
- CommandParameter = expectedParameter,
- };
- root.Content = button;
- return button;
- }
- private static AvaloniaObject MakeMenuWithoutCommand(int expectedParameter, Action<object> action, Window root)
- {
- var menuitem = new MenuItem()
- {
- };
- var rootMenu = new Menu();
- rootMenu.Items.Add(menuitem);
- root.Content = rootMenu;
- return menuitem;
- }
- private static AvaloniaObject MakeButtonWithoutCommand(int expectedParameter, Action<object> action, Window root)
- {
- var button = new Button()
- {
- };
- root.Content = button;
- return button;
- }
- private static FuncControlTemplate CreateWindowTemplate()
- {
- return new FuncControlTemplate<Window>((parent, scope) =>
- {
- return new ContentPresenter
- {
- Name = "PART_ContentPresenter",
- [~ContentPresenter.ContentProperty] = parent[~ContentControl.ContentProperty],
- }.RegisterInNameScope(scope);
- });
- }
- class Command : System.Windows.Input.ICommand
- {
- private readonly Action<object> _execeute;
- #pragma warning disable 67 // Event not used
- public event EventHandler CanExecuteChanged;
- #pragma warning restore 67 // Event not used
- public Command(Action<object> execeute)
- {
- _execeute = execeute;
- }
- public bool CanExecute(object parameter) => true;
- public void Execute(object parameter) => _execeute?.Invoke(parameter);
- }
- }
- }
|