ButtonKeyAssigner.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. using Avalonia.Controls;
  2. using Avalonia.Controls.Primitives;
  3. using Avalonia.LogicalTree;
  4. using Avalonia.Threading;
  5. using Ryujinx.Input;
  6. using Ryujinx.Input.Assigner;
  7. using System;
  8. using System.Linq;
  9. using System.Threading.Tasks;
  10. namespace Ryujinx.Ava.UI.Helpers
  11. {
  12. internal class ButtonKeyAssigner
  13. {
  14. internal class ButtonAssignedEventArgs : EventArgs
  15. {
  16. public ToggleButton Button { get; }
  17. public bool IsAssigned { get; }
  18. public ButtonAssignedEventArgs(ToggleButton button, bool isAssigned)
  19. {
  20. Button = button;
  21. IsAssigned = isAssigned;
  22. }
  23. }
  24. public ToggleButton ToggledButton { get; set; }
  25. private bool _isWaitingForInput;
  26. private bool _shouldUnbind;
  27. public event EventHandler<ButtonAssignedEventArgs> ButtonAssigned;
  28. public ButtonKeyAssigner(ToggleButton toggleButton)
  29. {
  30. ToggledButton = toggleButton;
  31. }
  32. public async void GetInputAndAssign(IButtonAssigner assigner, IKeyboard keyboard = null)
  33. {
  34. Dispatcher.UIThread.Post(() =>
  35. {
  36. ToggledButton.IsChecked = true;
  37. });
  38. if (_isWaitingForInput)
  39. {
  40. Dispatcher.UIThread.Post(() =>
  41. {
  42. Cancel();
  43. });
  44. return;
  45. }
  46. _isWaitingForInput = true;
  47. assigner.Initialize();
  48. await Task.Run(async () =>
  49. {
  50. while (true)
  51. {
  52. if (!_isWaitingForInput)
  53. {
  54. return;
  55. }
  56. await Task.Delay(10);
  57. assigner.ReadInput();
  58. if (assigner.HasAnyButtonPressed() || assigner.ShouldCancel() || (keyboard != null && keyboard.IsPressed(Key.Escape)))
  59. {
  60. break;
  61. }
  62. }
  63. });
  64. await Dispatcher.UIThread.InvokeAsync(() =>
  65. {
  66. string pressedButton = assigner.GetPressedButton();
  67. if (_shouldUnbind)
  68. {
  69. SetButtonText(ToggledButton, "Unbound");
  70. }
  71. else if (pressedButton != "")
  72. {
  73. SetButtonText(ToggledButton, pressedButton);
  74. }
  75. _shouldUnbind = false;
  76. _isWaitingForInput = false;
  77. ToggledButton.IsChecked = false;
  78. ButtonAssigned?.Invoke(this, new ButtonAssignedEventArgs(ToggledButton, pressedButton != null));
  79. static void SetButtonText(ToggleButton button, string text)
  80. {
  81. ILogical textBlock = button.GetLogicalDescendants().First(x => x is TextBlock);
  82. if (textBlock != null && textBlock is TextBlock block)
  83. {
  84. block.Text = text;
  85. }
  86. }
  87. });
  88. }
  89. public void Cancel(bool shouldUnbind = false)
  90. {
  91. _isWaitingForInput = false;
  92. ToggledButton.IsChecked = false;
  93. _shouldUnbind = shouldUnbind;
  94. }
  95. }
  96. }