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