ControllerInputView.axaml.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. using Avalonia;
  2. using Avalonia.Controls;
  3. using Avalonia.Controls.Primitives;
  4. using Avalonia.Input;
  5. using Avalonia.Interactivity;
  6. using Avalonia.LogicalTree;
  7. using DiscordRPC;
  8. using Ryujinx.Ava.UI.Helpers;
  9. using Ryujinx.Ava.UI.ViewModels.Input;
  10. using Ryujinx.Common.Configuration.Hid.Controller;
  11. using Ryujinx.Common.Logging;
  12. using Ryujinx.Input;
  13. using Ryujinx.Input.Assigner;
  14. using System;
  15. using StickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
  16. namespace Ryujinx.Ava.UI.Views.Input
  17. {
  18. public partial class ControllerInputView : UserControl
  19. {
  20. private ButtonKeyAssigner _currentAssigner;
  21. public ControllerInputView()
  22. {
  23. InitializeComponent();
  24. foreach (ILogical visual in SettingButtons.GetLogicalDescendants())
  25. {
  26. if (visual is ToggleButton button and not CheckBox)
  27. {
  28. button.IsCheckedChanged += Button_IsCheckedChanged;
  29. }
  30. if (visual is CheckBox check)
  31. {
  32. check.IsCheckedChanged += CheckBox_IsCheckedChanged;
  33. }
  34. if (visual is Slider slider)
  35. {
  36. slider.PropertyChanged += Slider_IsCheckedChanged;
  37. }
  38. }
  39. }
  40. protected override void OnPointerReleased(PointerReleasedEventArgs e)
  41. {
  42. base.OnPointerReleased(e);
  43. if (_currentAssigner != null && _currentAssigner.ToggledButton != null && !_currentAssigner.ToggledButton.IsPointerOver)
  44. {
  45. _currentAssigner.Cancel();
  46. }
  47. }
  48. private float _changeSlider = -1.0f;
  49. private void Slider_IsCheckedChanged(object sender, AvaloniaPropertyChangedEventArgs e)
  50. {
  51. if (sender is Slider check)
  52. {
  53. if ((bool)check.IsPointerOver && _changeSlider == -1.0f)
  54. {
  55. _changeSlider = (float)check.Value;
  56. }
  57. else if (!(bool)check.IsPointerOver)
  58. {
  59. _changeSlider = -1.0f;
  60. }
  61. if (_changeSlider != -1.0f && _changeSlider != (float)check.Value)
  62. {
  63. var viewModel = (DataContext as ControllerInputViewModel);
  64. viewModel.ParentModel.IsModified = true;
  65. _changeSlider = (float)check.Value;
  66. }
  67. }
  68. }
  69. private void CheckBox_IsCheckedChanged(object sender, RoutedEventArgs e)
  70. {
  71. if (sender is CheckBox check)
  72. {
  73. if ((bool)check.IsPointerOver)
  74. {
  75. var viewModel = (DataContext as ControllerInputViewModel);
  76. viewModel.ParentModel.IsModified = true;
  77. _currentAssigner?.Cancel();
  78. _currentAssigner = null;
  79. }
  80. }
  81. }
  82. private void Button_IsCheckedChanged(object sender, RoutedEventArgs e)
  83. {
  84. if (sender is ToggleButton button )
  85. {
  86. if ((bool)button.IsChecked)
  87. {
  88. if (_currentAssigner != null && button == _currentAssigner.ToggledButton)
  89. {
  90. return;
  91. }
  92. bool isStick = button.Tag != null && button.Tag.ToString() == "stick";
  93. if (_currentAssigner == null)
  94. {
  95. _currentAssigner = new ButtonKeyAssigner(button);
  96. this.Focus(NavigationMethod.Pointer);
  97. PointerPressed += MouseClick;
  98. var viewModel = (DataContext as ControllerInputViewModel);
  99. IKeyboard keyboard = (IKeyboard)viewModel.ParentModel.AvaloniaKeyboardDriver.GetGamepad("0"); // Open Avalonia keyboard for cancel operations.
  100. IButtonAssigner assigner = CreateButtonAssigner(isStick);
  101. _currentAssigner.ButtonAssigned += (sender, e) =>
  102. {
  103. if (e.ButtonValue.HasValue)
  104. {
  105. var buttonValue = e.ButtonValue.Value;
  106. viewModel.ParentModel.IsModified = true;
  107. switch (button.Name)
  108. {
  109. case "ButtonZl":
  110. viewModel.Config.ButtonZl = buttonValue.AsHidType<GamepadInputId>();
  111. break;
  112. case "ButtonL":
  113. viewModel.Config.ButtonL = buttonValue.AsHidType<GamepadInputId>();
  114. break;
  115. case "ButtonMinus":
  116. viewModel.Config.ButtonMinus = buttonValue.AsHidType<GamepadInputId>();
  117. break;
  118. case "LeftStickButton":
  119. viewModel.Config.LeftStickButton = buttonValue.AsHidType<GamepadInputId>();
  120. break;
  121. case "LeftJoystick":
  122. viewModel.Config.LeftJoystick = buttonValue.AsHidType<StickInputId>();
  123. break;
  124. case "DpadUp":
  125. viewModel.Config.DpadUp = buttonValue.AsHidType<GamepadInputId>();
  126. break;
  127. case "DpadDown":
  128. viewModel.Config.DpadDown = buttonValue.AsHidType<GamepadInputId>();
  129. break;
  130. case "DpadLeft":
  131. viewModel.Config.DpadLeft = buttonValue.AsHidType<GamepadInputId>();
  132. break;
  133. case "DpadRight":
  134. viewModel.Config.DpadRight = buttonValue.AsHidType<GamepadInputId>();
  135. break;
  136. case "LeftButtonSr":
  137. viewModel.Config.LeftButtonSr = buttonValue.AsHidType<GamepadInputId>();
  138. break;
  139. case "LeftButtonSl":
  140. viewModel.Config.LeftButtonSl = buttonValue.AsHidType<GamepadInputId>();
  141. break;
  142. case "RightButtonSr":
  143. viewModel.Config.RightButtonSr = buttonValue.AsHidType<GamepadInputId>();
  144. break;
  145. case "RightButtonSl":
  146. viewModel.Config.RightButtonSl = buttonValue.AsHidType<GamepadInputId>();
  147. break;
  148. case "ButtonZr":
  149. viewModel.Config.ButtonZr = buttonValue.AsHidType<GamepadInputId>();
  150. break;
  151. case "ButtonR":
  152. viewModel.Config.ButtonR = buttonValue.AsHidType<GamepadInputId>();
  153. break;
  154. case "ButtonPlus":
  155. viewModel.Config.ButtonPlus = buttonValue.AsHidType<GamepadInputId>();
  156. break;
  157. case "ButtonA":
  158. viewModel.Config.ButtonA = buttonValue.AsHidType<GamepadInputId>();
  159. break;
  160. case "ButtonB":
  161. viewModel.Config.ButtonB = buttonValue.AsHidType<GamepadInputId>();
  162. break;
  163. case "ButtonX":
  164. viewModel.Config.ButtonX = buttonValue.AsHidType<GamepadInputId>();
  165. break;
  166. case "ButtonY":
  167. viewModel.Config.ButtonY = buttonValue.AsHidType<GamepadInputId>();
  168. break;
  169. case "RightStickButton":
  170. viewModel.Config.RightStickButton = buttonValue.AsHidType<GamepadInputId>();
  171. break;
  172. case "RightJoystick":
  173. viewModel.Config.RightJoystick = buttonValue.AsHidType<StickInputId>();
  174. break;
  175. }
  176. }
  177. };
  178. _currentAssigner.GetInputAndAssign(assigner, keyboard);
  179. }
  180. else
  181. {
  182. if (_currentAssigner != null )
  183. {
  184. _currentAssigner.Cancel();
  185. _currentAssigner = null;
  186. button.IsChecked = false;
  187. }
  188. }
  189. }
  190. else
  191. {
  192. _currentAssigner?.Cancel();
  193. _currentAssigner = null;
  194. }
  195. }
  196. }
  197. private void MouseClick(object sender, PointerPressedEventArgs e)
  198. {
  199. bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed;
  200. _currentAssigner?.Cancel(shouldUnbind);
  201. PointerPressed -= MouseClick;
  202. }
  203. private IButtonAssigner CreateButtonAssigner(bool forStick)
  204. {
  205. IButtonAssigner assigner;
  206. var controllerInputViewModel = DataContext as ControllerInputViewModel;
  207. assigner = new GamepadButtonAssigner(
  208. controllerInputViewModel.ParentModel.SelectedGamepad,
  209. (controllerInputViewModel.ParentModel.Config as StandardControllerInputConfig).TriggerThreshold,
  210. forStick);
  211. return assigner;
  212. }
  213. protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
  214. {
  215. base.OnDetachedFromVisualTree(e);
  216. _currentAssigner?.Cancel();
  217. _currentAssigner = null;
  218. }
  219. }
  220. }