This is an attempt to decouple "saving gamepad settings" from the rest of the emulator settings. Should fix the issue where the gamepad was not detected when starting the emulator and the game (usually after saving settings with the gamepad turned off)
211 lines
9.1 KiB
C#
211 lines
9.1 KiB
C#
using Avalonia;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Controls.Primitives;
|
|
using Avalonia.Input;
|
|
using Avalonia.Interactivity;
|
|
using Avalonia.LogicalTree;
|
|
using Ryujinx.Ava.UI.Helpers;
|
|
using Ryujinx.Ava.UI.ViewModels.Input;
|
|
using Ryujinx.Input;
|
|
using Ryujinx.Input.Assigner;
|
|
using Button = Ryujinx.Input.Button;
|
|
using Key = Ryujinx.Common.Configuration.Hid.Key;
|
|
|
|
namespace Ryujinx.Ava.UI.Views.Input
|
|
{
|
|
public partial class KeyboardInputView : UserControl
|
|
{
|
|
private ButtonKeyAssigner _currentAssigner;
|
|
|
|
public KeyboardInputView()
|
|
{
|
|
InitializeComponent();
|
|
|
|
foreach (ILogical visual in SettingButtons.GetLogicalDescendants())
|
|
{
|
|
if (visual is ToggleButton button and not CheckBox)
|
|
{
|
|
button.IsCheckedChanged += Button_IsCheckedChanged;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override void OnPointerReleased(PointerReleasedEventArgs e)
|
|
{
|
|
base.OnPointerReleased(e);
|
|
|
|
if (_currentAssigner is { ToggledButton.IsPointerOver: false })
|
|
{
|
|
_currentAssigner.Cancel();
|
|
}
|
|
}
|
|
|
|
private void Button_IsCheckedChanged(object sender, RoutedEventArgs e)
|
|
{
|
|
if (sender is not ToggleButton button)
|
|
return;
|
|
|
|
if (button.IsChecked is true)
|
|
{
|
|
if (_currentAssigner != null && button == _currentAssigner.ToggledButton)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (_currentAssigner == null)
|
|
{
|
|
_currentAssigner = new ButtonKeyAssigner(button);
|
|
|
|
Focus(NavigationMethod.Pointer);
|
|
|
|
PointerPressed += MouseClick;
|
|
|
|
FlagInputConfigChanged();
|
|
|
|
if (DataContext is not KeyboardInputViewModel viewModel)
|
|
return;
|
|
|
|
IKeyboard keyboard =
|
|
(IKeyboard)viewModel.ParentModel.AvaloniaKeyboardDriver.GetGamepad("0"); // Open Avalonia keyboard for cancel operations.
|
|
IButtonAssigner assigner =
|
|
new KeyboardKeyAssigner((IKeyboard)viewModel.ParentModel.SelectedGamepad);
|
|
|
|
_currentAssigner.ButtonAssigned += (_, e) =>
|
|
{
|
|
if (e.ButtonValue.HasValue)
|
|
{
|
|
Button buttonValue = e.ButtonValue.Value;
|
|
viewModel.ParentModel.IsModified = true;
|
|
|
|
switch (button.Name)
|
|
{
|
|
case "ButtonZl":
|
|
viewModel.Config.ButtonZl = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "ButtonL":
|
|
viewModel.Config.ButtonL = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "ButtonMinus":
|
|
viewModel.Config.ButtonMinus = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "LeftStickButton":
|
|
viewModel.Config.LeftStickButton = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "LeftStickUp":
|
|
viewModel.Config.LeftStickUp = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "LeftStickDown":
|
|
viewModel.Config.LeftStickDown = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "LeftStickRight":
|
|
viewModel.Config.LeftStickRight = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "LeftStickLeft":
|
|
viewModel.Config.LeftStickLeft = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "DpadUp":
|
|
viewModel.Config.DpadUp = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "DpadDown":
|
|
viewModel.Config.DpadDown = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "DpadLeft":
|
|
viewModel.Config.DpadLeft = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "DpadRight":
|
|
viewModel.Config.DpadRight = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "LeftButtonSr":
|
|
viewModel.Config.LeftButtonSr = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "LeftButtonSl":
|
|
viewModel.Config.LeftButtonSl = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "RightButtonSr":
|
|
viewModel.Config.RightButtonSr = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "RightButtonSl":
|
|
viewModel.Config.RightButtonSl = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "ButtonZr":
|
|
viewModel.Config.ButtonZr = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "ButtonR":
|
|
viewModel.Config.ButtonR = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "ButtonPlus":
|
|
viewModel.Config.ButtonPlus = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "ButtonA":
|
|
viewModel.Config.ButtonA = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "ButtonB":
|
|
viewModel.Config.ButtonB = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "ButtonX":
|
|
viewModel.Config.ButtonX = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "ButtonY":
|
|
viewModel.Config.ButtonY = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "RightStickButton":
|
|
viewModel.Config.RightStickButton = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "RightStickUp":
|
|
viewModel.Config.RightStickUp = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "RightStickDown":
|
|
viewModel.Config.RightStickDown = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "RightStickRight":
|
|
viewModel.Config.RightStickRight = buttonValue.AsHidType<Key>();
|
|
break;
|
|
case "RightStickLeft":
|
|
viewModel.Config.RightStickLeft = buttonValue.AsHidType<Key>();
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
_currentAssigner.GetInputAndAssign(assigner, keyboard);
|
|
}
|
|
else
|
|
{
|
|
if (_currentAssigner != null)
|
|
{
|
|
_currentAssigner.Cancel();
|
|
_currentAssigner = null;
|
|
button.IsChecked = false;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_currentAssigner?.Cancel();
|
|
_currentAssigner = null;
|
|
}
|
|
}
|
|
|
|
private void FlagInputConfigChanged()
|
|
{
|
|
(DataContext as KeyboardInputViewModel)!.ParentModel.IsInputConfigChanged = true;
|
|
}
|
|
|
|
private void MouseClick(object sender, PointerPressedEventArgs e)
|
|
{
|
|
bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed;
|
|
|
|
_currentAssigner?.Cancel(shouldUnbind);
|
|
|
|
PointerPressed -= MouseClick;
|
|
}
|
|
|
|
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
|
|
{
|
|
base.OnDetachedFromVisualTree(e);
|
|
_currentAssigner?.Cancel();
|
|
_currentAssigner = null;
|
|
}
|
|
}
|
|
}
|