using Avalonia.Controls; using Avalonia.Controls.Primitives; using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.LogicalTree; using Ryujinx.Ava.Input; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.ViewModels; using Ryujinx.Input; using Ryujinx.Input.Assigner; using Key = Ryujinx.Common.Configuration.Hid.Key; namespace Ryujinx.Ava.UI.Views.Settings { public partial class SettingsHotkeysView : UserControl { private ButtonKeyAssigner _currentAssigner; private readonly IGamepadDriver _avaloniaKeyboardDriver; public SettingsHotkeysView() { InitializeComponent(); foreach (ILogical visual in SettingButtons.GetLogicalDescendants()) { if (visual is ToggleButton button and not CheckBox) { button.IsCheckedChanged += Button_IsCheckedChanged; } } _avaloniaKeyboardDriver = new AvaloniaKeyboardDriver(this); } protected override void OnPointerReleased(PointerReleasedEventArgs e) { base.OnPointerReleased(e); if (!_currentAssigner?.ToggledButton?.IsPointerOver ?? false) { _currentAssigner.Cancel(); } } private void MouseClick(object sender, PointerPressedEventArgs e) { bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed; _currentAssigner?.Cancel(shouldUnbind); PointerPressed -= MouseClick; } private void Button_IsCheckedChanged(object sender, RoutedEventArgs e) { if (sender is ToggleButton button) { if ((bool)button.IsChecked) { if (_currentAssigner != null && button == _currentAssigner.ToggledButton) { return; } if (_currentAssigner == null) { _currentAssigner = new ButtonKeyAssigner(button); this.Focus(NavigationMethod.Pointer); PointerPressed += MouseClick; var keyboard = (IKeyboard)_avaloniaKeyboardDriver.GetGamepad("0"); IButtonAssigner assigner = new KeyboardKeyAssigner(keyboard); _currentAssigner.ButtonAssigned += (sender, e) => { if (e.ButtonValue.HasValue) { var viewModel = (DataContext) as SettingsViewModel; var buttonValue = e.ButtonValue.Value; switch (button.Name) { case "ToggleVsync": viewModel.KeyboardHotkey.ToggleVsync = buttonValue.AsHidType(); break; case "Screenshot": viewModel.KeyboardHotkey.Screenshot = buttonValue.AsHidType(); break; case "ShowUI": viewModel.KeyboardHotkey.ShowUI = buttonValue.AsHidType(); break; case "Pause": viewModel.KeyboardHotkey.Pause = buttonValue.AsHidType(); break; case "ToggleMute": viewModel.KeyboardHotkey.ToggleMute = buttonValue.AsHidType(); break; case "ResScaleUp": viewModel.KeyboardHotkey.ResScaleUp = buttonValue.AsHidType(); break; case "ResScaleDown": viewModel.KeyboardHotkey.ResScaleDown = buttonValue.AsHidType(); break; case "VolumeUp": viewModel.KeyboardHotkey.VolumeUp = buttonValue.AsHidType(); break; case "VolumeDown": viewModel.KeyboardHotkey.VolumeDown = buttonValue.AsHidType(); break; } } }; _currentAssigner.GetInputAndAssign(assigner, keyboard); } else { if (_currentAssigner != null) { _currentAssigner.Cancel(); _currentAssigner = null; button.IsChecked = false; } } } else { _currentAssigner?.Cancel(); _currentAssigner = null; } } } public void Dispose() { _currentAssigner?.Cancel(); _currentAssigner = null; _avaloniaKeyboardDriver.Dispose(); } } }