diff --git a/src/Ryujinx.Ava/Assets/Locales/en_US.json b/src/Ryujinx.Ava/Assets/Locales/en_US.json
index a67b796bd0..fc65fe4a09 100644
--- a/src/Ryujinx.Ava/Assets/Locales/en_US.json
+++ b/src/Ryujinx.Ava/Assets/Locales/en_US.json
@@ -263,6 +263,105 @@
"ControllerSettingsMotionGyroDeadzone": "Gyro Deadzone:",
"ControllerSettingsSave": "Save",
"ControllerSettingsClose": "Close",
+ "KeyUnknown": "Unknown",
+ "KeyShiftLeft": "Shift Left",
+ "KeyShiftRight": "Shift Right",
+ "KeyControlLeft": "Control Left",
+ "KeyControlRight": "Control Right",
+ "KeyAltLeft": "Alt Left",
+ "KeyAltRight": "Alt Right",
+ "KeyOptLeft": "⌥ Left",
+ "KeyOptRight": "⌥ Right",
+ "KeyWinLeft": "⊞ Left",
+ "KeyWinRight": "⊞ Right",
+ "KeyCmdLeft": "⌘ Left",
+ "KeyCmdRight": "⌘ Right",
+ "KeyMenu": "Menu",
+ "KeyUp": "Up",
+ "KeyDown": "Down",
+ "KeyLeft": "Left",
+ "KeyRight": "Right",
+ "KeyEnter": "Enter",
+ "KeyEscape": "Escape",
+ "KeySpace": "Space",
+ "KeyTab": "Tab",
+ "KeyBackSpace": "Backspace",
+ "KeyInsert": "Insert",
+ "KeyDelete": "Delete",
+ "KeyPageUp": "Page Up",
+ "KeyPageDown": "Page Down",
+ "KeyHome": "Home",
+ "KeyEnd": "End",
+ "KeyCapsLock": "Caps Lock",
+ "KeyScrollLock": "Scroll Lock",
+ "KeyPrintScreen": "Print Screen",
+ "KeyPause": "Pause",
+ "KeyNumLock": "Num Lock",
+ "KeyClear": "Clear",
+ "KeyKeypad0": "Keypad 0",
+ "KeyKeypad1": "Keypad 1",
+ "KeyKeypad2": "Keypad 2",
+ "KeyKeypad3": "Keypad 3",
+ "KeyKeypad4": "Keypad 4",
+ "KeyKeypad5": "Keypad 5",
+ "KeyKeypad6": "Keypad 6",
+ "KeyKeypad7": "Keypad 7",
+ "KeyKeypad8": "Keypad 8",
+ "KeyKeypad9": "Keypad 9",
+ "KeyKeypadDivide": "Keypad Divide",
+ "KeyKeypadMultiply": "Keypad Multiply",
+ "KeyKeypadSubtract": "Keypad Subtract",
+ "KeyKeypadAdd": "Keypad Add",
+ "KeyKeypadDecimal": "Keypad Decimal",
+ "KeyKeypadEnter": "Keypad Enter",
+ "KeyNumber0": "0",
+ "KeyNumber1": "1",
+ "KeyNumber2": "2",
+ "KeyNumber3": "3",
+ "KeyNumber4": "4",
+ "KeyNumber5": "5",
+ "KeyNumber6": "6",
+ "KeyNumber7": "7",
+ "KeyNumber8": "8",
+ "KeyNumber9": "9",
+ "KeyTilde": "~",
+ "KeyGrave": "`",
+ "KeyMinus": "-",
+ "KeyPlus": "+",
+ "KeyBracketLeft": "[",
+ "KeyBracketRight": "]",
+ "KeySemicolon": ";",
+ "KeyQuote": "\"",
+ "KeyComma": ",",
+ "KeyPeriod": ".",
+ "KeySlash": "/",
+ "KeyBackSlash": "\\",
+ "KeyUnbound": "Unbound",
+ "GamepadLeftStick": "Left Stick Button",
+ "GamepadRightStick": "Right Stick Button",
+ "GamepadLeftShoulder": "Left Shoulder",
+ "GamepadRightShoulder": "Right Shoulder",
+ "GamepadLeftTrigger": "Left Trigger",
+ "GamepadRightTrigger": "Right Trigger",
+ "GamepadDpadUp": "Up",
+ "GamepadDpadDown": "Down",
+ "GamepadDpadLeft": "Left",
+ "GamepadDpadRight": "Right",
+ "GamepadMinus": "-",
+ "GamepadPlus": "+",
+ "GamepadGuide": "Guide",
+ "GamepadMisc1": "Misc",
+ "GamepadPaddle1": "Paddle 1",
+ "GamepadPaddle2": "Paddle 2",
+ "GamepadPaddle3": "Paddle 3",
+ "GamepadPaddle4": "Paddle 4",
+ "GamepadTouchpad": "Touchpad",
+ "GamepadSingleLeftTrigger0": "Left Trigger 0",
+ "GamepadSingleRightTrigger0": "Right Trigger 0",
+ "GamepadSingleLeftTrigger1": "Left Trigger 1",
+ "GamepadSingleRightTrigger1": "Right Trigger 1",
+ "StickLeft": "Left Stick",
+ "StickRight": "Right Stick",
"UserProfilesSelectedUserProfile": "Selected User Profile:",
"UserProfilesSaveProfileName": "Save Profile Name",
"UserProfilesChangeProfileImage": "Change Profile Image",
diff --git a/src/Ryujinx.Ava/Assets/Styles/Styles.xaml b/src/Ryujinx.Ava/Assets/Styles/Styles.xaml
index f7f64be22f..b3a6f59c8d 100644
--- a/src/Ryujinx.Ava/Assets/Styles/Styles.xaml
+++ b/src/Ryujinx.Ava/Assets/Styles/Styles.xaml
@@ -15,8 +15,7 @@
@@ -393,4 +392,4 @@
600
756
-
\ No newline at end of file
+
diff --git a/src/Ryujinx.Ava/UI/Helpers/ButtonKeyAssigner.cs b/src/Ryujinx.Ava/UI/Helpers/ButtonKeyAssigner.cs
index 7e8ba73421..54e0918a50 100644
--- a/src/Ryujinx.Ava/UI/Helpers/ButtonKeyAssigner.cs
+++ b/src/Ryujinx.Ava/UI/Helpers/ButtonKeyAssigner.cs
@@ -1,11 +1,8 @@
-using Avalonia.Controls;
using Avalonia.Controls.Primitives;
-using Avalonia.LogicalTree;
using Avalonia.Threading;
using Ryujinx.Input;
using Ryujinx.Input.Assigner;
using System;
-using System.Linq;
using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Helpers
@@ -15,12 +12,12 @@ namespace Ryujinx.Ava.UI.Helpers
internal class ButtonAssignedEventArgs : EventArgs
{
public ToggleButton Button { get; }
- public bool IsAssigned { get; }
+ public ButtonValue? ButtonValue { get; }
- public ButtonAssignedEventArgs(ToggleButton button, bool isAssigned)
+ public ButtonAssignedEventArgs(ToggleButton button, ButtonValue? buttonValue)
{
Button = button;
- IsAssigned = isAssigned;
+ ButtonValue = buttonValue;
}
}
@@ -78,15 +75,11 @@ namespace Ryujinx.Ava.UI.Helpers
await Dispatcher.UIThread.InvokeAsync(() =>
{
- string pressedButton = assigner.GetPressedButton();
+ ButtonValue? pressedButton = assigner.GetPressedButton();
if (_shouldUnbind)
{
- SetButtonText(ToggledButton, "Unbound");
- }
- else if (pressedButton != "")
- {
- SetButtonText(ToggledButton, pressedButton);
+ pressedButton = null;
}
_shouldUnbind = false;
@@ -94,17 +87,8 @@ namespace Ryujinx.Ava.UI.Helpers
ToggledButton.IsChecked = false;
- ButtonAssigned?.Invoke(this, new ButtonAssignedEventArgs(ToggledButton, pressedButton != null));
+ ButtonAssigned?.Invoke(this, new ButtonAssignedEventArgs(ToggledButton, pressedButton));
- static void SetButtonText(ToggleButton button, string text)
- {
- ILogical textBlock = button.GetLogicalDescendants().First(x => x is TextBlock);
-
- if (textBlock != null && textBlock is TextBlock block)
- {
- block.Text = text;
- }
- }
});
}
diff --git a/src/Ryujinx.Ava/UI/Helpers/KeyValueConverter.cs b/src/Ryujinx.Ava/UI/Helpers/KeyValueConverter.cs
index 028ed6bf46..1c4aa7b21f 100644
--- a/src/Ryujinx.Ava/UI/Helpers/KeyValueConverter.cs
+++ b/src/Ryujinx.Ava/UI/Helpers/KeyValueConverter.cs
@@ -1,7 +1,9 @@
using Avalonia.Data.Converters;
+using Ryujinx.Ava.Common.Locale;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Configuration.Hid.Controller;
using System;
+using System.Collections.Generic;
using System.Globalization;
namespace Ryujinx.Ava.UI.Helpers
@@ -10,37 +12,158 @@ namespace Ryujinx.Ava.UI.Helpers
{
public static KeyValueConverter Instance = new();
+ private static readonly Dictionary _keysMap = new()
+ {
+ { Key.Unknown, LocaleKeys.KeyUnknown },
+ { Key.ShiftLeft, LocaleKeys.KeyShiftLeft },
+ { Key.ShiftRight, LocaleKeys.KeyShiftRight },
+ { Key.ControlLeft, LocaleKeys.KeyControlLeft },
+ { Key.ControlRight, LocaleKeys.KeyControlRight },
+ { Key.AltLeft, OperatingSystem.IsMacOS() ? LocaleKeys.KeyOptLeft : LocaleKeys.KeyAltLeft },
+ { Key.AltRight, OperatingSystem.IsMacOS() ? LocaleKeys.KeyOptRight : LocaleKeys.KeyAltRight },
+ { Key.WinLeft, OperatingSystem.IsMacOS() ? LocaleKeys.KeyCmdLeft : LocaleKeys.KeyWinLeft },
+ { Key.WinRight, OperatingSystem.IsMacOS() ? LocaleKeys.KeyCmdRight : LocaleKeys.KeyWinRight },
+ { Key.Up, LocaleKeys.KeyUp },
+ { Key.Down, LocaleKeys.KeyDown },
+ { Key.Left, LocaleKeys.KeyLeft },
+ { Key.Right, LocaleKeys.KeyRight },
+ { Key.Enter, LocaleKeys.KeyEnter },
+ { Key.Escape, LocaleKeys.KeyEscape },
+ { Key.Space, LocaleKeys.KeySpace },
+ { Key.Tab, LocaleKeys.KeyTab },
+ { Key.BackSpace, LocaleKeys.KeyBackSpace },
+ { Key.Insert, LocaleKeys.KeyInsert },
+ { Key.Delete, LocaleKeys.KeyDelete },
+ { Key.PageUp, LocaleKeys.KeyPageUp },
+ { Key.PageDown, LocaleKeys.KeyPageDown },
+ { Key.Home, LocaleKeys.KeyHome },
+ { Key.End, LocaleKeys.KeyEnd },
+ { Key.CapsLock, LocaleKeys.KeyCapsLock },
+ { Key.ScrollLock, LocaleKeys.KeyScrollLock },
+ { Key.PrintScreen, LocaleKeys.KeyPrintScreen },
+ { Key.Pause, LocaleKeys.KeyPause },
+ { Key.NumLock, LocaleKeys.KeyNumLock },
+ { Key.Clear, LocaleKeys.KeyClear },
+ { Key.Keypad0, LocaleKeys.KeyKeypad0 },
+ { Key.Keypad1, LocaleKeys.KeyKeypad1 },
+ { Key.Keypad2, LocaleKeys.KeyKeypad2 },
+ { Key.Keypad3, LocaleKeys.KeyKeypad3 },
+ { Key.Keypad4, LocaleKeys.KeyKeypad4 },
+ { Key.Keypad5, LocaleKeys.KeyKeypad5 },
+ { Key.Keypad6, LocaleKeys.KeyKeypad6 },
+ { Key.Keypad7, LocaleKeys.KeyKeypad7 },
+ { Key.Keypad8, LocaleKeys.KeyKeypad8 },
+ { Key.Keypad9, LocaleKeys.KeyKeypad9 },
+ { Key.KeypadDivide, LocaleKeys.KeyKeypadDivide },
+ { Key.KeypadMultiply, LocaleKeys.KeyKeypadMultiply },
+ { Key.KeypadSubtract, LocaleKeys.KeyKeypadSubtract },
+ { Key.KeypadAdd, LocaleKeys.KeyKeypadAdd },
+ { Key.KeypadDecimal, LocaleKeys.KeyKeypadDecimal },
+ { Key.KeypadEnter, LocaleKeys.KeyKeypadEnter },
+ { Key.Number0, LocaleKeys.KeyNumber0 },
+ { Key.Number1, LocaleKeys.KeyNumber1 },
+ { Key.Number2, LocaleKeys.KeyNumber2 },
+ { Key.Number3, LocaleKeys.KeyNumber3 },
+ { Key.Number4, LocaleKeys.KeyNumber4 },
+ { Key.Number5, LocaleKeys.KeyNumber5 },
+ { Key.Number6, LocaleKeys.KeyNumber6 },
+ { Key.Number7, LocaleKeys.KeyNumber7 },
+ { Key.Number8, LocaleKeys.KeyNumber8 },
+ { Key.Number9, LocaleKeys.KeyNumber9 },
+ { Key.Tilde, LocaleKeys.KeyTilde },
+ { Key.Grave, LocaleKeys.KeyGrave },
+ { Key.Minus, LocaleKeys.KeyMinus },
+ { Key.Plus, LocaleKeys.KeyPlus },
+ { Key.BracketLeft, LocaleKeys.KeyBracketLeft },
+ { Key.BracketRight, LocaleKeys.KeyBracketRight },
+ { Key.Semicolon, LocaleKeys.KeySemicolon },
+ { Key.Quote, LocaleKeys.KeyQuote },
+ { Key.Comma, LocaleKeys.KeyComma },
+ { Key.Period, LocaleKeys.KeyPeriod },
+ { Key.Slash, LocaleKeys.KeySlash },
+ { Key.BackSlash, LocaleKeys.KeyBackSlash },
+ { Key.Unbound, LocaleKeys.KeyUnbound },
+ };
+
+ private static readonly Dictionary _gamepadInputIdMap = new()
+ {
+ { GamepadInputId.LeftStick, LocaleKeys.GamepadLeftStick },
+ { GamepadInputId.RightStick, LocaleKeys.GamepadRightStick },
+ { GamepadInputId.LeftShoulder, LocaleKeys.GamepadLeftShoulder },
+ { GamepadInputId.RightShoulder, LocaleKeys.GamepadRightShoulder },
+ { GamepadInputId.LeftTrigger, LocaleKeys.GamepadLeftTrigger },
+ { GamepadInputId.RightTrigger, LocaleKeys.GamepadRightTrigger },
+ { GamepadInputId.DpadUp, LocaleKeys.GamepadDpadUp},
+ { GamepadInputId.DpadDown, LocaleKeys.GamepadDpadDown},
+ { GamepadInputId.DpadLeft, LocaleKeys.GamepadDpadLeft},
+ { GamepadInputId.DpadRight, LocaleKeys.GamepadDpadRight},
+ { GamepadInputId.Minus, LocaleKeys.GamepadMinus},
+ { GamepadInputId.Plus, LocaleKeys.GamepadPlus},
+ { GamepadInputId.Guide, LocaleKeys.GamepadGuide},
+ { GamepadInputId.Misc1, LocaleKeys.GamepadMisc1},
+ { GamepadInputId.Paddle1, LocaleKeys.GamepadPaddle1},
+ { GamepadInputId.Paddle2, LocaleKeys.GamepadPaddle2},
+ { GamepadInputId.Paddle3, LocaleKeys.GamepadPaddle3},
+ { GamepadInputId.Paddle4, LocaleKeys.GamepadPaddle4},
+ { GamepadInputId.Touchpad, LocaleKeys.GamepadTouchpad},
+ { GamepadInputId.SingleLeftTrigger0, LocaleKeys.GamepadSingleLeftTrigger0},
+ { GamepadInputId.SingleRightTrigger0, LocaleKeys.GamepadSingleRightTrigger0},
+ { GamepadInputId.SingleLeftTrigger1, LocaleKeys.GamepadSingleLeftTrigger1},
+ { GamepadInputId.SingleRightTrigger1, LocaleKeys.GamepadSingleRightTrigger1},
+ { GamepadInputId.Unbound, LocaleKeys.KeyUnbound},
+ };
+
+ private static readonly Dictionary _stickInputIdMap = new()
+ {
+ { StickInputId.Left, LocaleKeys.StickLeft},
+ { StickInputId.Right, LocaleKeys.StickRight},
+ { StickInputId.Unbound, LocaleKeys.KeyUnbound},
+ };
+
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
- if (value == null)
+ string keyString = "";
+
+ if (value is Key key)
{
- return null;
+ if (_keysMap.TryGetValue(key, out LocaleKeys localeKey))
+ {
+ keyString = LocaleManager.Instance[localeKey];
+ }
+ else
+ {
+ keyString = key.ToString();
+ }
+ }
+ else if (value is GamepadInputId gamepadInputId)
+ {
+ if (_gamepadInputIdMap.TryGetValue(gamepadInputId, out LocaleKeys localeKey))
+ {
+ keyString = LocaleManager.Instance[localeKey];
+ }
+ else
+ {
+ keyString = gamepadInputId.ToString();
+ }
+ }
+ else if (value is StickInputId stickInputId)
+ {
+ if (_stickInputIdMap.TryGetValue(stickInputId, out LocaleKeys localeKey))
+ {
+ keyString = LocaleManager.Instance[localeKey];
+ }
+ else
+ {
+ keyString = stickInputId.ToString();
+ }
}
- return value.ToString();
+ return keyString;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
- object key = null;
-
- if (value != null)
- {
- if (targetType == typeof(Key))
- {
- key = Enum.Parse(value.ToString());
- }
- else if (targetType == typeof(GamepadInputId))
- {
- key = Enum.Parse(value.ToString());
- }
- else if (targetType == typeof(StickInputId))
- {
- key = Enum.Parse(value.ToString());
- }
- }
-
- return key;
+ throw new NotSupportedException();
}
}
}
diff --git a/src/Ryujinx.Ava/UI/Models/Input/ControllerInputConfig.cs b/src/Ryujinx.Ava/UI/Models/Input/ControllerInputConfig.cs
new file mode 100644
index 0000000000..4929e582e1
--- /dev/null
+++ b/src/Ryujinx.Ava/UI/Models/Input/ControllerInputConfig.cs
@@ -0,0 +1,580 @@
+using Ryujinx.Ava.UI.ViewModels;
+using Ryujinx.Common.Configuration.Hid;
+using Ryujinx.Common.Configuration.Hid.Controller;
+using Ryujinx.Common.Configuration.Hid.Controller.Motion;
+using System;
+
+namespace Ryujinx.Ava.UI.Models.Input
+{
+ public class ControllerInputConfig : BaseModel
+ {
+ public bool EnableCemuHookMotion { get; set; }
+ public string DsuServerHost { get; set; }
+ public int DsuServerPort { get; set; }
+ public int Slot { get; set; }
+ public int AltSlot { get; set; }
+ public bool MirrorInput { get; set; }
+ public int Sensitivity { get; set; }
+ public double GyroDeadzone { get; set; }
+
+ public float WeakRumble { get; set; }
+ public float StrongRumble { get; set; }
+
+ public string Id { get; set; }
+ public ControllerType ControllerType { get; set; }
+ public PlayerIndex PlayerIndex { get; set; }
+
+ private StickInputId _leftJoystick;
+ public StickInputId LeftJoystick
+ {
+ get => _leftJoystick;
+ set
+ {
+ _leftJoystick = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private bool _leftInvertStickX;
+ public bool LeftInvertStickX
+ {
+ get => _leftInvertStickX;
+ set
+ {
+ _leftInvertStickX = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private bool _leftInvertStickY;
+ public bool LeftInvertStickY
+ {
+ get => _leftInvertStickY;
+ set
+ {
+ _leftInvertStickY = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private bool _leftRotate90;
+ public bool LeftRotate90
+ {
+ get => _leftRotate90;
+ set
+ {
+ _leftRotate90 = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private GamepadInputId _leftStickButton;
+ public GamepadInputId LeftStickButton
+ {
+ get => _leftStickButton;
+ set
+ {
+ _leftStickButton = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private StickInputId _rightJoystick;
+ public StickInputId RightJoystick
+ {
+ get => _rightJoystick;
+ set
+ {
+ _rightJoystick = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private bool _rightInvertStickX;
+ public bool RightInvertStickX
+ {
+ get => _rightInvertStickX;
+ set
+ {
+ _rightInvertStickX = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private bool _rightInvertStickY;
+ public bool RightInvertStickY
+ {
+ get => _rightInvertStickY;
+ set
+ {
+ _rightInvertStickY = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private bool _rightRotate90;
+ public bool RightRotate90
+ {
+ get => _rightRotate90;
+ set
+ {
+ _rightRotate90 = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private GamepadInputId _rightStickButton;
+ public GamepadInputId RightStickButton
+ {
+ get => _rightStickButton;
+ set
+ {
+ _rightStickButton = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private GamepadInputId _dpadUp;
+ public GamepadInputId DpadUp
+ {
+ get => _dpadUp;
+ set
+ {
+ _dpadUp = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private GamepadInputId _dpadDown;
+ public GamepadInputId DpadDown
+ {
+ get => _dpadDown;
+ set
+ {
+ _dpadDown = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private GamepadInputId _dpadLeft;
+ public GamepadInputId DpadLeft
+ {
+ get => _dpadLeft;
+ set
+ {
+ _dpadLeft = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private GamepadInputId _dpadRight;
+ public GamepadInputId DpadRight
+ {
+ get => _dpadRight;
+ set
+ {
+ _dpadRight = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private GamepadInputId _buttonL;
+ public GamepadInputId ButtonL
+ {
+ get => _buttonL;
+ set
+ {
+ _buttonL = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private GamepadInputId _buttonMinus;
+ public GamepadInputId ButtonMinus
+ {
+ get => _buttonMinus;
+ set
+ {
+ _buttonMinus = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private GamepadInputId _leftButtonSl;
+ public GamepadInputId LeftButtonSl
+ {
+ get => _leftButtonSl;
+ set
+ {
+ _leftButtonSl = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private GamepadInputId _leftButtonSr;
+ public GamepadInputId LeftButtonSr
+ {
+ get => _leftButtonSr;
+ set
+ {
+ _leftButtonSr = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private GamepadInputId _buttonZl;
+ public GamepadInputId ButtonZl
+ {
+ get => _buttonZl;
+ set
+ {
+ _buttonZl = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private GamepadInputId _buttonA;
+ public GamepadInputId ButtonA
+ {
+ get => _buttonA;
+ set
+ {
+ _buttonA = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private GamepadInputId _buttonB;
+ public GamepadInputId ButtonB
+ {
+ get => _buttonB;
+ set
+ {
+ _buttonB = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private GamepadInputId _buttonX;
+ public GamepadInputId ButtonX
+ {
+ get => _buttonX;
+ set
+ {
+ _buttonX = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private GamepadInputId _buttonY;
+ public GamepadInputId ButtonY
+ {
+ get => _buttonY;
+ set
+ {
+ _buttonY = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private GamepadInputId _buttonR;
+ public GamepadInputId ButtonR
+ {
+ get => _buttonR;
+ set
+ {
+ _buttonR = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private GamepadInputId _buttonPlus;
+ public GamepadInputId ButtonPlus
+ {
+ get => _buttonPlus;
+ set
+ {
+ _buttonPlus = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private GamepadInputId _rightButtonSl;
+ public GamepadInputId RightButtonSl
+ {
+ get => _rightButtonSl;
+ set
+ {
+ _rightButtonSl = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private GamepadInputId _rightButtonSr;
+ public GamepadInputId RightButtonSr
+ {
+ get => _rightButtonSr;
+ set
+ {
+ _rightButtonSr = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private GamepadInputId _buttonZr;
+ public GamepadInputId ButtonZr
+ {
+ get => _buttonZr;
+ set
+ {
+ _buttonZr = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private float _deadzoneLeft;
+ public float DeadzoneLeft
+ {
+ get => _deadzoneLeft;
+ set
+ {
+ _deadzoneLeft = MathF.Round(value, 3);
+ OnPropertyChanged();
+ }
+ }
+
+ private float _deadzoneRight;
+ public float DeadzoneRight
+ {
+ get => _deadzoneRight;
+ set
+ {
+ _deadzoneRight = MathF.Round(value, 3);
+ OnPropertyChanged();
+ }
+ }
+
+ private float _rangeLeft;
+ public float RangeLeft
+ {
+ get => _rangeLeft;
+ set
+ {
+ _rangeLeft = MathF.Round(value, 3);
+ OnPropertyChanged();
+ }
+ }
+
+ private float _rangeRight;
+ public float RangeRight
+ {
+ get => _rangeRight;
+ set
+ {
+ _rangeRight = MathF.Round(value, 3);
+ OnPropertyChanged();
+ }
+ }
+
+ private float _triggerThreshold;
+ public float TriggerThreshold
+ {
+ get => _triggerThreshold;
+ set
+ {
+ _triggerThreshold = MathF.Round(value, 3);
+ OnPropertyChanged();
+ }
+ }
+
+ private bool _enableMotion;
+ public bool EnableMotion
+ {
+ get => _enableMotion;
+ set
+ {
+ _enableMotion = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private bool _enableRumble;
+ public bool EnableRumble
+ {
+ get => _enableRumble;
+ set
+ {
+ _enableRumble = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public ControllerInputConfig(InputConfig config)
+ {
+ if (config != null)
+ {
+ Id = config.Id;
+ ControllerType = config.ControllerType;
+ PlayerIndex = config.PlayerIndex;
+
+ if (config is not StandardControllerInputConfig controllerInput)
+ {
+ return;
+ }
+
+ LeftJoystick = controllerInput.LeftJoyconStick.Joystick;
+ LeftInvertStickX = controllerInput.LeftJoyconStick.InvertStickX;
+ LeftInvertStickY = controllerInput.LeftJoyconStick.InvertStickY;
+ LeftRotate90 = controllerInput.LeftJoyconStick.Rotate90CW;
+ LeftStickButton = controllerInput.LeftJoyconStick.StickButton;
+
+ RightJoystick = controllerInput.RightJoyconStick.Joystick;
+ RightInvertStickX = controllerInput.RightJoyconStick.InvertStickX;
+ RightInvertStickY = controllerInput.RightJoyconStick.InvertStickY;
+ RightRotate90 = controllerInput.RightJoyconStick.Rotate90CW;
+ RightStickButton = controllerInput.RightJoyconStick.StickButton;
+
+ DpadUp = controllerInput.LeftJoycon.DpadUp;
+ DpadDown = controllerInput.LeftJoycon.DpadDown;
+ DpadLeft = controllerInput.LeftJoycon.DpadLeft;
+ DpadRight = controllerInput.LeftJoycon.DpadRight;
+ ButtonL = controllerInput.LeftJoycon.ButtonL;
+ ButtonMinus = controllerInput.LeftJoycon.ButtonMinus;
+ LeftButtonSl = controllerInput.LeftJoycon.ButtonSl;
+ LeftButtonSr = controllerInput.LeftJoycon.ButtonSr;
+ ButtonZl = controllerInput.LeftJoycon.ButtonZl;
+
+ ButtonA = controllerInput.RightJoycon.ButtonA;
+ ButtonB = controllerInput.RightJoycon.ButtonB;
+ ButtonX = controllerInput.RightJoycon.ButtonX;
+ ButtonY = controllerInput.RightJoycon.ButtonY;
+ ButtonR = controllerInput.RightJoycon.ButtonR;
+ ButtonPlus = controllerInput.RightJoycon.ButtonPlus;
+ RightButtonSl = controllerInput.RightJoycon.ButtonSl;
+ RightButtonSr = controllerInput.RightJoycon.ButtonSr;
+ ButtonZr = controllerInput.RightJoycon.ButtonZr;
+
+ DeadzoneLeft = controllerInput.DeadzoneLeft;
+ DeadzoneRight = controllerInput.DeadzoneRight;
+ RangeLeft = controllerInput.RangeLeft;
+ RangeRight = controllerInput.RangeRight;
+ TriggerThreshold = controllerInput.TriggerThreshold;
+
+ if (controllerInput.Motion != null)
+ {
+ EnableMotion = controllerInput.Motion.EnableMotion;
+ GyroDeadzone = controllerInput.Motion.GyroDeadzone;
+ Sensitivity = controllerInput.Motion.Sensitivity;
+
+ if (controllerInput.Motion is CemuHookMotionConfigController cemuHook)
+ {
+ EnableCemuHookMotion = true;
+ DsuServerHost = cemuHook.DsuServerHost;
+ DsuServerPort = cemuHook.DsuServerPort;
+ Slot = cemuHook.Slot;
+ AltSlot = cemuHook.AltSlot;
+ MirrorInput = cemuHook.MirrorInput;
+ }
+ }
+
+ if (controllerInput.Rumble != null)
+ {
+ EnableRumble = controllerInput.Rumble.EnableRumble;
+ WeakRumble = controllerInput.Rumble.WeakRumble;
+ StrongRumble = controllerInput.Rumble.StrongRumble;
+ }
+ }
+ }
+
+ public InputConfig GetConfig()
+ {
+ var config = new StandardControllerInputConfig
+ {
+ Id = Id,
+ Backend = InputBackendType.GamepadSDL2,
+ PlayerIndex = PlayerIndex,
+ ControllerType = ControllerType,
+ LeftJoycon = new LeftJoyconCommonConfig
+ {
+ DpadUp = DpadUp,
+ DpadDown = DpadDown,
+ DpadLeft = DpadLeft,
+ DpadRight = DpadRight,
+ ButtonL = ButtonL,
+ ButtonMinus = ButtonMinus,
+ ButtonSl = LeftButtonSl,
+ ButtonSr = LeftButtonSr,
+ ButtonZl = ButtonZl
+ },
+ RightJoycon = new RightJoyconCommonConfig
+ {
+ ButtonA = ButtonA,
+ ButtonB = ButtonB,
+ ButtonX = ButtonX,
+ ButtonY = ButtonY,
+ ButtonPlus = ButtonPlus,
+ ButtonSl = RightButtonSl,
+ ButtonSr = RightButtonSr,
+ ButtonR = ButtonR,
+ ButtonZr = ButtonZr
+ },
+ LeftJoyconStick = new JoyconConfigControllerStick
+ {
+ Joystick = LeftJoystick,
+ InvertStickX = LeftInvertStickX,
+ InvertStickY = LeftInvertStickY,
+ Rotate90CW = LeftRotate90,
+ StickButton = LeftStickButton
+ },
+ RightJoyconStick = new JoyconConfigControllerStick
+ {
+ Joystick = RightJoystick,
+ InvertStickX = RightInvertStickX,
+ InvertStickY = RightInvertStickY,
+ Rotate90CW = RightRotate90,
+ StickButton = RightStickButton
+ },
+ Rumble = new RumbleConfigController
+ {
+ EnableRumble = EnableRumble,
+ WeakRumble = WeakRumble,
+ StrongRumble = StrongRumble
+ },
+ Version = InputConfig.CurrentVersion,
+ DeadzoneLeft = DeadzoneLeft,
+ DeadzoneRight = DeadzoneRight,
+ RangeLeft = RangeLeft,
+ RangeRight = RangeRight,
+ TriggerThreshold = TriggerThreshold
+ };
+
+ if (EnableCemuHookMotion)
+ {
+ config.Motion = new CemuHookMotionConfigController
+ {
+ EnableMotion = EnableMotion,
+ MotionBackend = MotionInputBackendType.CemuHook,
+ GyroDeadzone = GyroDeadzone,
+ Sensitivity = Sensitivity,
+ DsuServerHost = DsuServerHost,
+ DsuServerPort = DsuServerPort,
+ Slot = Slot,
+ AltSlot = AltSlot,
+ MirrorInput = MirrorInput
+ };
+ }
+ else
+ {
+ config.Motion = new MotionConfigController
+ {
+ EnableMotion = EnableMotion,
+ MotionBackend = MotionInputBackendType.GamepadDriver,
+ GyroDeadzone = GyroDeadzone,
+ Sensitivity = Sensitivity
+ };
+ }
+
+ return config;
+ }
+ }
+}
diff --git a/src/Ryujinx.Ava/UI/Models/Input/KeyboardInputConfig.cs b/src/Ryujinx.Ava/UI/Models/Input/KeyboardInputConfig.cs
new file mode 100644
index 0000000000..029565210c
--- /dev/null
+++ b/src/Ryujinx.Ava/UI/Models/Input/KeyboardInputConfig.cs
@@ -0,0 +1,422 @@
+using Ryujinx.Ava.UI.ViewModels;
+using Ryujinx.Common.Configuration.Hid;
+using Ryujinx.Common.Configuration.Hid.Keyboard;
+
+namespace Ryujinx.Ava.UI.Models.Input
+{
+ public class KeyboardInputConfig : BaseModel
+ {
+ public string Id { get; set; }
+ public ControllerType ControllerType { get; set; }
+ public PlayerIndex PlayerIndex { get; set; }
+
+ private Key _leftStickUp;
+ public Key LeftStickUp
+ {
+ get => _leftStickUp;
+ set
+ {
+ _leftStickUp = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _leftStickDown;
+ public Key LeftStickDown
+ {
+ get => _leftStickDown;
+ set
+ {
+ _leftStickDown = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _leftStickLeft;
+ public Key LeftStickLeft
+ {
+ get => _leftStickLeft;
+ set
+ {
+ _leftStickLeft = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _leftStickRight;
+ public Key LeftStickRight
+ {
+ get => _leftStickRight;
+ set
+ {
+ _leftStickRight = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _leftStickButton;
+ public Key LeftStickButton
+ {
+ get => _leftStickButton;
+ set
+ {
+ _leftStickButton = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _rightStickUp;
+ public Key RightStickUp
+ {
+ get => _rightStickUp;
+ set
+ {
+ _rightStickUp = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _rightStickDown;
+ public Key RightStickDown
+ {
+ get => _rightStickDown;
+ set
+ {
+ _rightStickDown = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _rightStickLeft;
+ public Key RightStickLeft
+ {
+ get => _rightStickLeft;
+ set
+ {
+ _rightStickLeft = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _rightStickRight;
+ public Key RightStickRight
+ {
+ get => _rightStickRight;
+ set
+ {
+ _rightStickRight = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _rightStickButton;
+ public Key RightStickButton
+ {
+ get => _rightStickButton;
+ set
+ {
+ _rightStickButton = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _dpadUp;
+ public Key DpadUp
+ {
+ get => _dpadUp;
+ set
+ {
+ _dpadUp = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _dpadDown;
+ public Key DpadDown
+ {
+ get => _dpadDown;
+ set
+ {
+ _dpadDown = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _dpadLeft;
+ public Key DpadLeft
+ {
+ get => _dpadLeft;
+ set
+ {
+ _dpadLeft = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _dpadRight;
+ public Key DpadRight
+ {
+ get => _dpadRight;
+ set
+ {
+ _dpadRight = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _buttonL;
+ public Key ButtonL
+ {
+ get => _buttonL;
+ set
+ {
+ _buttonL = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _buttonMinus;
+ public Key ButtonMinus
+ {
+ get => _buttonMinus;
+ set
+ {
+ _buttonMinus = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _leftButtonSl;
+ public Key LeftButtonSl
+ {
+ get => _leftButtonSl;
+ set
+ {
+ _leftButtonSl = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _leftButtonSr;
+ public Key LeftButtonSr
+ {
+ get => _leftButtonSr;
+ set
+ {
+ _leftButtonSr = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _buttonZl;
+ public Key ButtonZl
+ {
+ get => _buttonZl;
+ set
+ {
+ _buttonZl = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _buttonA;
+ public Key ButtonA
+ {
+ get => _buttonA;
+ set
+ {
+ _buttonA = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _buttonB;
+ public Key ButtonB
+ {
+ get => _buttonB;
+ set
+ {
+ _buttonB = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _buttonX;
+ public Key ButtonX
+ {
+ get => _buttonX;
+ set
+ {
+ _buttonX = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _buttonY;
+ public Key ButtonY
+ {
+ get => _buttonY;
+ set
+ {
+ _buttonY = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _buttonR;
+ public Key ButtonR
+ {
+ get => _buttonR;
+ set
+ {
+ _buttonR = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _buttonPlus;
+ public Key ButtonPlus
+ {
+ get => _buttonPlus;
+ set
+ {
+ _buttonPlus = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _rightButtonSl;
+ public Key RightButtonSl
+ {
+ get => _rightButtonSl;
+ set
+ {
+ _rightButtonSl = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _rightButtonSr;
+ public Key RightButtonSr
+ {
+ get => _rightButtonSr;
+ set
+ {
+ _rightButtonSr = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private Key _buttonZr;
+ public Key ButtonZr
+ {
+ get => _buttonZr;
+ set
+ {
+ _buttonZr = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public KeyboardInputConfig(InputConfig config)
+ {
+ if (config != null)
+ {
+ Id = config.Id;
+ ControllerType = config.ControllerType;
+ PlayerIndex = config.PlayerIndex;
+
+ if (config is not StandardKeyboardInputConfig keyboardConfig)
+ {
+ return;
+ }
+
+ LeftStickUp = keyboardConfig.LeftJoyconStick.StickUp;
+ LeftStickDown = keyboardConfig.LeftJoyconStick.StickDown;
+ LeftStickLeft = keyboardConfig.LeftJoyconStick.StickLeft;
+ LeftStickRight = keyboardConfig.LeftJoyconStick.StickRight;
+ LeftStickButton = keyboardConfig.LeftJoyconStick.StickButton;
+
+ RightStickUp = keyboardConfig.RightJoyconStick.StickUp;
+ RightStickDown = keyboardConfig.RightJoyconStick.StickDown;
+ RightStickLeft = keyboardConfig.RightJoyconStick.StickLeft;
+ RightStickRight = keyboardConfig.RightJoyconStick.StickRight;
+ RightStickButton = keyboardConfig.RightJoyconStick.StickButton;
+
+ DpadUp = keyboardConfig.LeftJoycon.DpadUp;
+ DpadDown = keyboardConfig.LeftJoycon.DpadDown;
+ DpadLeft = keyboardConfig.LeftJoycon.DpadLeft;
+ DpadRight = keyboardConfig.LeftJoycon.DpadRight;
+ ButtonL = keyboardConfig.LeftJoycon.ButtonL;
+ ButtonMinus = keyboardConfig.LeftJoycon.ButtonMinus;
+ LeftButtonSl = keyboardConfig.LeftJoycon.ButtonSl;
+ LeftButtonSr = keyboardConfig.LeftJoycon.ButtonSr;
+ ButtonZl = keyboardConfig.LeftJoycon.ButtonZl;
+
+ ButtonA = keyboardConfig.RightJoycon.ButtonA;
+ ButtonB = keyboardConfig.RightJoycon.ButtonB;
+ ButtonX = keyboardConfig.RightJoycon.ButtonX;
+ ButtonY = keyboardConfig.RightJoycon.ButtonY;
+ ButtonR = keyboardConfig.RightJoycon.ButtonR;
+ ButtonPlus = keyboardConfig.RightJoycon.ButtonPlus;
+ RightButtonSl = keyboardConfig.RightJoycon.ButtonSl;
+ RightButtonSr = keyboardConfig.RightJoycon.ButtonSr;
+ ButtonZr = keyboardConfig.RightJoycon.ButtonZr;
+ }
+ }
+
+ public InputConfig GetConfig()
+ {
+ var config = new StandardKeyboardInputConfig
+ {
+ Id = Id,
+ Backend = InputBackendType.WindowKeyboard,
+ PlayerIndex = PlayerIndex,
+ ControllerType = ControllerType,
+ LeftJoycon = new LeftJoyconCommonConfig
+ {
+ DpadUp = DpadUp,
+ DpadDown = DpadDown,
+ DpadLeft = DpadLeft,
+ DpadRight = DpadRight,
+ ButtonL = ButtonL,
+ ButtonMinus = ButtonMinus,
+ ButtonZl = ButtonZl,
+ ButtonSl = LeftButtonSl,
+ ButtonSr = LeftButtonSr
+ },
+ RightJoycon = new RightJoyconCommonConfig
+ {
+ ButtonA = ButtonA,
+ ButtonB = ButtonB,
+ ButtonX = ButtonX,
+ ButtonY = ButtonY,
+ ButtonPlus = ButtonPlus,
+ ButtonSl = RightButtonSl,
+ ButtonSr = RightButtonSr,
+ ButtonR = ButtonR,
+ ButtonZr = ButtonZr
+ },
+ LeftJoyconStick = new JoyconConfigKeyboardStick
+ {
+ StickUp = LeftStickUp,
+ StickDown = LeftStickDown,
+ StickRight = LeftStickRight,
+ StickLeft = LeftStickLeft,
+ StickButton = LeftStickButton
+ },
+ RightJoyconStick = new JoyconConfigKeyboardStick
+ {
+ StickUp = RightStickUp,
+ StickDown = RightStickDown,
+ StickLeft = RightStickLeft,
+ StickRight = RightStickRight,
+ StickButton = RightStickButton
+ },
+ Version = InputConfig.CurrentVersion
+ };
+
+ return config;
+ }
+ }
+}
diff --git a/src/Ryujinx.Ava/UI/Models/InputConfiguration.cs b/src/Ryujinx.Ava/UI/Models/InputConfiguration.cs
deleted file mode 100644
index f1352c6d8b..0000000000
--- a/src/Ryujinx.Ava/UI/Models/InputConfiguration.cs
+++ /dev/null
@@ -1,456 +0,0 @@
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.Common.Configuration.Hid;
-using Ryujinx.Common.Configuration.Hid.Controller;
-using Ryujinx.Common.Configuration.Hid.Controller.Motion;
-using Ryujinx.Common.Configuration.Hid.Keyboard;
-using System;
-
-namespace Ryujinx.Ava.UI.Models
-{
- internal class InputConfiguration : BaseModel
- {
- private float _deadzoneRight;
- private float _triggerThreshold;
- private float _deadzoneLeft;
- private double _gyroDeadzone;
- private int _sensitivity;
- private bool _enableMotion;
- private float _weakRumble;
- private float _strongRumble;
- private float _rangeLeft;
- private float _rangeRight;
-
- public InputBackendType Backend { get; set; }
-
- ///
- /// Controller id
- ///
- public string Id { get; set; }
-
- ///
- /// Controller's Type
- ///
- public ControllerType ControllerType { get; set; }
-
- ///
- /// Player's Index for the controller
- ///
- public PlayerIndex PlayerIndex { get; set; }
-
- public TStick LeftJoystick { get; set; }
- public bool LeftInvertStickX { get; set; }
- public bool LeftInvertStickY { get; set; }
- public bool RightRotate90 { get; set; }
- public TKey LeftControllerStickButton { get; set; }
-
- public TStick RightJoystick { get; set; }
- public bool RightInvertStickX { get; set; }
- public bool RightInvertStickY { get; set; }
- public bool LeftRotate90 { get; set; }
- public TKey RightControllerStickButton { get; set; }
-
- public float DeadzoneLeft
- {
- get => _deadzoneLeft;
- set
- {
- _deadzoneLeft = MathF.Round(value, 3);
-
- OnPropertyChanged();
- }
- }
-
- public float RangeLeft
- {
- get => _rangeLeft;
- set
- {
- _rangeLeft = MathF.Round(value, 3);
-
- OnPropertyChanged();
- }
- }
-
- public float DeadzoneRight
- {
- get => _deadzoneRight;
- set
- {
- _deadzoneRight = MathF.Round(value, 3);
-
- OnPropertyChanged();
- }
- }
-
- public float RangeRight
- {
- get => _rangeRight;
- set
- {
- _rangeRight = MathF.Round(value, 3);
-
- OnPropertyChanged();
- }
- }
-
- public float TriggerThreshold
- {
- get => _triggerThreshold;
- set
- {
- _triggerThreshold = MathF.Round(value, 3);
-
- OnPropertyChanged();
- }
- }
-
- public MotionInputBackendType MotionBackend { get; set; }
-
- public TKey ButtonMinus { get; set; }
- public TKey ButtonL { get; set; }
- public TKey ButtonZl { get; set; }
- public TKey LeftButtonSl { get; set; }
- public TKey LeftButtonSr { get; set; }
- public TKey DpadUp { get; set; }
- public TKey DpadDown { get; set; }
- public TKey DpadLeft { get; set; }
- public TKey DpadRight { get; set; }
-
- public TKey ButtonPlus { get; set; }
- public TKey ButtonR { get; set; }
- public TKey ButtonZr { get; set; }
- public TKey RightButtonSl { get; set; }
- public TKey RightButtonSr { get; set; }
- public TKey ButtonX { get; set; }
- public TKey ButtonB { get; set; }
- public TKey ButtonY { get; set; }
- public TKey ButtonA { get; set; }
-
- public TKey LeftStickUp { get; set; }
- public TKey LeftStickDown { get; set; }
- public TKey LeftStickLeft { get; set; }
- public TKey LeftStickRight { get; set; }
- public TKey LeftKeyboardStickButton { get; set; }
-
- public TKey RightStickUp { get; set; }
- public TKey RightStickDown { get; set; }
- public TKey RightStickLeft { get; set; }
- public TKey RightStickRight { get; set; }
- public TKey RightKeyboardStickButton { get; set; }
-
- public int Sensitivity
- {
- get => _sensitivity;
- set
- {
- _sensitivity = value;
-
- OnPropertyChanged();
- }
- }
-
- public double GyroDeadzone
- {
- get => _gyroDeadzone;
- set
- {
- _gyroDeadzone = Math.Round(value, 3);
-
- OnPropertyChanged();
- }
- }
-
- public bool EnableMotion
- {
- get => _enableMotion; set
- {
- _enableMotion = value;
-
- OnPropertyChanged();
- }
- }
-
- public bool EnableCemuHookMotion { get; set; }
- public int Slot { get; set; }
- public int AltSlot { get; set; }
- public bool MirrorInput { get; set; }
- public string DsuServerHost { get; set; }
- public int DsuServerPort { get; set; }
-
- public bool EnableRumble { get; set; }
- public float WeakRumble
- {
- get => _weakRumble; set
- {
- _weakRumble = value;
-
- OnPropertyChanged();
- }
- }
- public float StrongRumble
- {
- get => _strongRumble; set
- {
- _strongRumble = value;
-
- OnPropertyChanged();
- }
- }
-
- public InputConfiguration(InputConfig config)
- {
- if (config != null)
- {
- Backend = config.Backend;
- Id = config.Id;
- ControllerType = config.ControllerType;
- PlayerIndex = config.PlayerIndex;
-
- if (config is StandardKeyboardInputConfig keyboardConfig)
- {
- LeftStickUp = (TKey)(object)keyboardConfig.LeftJoyconStick.StickUp;
- LeftStickDown = (TKey)(object)keyboardConfig.LeftJoyconStick.StickDown;
- LeftStickLeft = (TKey)(object)keyboardConfig.LeftJoyconStick.StickLeft;
- LeftStickRight = (TKey)(object)keyboardConfig.LeftJoyconStick.StickRight;
- LeftKeyboardStickButton = (TKey)(object)keyboardConfig.LeftJoyconStick.StickButton;
-
- RightStickUp = (TKey)(object)keyboardConfig.RightJoyconStick.StickUp;
- RightStickDown = (TKey)(object)keyboardConfig.RightJoyconStick.StickDown;
- RightStickLeft = (TKey)(object)keyboardConfig.RightJoyconStick.StickLeft;
- RightStickRight = (TKey)(object)keyboardConfig.RightJoyconStick.StickRight;
- RightKeyboardStickButton = (TKey)(object)keyboardConfig.RightJoyconStick.StickButton;
-
- ButtonA = (TKey)(object)keyboardConfig.RightJoycon.ButtonA;
- ButtonB = (TKey)(object)keyboardConfig.RightJoycon.ButtonB;
- ButtonX = (TKey)(object)keyboardConfig.RightJoycon.ButtonX;
- ButtonY = (TKey)(object)keyboardConfig.RightJoycon.ButtonY;
- ButtonR = (TKey)(object)keyboardConfig.RightJoycon.ButtonR;
- RightButtonSl = (TKey)(object)keyboardConfig.RightJoycon.ButtonSl;
- RightButtonSr = (TKey)(object)keyboardConfig.RightJoycon.ButtonSr;
- ButtonZr = (TKey)(object)keyboardConfig.RightJoycon.ButtonZr;
- ButtonPlus = (TKey)(object)keyboardConfig.RightJoycon.ButtonPlus;
-
- DpadUp = (TKey)(object)keyboardConfig.LeftJoycon.DpadUp;
- DpadDown = (TKey)(object)keyboardConfig.LeftJoycon.DpadDown;
- DpadLeft = (TKey)(object)keyboardConfig.LeftJoycon.DpadLeft;
- DpadRight = (TKey)(object)keyboardConfig.LeftJoycon.DpadRight;
- ButtonMinus = (TKey)(object)keyboardConfig.LeftJoycon.ButtonMinus;
- LeftButtonSl = (TKey)(object)keyboardConfig.LeftJoycon.ButtonSl;
- LeftButtonSr = (TKey)(object)keyboardConfig.LeftJoycon.ButtonSr;
- ButtonZl = (TKey)(object)keyboardConfig.LeftJoycon.ButtonZl;
- ButtonL = (TKey)(object)keyboardConfig.LeftJoycon.ButtonL;
- }
- else if (config is StandardControllerInputConfig controllerConfig)
- {
- LeftJoystick = (TStick)(object)controllerConfig.LeftJoyconStick.Joystick;
- LeftInvertStickX = controllerConfig.LeftJoyconStick.InvertStickX;
- LeftInvertStickY = controllerConfig.LeftJoyconStick.InvertStickY;
- LeftRotate90 = controllerConfig.LeftJoyconStick.Rotate90CW;
- LeftControllerStickButton = (TKey)(object)controllerConfig.LeftJoyconStick.StickButton;
-
- RightJoystick = (TStick)(object)controllerConfig.RightJoyconStick.Joystick;
- RightInvertStickX = controllerConfig.RightJoyconStick.InvertStickX;
- RightInvertStickY = controllerConfig.RightJoyconStick.InvertStickY;
- RightRotate90 = controllerConfig.RightJoyconStick.Rotate90CW;
- RightControllerStickButton = (TKey)(object)controllerConfig.RightJoyconStick.StickButton;
-
- ButtonA = (TKey)(object)controllerConfig.RightJoycon.ButtonA;
- ButtonB = (TKey)(object)controllerConfig.RightJoycon.ButtonB;
- ButtonX = (TKey)(object)controllerConfig.RightJoycon.ButtonX;
- ButtonY = (TKey)(object)controllerConfig.RightJoycon.ButtonY;
- ButtonR = (TKey)(object)controllerConfig.RightJoycon.ButtonR;
- RightButtonSl = (TKey)(object)controllerConfig.RightJoycon.ButtonSl;
- RightButtonSr = (TKey)(object)controllerConfig.RightJoycon.ButtonSr;
- ButtonZr = (TKey)(object)controllerConfig.RightJoycon.ButtonZr;
- ButtonPlus = (TKey)(object)controllerConfig.RightJoycon.ButtonPlus;
-
- DpadUp = (TKey)(object)controllerConfig.LeftJoycon.DpadUp;
- DpadDown = (TKey)(object)controllerConfig.LeftJoycon.DpadDown;
- DpadLeft = (TKey)(object)controllerConfig.LeftJoycon.DpadLeft;
- DpadRight = (TKey)(object)controllerConfig.LeftJoycon.DpadRight;
- ButtonMinus = (TKey)(object)controllerConfig.LeftJoycon.ButtonMinus;
- LeftButtonSl = (TKey)(object)controllerConfig.LeftJoycon.ButtonSl;
- LeftButtonSr = (TKey)(object)controllerConfig.LeftJoycon.ButtonSr;
- ButtonZl = (TKey)(object)controllerConfig.LeftJoycon.ButtonZl;
- ButtonL = (TKey)(object)controllerConfig.LeftJoycon.ButtonL;
-
- DeadzoneLeft = controllerConfig.DeadzoneLeft;
- DeadzoneRight = controllerConfig.DeadzoneRight;
- RangeLeft = controllerConfig.RangeLeft;
- RangeRight = controllerConfig.RangeRight;
- TriggerThreshold = controllerConfig.TriggerThreshold;
-
- if (controllerConfig.Motion != null)
- {
- EnableMotion = controllerConfig.Motion.EnableMotion;
- MotionBackend = controllerConfig.Motion.MotionBackend;
- GyroDeadzone = controllerConfig.Motion.GyroDeadzone;
- Sensitivity = controllerConfig.Motion.Sensitivity;
-
- if (controllerConfig.Motion is CemuHookMotionConfigController cemuHook)
- {
- EnableCemuHookMotion = true;
- DsuServerHost = cemuHook.DsuServerHost;
- DsuServerPort = cemuHook.DsuServerPort;
- Slot = cemuHook.Slot;
- AltSlot = cemuHook.AltSlot;
- MirrorInput = cemuHook.MirrorInput;
- }
-
- if (controllerConfig.Rumble != null)
- {
- EnableRumble = controllerConfig.Rumble.EnableRumble;
- WeakRumble = controllerConfig.Rumble.WeakRumble;
- StrongRumble = controllerConfig.Rumble.StrongRumble;
- }
- }
- }
- }
- }
-
- public InputConfiguration()
- {
- }
-
- public InputConfig GetConfig()
- {
- if (Backend == InputBackendType.WindowKeyboard)
- {
- return new StandardKeyboardInputConfig
- {
- Id = Id,
- Backend = Backend,
- PlayerIndex = PlayerIndex,
- ControllerType = ControllerType,
- LeftJoycon = new LeftJoyconCommonConfig
- {
- DpadUp = (Key)(object)DpadUp,
- DpadDown = (Key)(object)DpadDown,
- DpadLeft = (Key)(object)DpadLeft,
- DpadRight = (Key)(object)DpadRight,
- ButtonL = (Key)(object)ButtonL,
- ButtonZl = (Key)(object)ButtonZl,
- ButtonSl = (Key)(object)LeftButtonSl,
- ButtonSr = (Key)(object)LeftButtonSr,
- ButtonMinus = (Key)(object)ButtonMinus,
- },
- RightJoycon = new RightJoyconCommonConfig
- {
- ButtonA = (Key)(object)ButtonA,
- ButtonB = (Key)(object)ButtonB,
- ButtonX = (Key)(object)ButtonX,
- ButtonY = (Key)(object)ButtonY,
- ButtonPlus = (Key)(object)ButtonPlus,
- ButtonSl = (Key)(object)RightButtonSl,
- ButtonSr = (Key)(object)RightButtonSr,
- ButtonR = (Key)(object)ButtonR,
- ButtonZr = (Key)(object)ButtonZr,
- },
- LeftJoyconStick = new JoyconConfigKeyboardStick
- {
- StickUp = (Key)(object)LeftStickUp,
- StickDown = (Key)(object)LeftStickDown,
- StickRight = (Key)(object)LeftStickRight,
- StickLeft = (Key)(object)LeftStickLeft,
- StickButton = (Key)(object)LeftKeyboardStickButton,
- },
- RightJoyconStick = new JoyconConfigKeyboardStick
- {
- StickUp = (Key)(object)RightStickUp,
- StickDown = (Key)(object)RightStickDown,
- StickLeft = (Key)(object)RightStickLeft,
- StickRight = (Key)(object)RightStickRight,
- StickButton = (Key)(object)RightKeyboardStickButton,
- },
- Version = InputConfig.CurrentVersion,
- };
-
- }
-
- if (Backend == InputBackendType.GamepadSDL2)
- {
- var config = new StandardControllerInputConfig
- {
- Id = Id,
- Backend = Backend,
- PlayerIndex = PlayerIndex,
- ControllerType = ControllerType,
- LeftJoycon = new LeftJoyconCommonConfig
- {
- DpadUp = (GamepadInputId)(object)DpadUp,
- DpadDown = (GamepadInputId)(object)DpadDown,
- DpadLeft = (GamepadInputId)(object)DpadLeft,
- DpadRight = (GamepadInputId)(object)DpadRight,
- ButtonL = (GamepadInputId)(object)ButtonL,
- ButtonZl = (GamepadInputId)(object)ButtonZl,
- ButtonSl = (GamepadInputId)(object)LeftButtonSl,
- ButtonSr = (GamepadInputId)(object)LeftButtonSr,
- ButtonMinus = (GamepadInputId)(object)ButtonMinus,
- },
- RightJoycon = new RightJoyconCommonConfig
- {
- ButtonA = (GamepadInputId)(object)ButtonA,
- ButtonB = (GamepadInputId)(object)ButtonB,
- ButtonX = (GamepadInputId)(object)ButtonX,
- ButtonY = (GamepadInputId)(object)ButtonY,
- ButtonPlus = (GamepadInputId)(object)ButtonPlus,
- ButtonSl = (GamepadInputId)(object)RightButtonSl,
- ButtonSr = (GamepadInputId)(object)RightButtonSr,
- ButtonR = (GamepadInputId)(object)ButtonR,
- ButtonZr = (GamepadInputId)(object)ButtonZr,
- },
- LeftJoyconStick = new JoyconConfigControllerStick
- {
- Joystick = (StickInputId)(object)LeftJoystick,
- InvertStickX = LeftInvertStickX,
- InvertStickY = LeftInvertStickY,
- Rotate90CW = LeftRotate90,
- StickButton = (GamepadInputId)(object)LeftControllerStickButton,
- },
- RightJoyconStick = new JoyconConfigControllerStick
- {
- Joystick = (StickInputId)(object)RightJoystick,
- InvertStickX = RightInvertStickX,
- InvertStickY = RightInvertStickY,
- Rotate90CW = RightRotate90,
- StickButton = (GamepadInputId)(object)RightControllerStickButton,
- },
- Rumble = new RumbleConfigController
- {
- EnableRumble = EnableRumble,
- WeakRumble = WeakRumble,
- StrongRumble = StrongRumble,
- },
- Version = InputConfig.CurrentVersion,
- DeadzoneLeft = DeadzoneLeft,
- DeadzoneRight = DeadzoneRight,
- RangeLeft = RangeLeft,
- RangeRight = RangeRight,
- TriggerThreshold = TriggerThreshold,
- Motion = EnableCemuHookMotion
- ? new CemuHookMotionConfigController
- {
- DsuServerHost = DsuServerHost,
- DsuServerPort = DsuServerPort,
- Slot = Slot,
- AltSlot = AltSlot,
- MirrorInput = MirrorInput,
- MotionBackend = MotionInputBackendType.CemuHook,
- }
- : new StandardMotionConfigController
- {
- MotionBackend = MotionInputBackendType.GamepadDriver,
- },
- };
-
- config.Motion.Sensitivity = Sensitivity;
- config.Motion.EnableMotion = EnableMotion;
- config.Motion.GyroDeadzone = GyroDeadzone;
-
- return config;
- }
-
- return null;
- }
- }
-}
diff --git a/src/Ryujinx.Ava/UI/ViewModels/Input/ControllerInputViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/Input/ControllerInputViewModel.cs
new file mode 100644
index 0000000000..0e23dfa76b
--- /dev/null
+++ b/src/Ryujinx.Ava/UI/ViewModels/Input/ControllerInputViewModel.cs
@@ -0,0 +1,84 @@
+using Avalonia.Svg.Skia;
+using Ryujinx.Ava.UI.Models.Input;
+using Ryujinx.Ava.UI.Views.Input;
+
+namespace Ryujinx.Ava.UI.ViewModels.Input
+{
+ public class ControllerInputViewModel : BaseModel
+ {
+ private ControllerInputConfig _config;
+ public ControllerInputConfig Config
+ {
+ get => _config;
+ set
+ {
+ _config = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private bool _isLeft;
+ public bool IsLeft
+ {
+ get => _isLeft;
+ set
+ {
+ _isLeft = value;
+ OnPropertyChanged();
+ OnPropertyChanged(nameof(HasSides));
+ }
+ }
+
+ private bool _isRight;
+ public bool IsRight
+ {
+ get => _isRight;
+ set
+ {
+ _isRight = value;
+ OnPropertyChanged();
+ OnPropertyChanged(nameof(HasSides));
+ }
+ }
+
+ public bool HasSides => IsLeft ^ IsRight;
+
+ private SvgImage _image;
+ public SvgImage Image
+ {
+ get => _image;
+ set
+ {
+ _image = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public InputViewModel parentModel;
+
+ public ControllerInputViewModel(InputViewModel model, ControllerInputConfig config)
+ {
+ parentModel = model;
+ model.NotifyChangesEvent += OnParentModelChanged;
+ OnParentModelChanged();
+ Config = config;
+ }
+
+ public async void ShowMotionConfig()
+ {
+ await MotionInputView.Show(this);
+ }
+
+ public async void ShowRumbleConfig()
+ {
+ await RumbleInputView.Show(this);
+ }
+
+ public void OnParentModelChanged()
+ {
+ IsLeft = parentModel.IsLeft;
+ IsRight = parentModel.IsRight;
+ Image = parentModel.Image;
+ }
+ }
+}
diff --git a/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/Input/InputViewModel.cs
similarity index 92%
rename from src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs
rename to src/Ryujinx.Ava/UI/ViewModels/Input/InputViewModel.cs
index c0c625321e..ef8ffd50d4 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/ControllerInputViewModel.cs
+++ b/src/Ryujinx.Ava/UI/ViewModels/Input/InputViewModel.cs
@@ -8,7 +8,7 @@ using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Input;
using Ryujinx.Ava.UI.Helpers;
using Ryujinx.Ava.UI.Models;
-using Ryujinx.Ava.UI.Views.Input;
+using Ryujinx.Ava.UI.Models.Input;
using Ryujinx.Ava.UI.Windows;
using Ryujinx.Common;
using Ryujinx.Common.Configuration;
@@ -30,9 +30,9 @@ using ConfigGamepadInputId = Ryujinx.Common.Configuration.Hid.Controller.Gamepad
using ConfigStickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
using Key = Ryujinx.Common.Configuration.Hid.Key;
-namespace Ryujinx.Ava.UI.ViewModels
+namespace Ryujinx.Ava.UI.ViewModels.Input
{
- public class ControllerInputViewModel : BaseModel, IDisposable
+ public class InputViewModel : BaseModel, IDisposable
{
private const string Disabled = "disabled";
private const string ProControllerResource = "Ryujinx.Ui.Common/Resources/Controller_ProCon.svg";
@@ -48,7 +48,7 @@ namespace Ryujinx.Ava.UI.ViewModels
private int _controllerNumber;
private string _controllerImage;
private int _device;
- private object _configuration;
+ private object _configViewModel;
private string _profileName;
private bool _isLoaded;
@@ -71,13 +71,14 @@ namespace Ryujinx.Ava.UI.ViewModels
public bool IsLeft { get; set; }
public bool IsModified { get; set; }
+ public event Action NotifyChangesEvent;
- public object Configuration
+ public object ConfigViewModel
{
- get => _configuration;
+ get => _configViewModel;
set
{
- _configuration = value;
+ _configViewModel = value;
OnPropertyChanged();
}
@@ -232,7 +233,7 @@ namespace Ryujinx.Ava.UI.ViewModels
public InputConfig Config { get; set; }
- public ControllerInputViewModel(UserControl owner) : this()
+ public InputViewModel(UserControl owner) : this()
{
if (Program.PreviewerDetached)
{
@@ -244,7 +245,6 @@ namespace Ryujinx.Ava.UI.ViewModels
_mainWindow.InputManager.GamepadDriver.OnGamepadConnected += HandleOnGamepadConnected;
_mainWindow.InputManager.GamepadDriver.OnGamepadDisconnected += HandleOnGamepadDisconnected;
-
_mainWindow.ViewModel.AppHost?.NpadManager.BlockInputUpdates();
_isLoaded = false;
@@ -255,7 +255,7 @@ namespace Ryujinx.Ava.UI.ViewModels
}
}
- public ControllerInputViewModel()
+ public InputViewModel()
{
PlayerIndexes = new ObservableCollection();
Controllers = new ObservableCollection();
@@ -282,12 +282,12 @@ namespace Ryujinx.Ava.UI.ViewModels
if (Config is StandardKeyboardInputConfig keyboardInputConfig)
{
- Configuration = new InputConfiguration(keyboardInputConfig);
+ ConfigViewModel = new KeyboardInputViewModel(this, new KeyboardInputConfig(keyboardInputConfig));
}
if (Config is StandardControllerInputConfig controllerInputConfig)
{
- Configuration = new InputConfiguration(controllerInputConfig);
+ ConfigViewModel = new ControllerInputViewModel(this, new ControllerInputConfig(controllerInputConfig));
}
}
@@ -323,16 +323,6 @@ namespace Ryujinx.Ava.UI.ViewModels
}
}
- public async void ShowMotionConfig()
- {
- await MotionInputView.Show(this);
- }
-
- public async void ShowRumbleConfig()
- {
- await RumbleInputView.Show(this);
- }
-
private void LoadInputDriver()
{
if (_device < 0)
@@ -740,7 +730,7 @@ namespace Ryujinx.Ava.UI.ViewModels
return;
}
- if (Configuration == null)
+ if (ConfigViewModel == null)
{
return;
}
@@ -751,35 +741,37 @@ namespace Ryujinx.Ava.UI.ViewModels
return;
}
-
- bool validFileName = ProfileName.IndexOfAny(Path.GetInvalidFileNameChars()) == -1;
-
- if (validFileName)
- {
- string path = Path.Combine(GetProfileBasePath(), ProfileName + ".json");
-
- InputConfig config = null;
-
- if (IsKeyboard)
- {
- config = (Configuration as InputConfiguration).GetConfig();
- }
- else if (IsController)
- {
- config = (Configuration as InputConfiguration).GetConfig();
- }
-
- config.ControllerType = Controllers[_controller].Type;
-
- string jsonString = JsonHelper.Serialize(config, _serializerContext.InputConfig);
-
- await File.WriteAllTextAsync(path, jsonString);
-
- LoadProfiles();
- }
else
{
- await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogProfileInvalidProfileNameErrorMessage]);
+ bool validFileName = ProfileName.IndexOfAny(Path.GetInvalidFileNameChars()) == -1;
+
+ if (validFileName)
+ {
+ string path = Path.Combine(GetProfileBasePath(), ProfileName + ".json");
+
+ InputConfig config = null;
+
+ if (IsKeyboard)
+ {
+ config = (ConfigViewModel as KeyboardInputViewModel).Config.GetConfig();
+ }
+ else if (IsController)
+ {
+ config = (ConfigViewModel as ControllerInputViewModel).Config.GetConfig();
+ }
+
+ config.ControllerType = Controllers[_controller].Type;
+
+ string jsonString = JsonHelper.Serialize(config, _serializerContext.InputConfig);
+
+ await File.WriteAllTextAsync(path, jsonString);
+
+ LoadProfiles();
+ }
+ else
+ {
+ await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogProfileInvalidProfileNameErrorMessage]);
+ }
}
}
@@ -830,18 +822,18 @@ namespace Ryujinx.Ava.UI.ViewModels
if (device.Type == DeviceType.Keyboard)
{
- var inputConfig = Configuration as InputConfiguration;
+ var inputConfig = (ConfigViewModel as KeyboardInputViewModel).Config;
inputConfig.Id = device.Id;
}
else
{
- var inputConfig = Configuration as InputConfiguration;
+ var inputConfig = (ConfigViewModel as ControllerInputViewModel).Config;
inputConfig.Id = device.Id.Split(" ")[0];
}
var config = !IsController
- ? (Configuration as InputConfiguration).GetConfig()
- : (Configuration as InputConfiguration).GetConfig();
+ ? (ConfigViewModel as KeyboardInputViewModel).Config.GetConfig()
+ : (ConfigViewModel as ControllerInputViewModel).Config.GetConfig();
config.ControllerType = Controllers[_controller].Type;
config.PlayerIndex = _playerId;
@@ -872,12 +864,13 @@ namespace Ryujinx.Ava.UI.ViewModels
public void NotifyChanges()
{
- OnPropertyChanged(nameof(Configuration));
+ OnPropertyChanged(nameof(ConfigViewModel));
OnPropertyChanged(nameof(IsController));
OnPropertyChanged(nameof(ShowSettings));
OnPropertyChanged(nameof(IsKeyboard));
OnPropertyChanged(nameof(IsRight));
OnPropertyChanged(nameof(IsLeft));
+ NotifyChangesEvent?.Invoke();
}
public void Dispose()
diff --git a/src/Ryujinx.Ava/UI/ViewModels/Input/KeyboardInputViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/Input/KeyboardInputViewModel.cs
new file mode 100644
index 0000000000..a938730638
--- /dev/null
+++ b/src/Ryujinx.Ava/UI/ViewModels/Input/KeyboardInputViewModel.cs
@@ -0,0 +1,73 @@
+using Avalonia.Svg.Skia;
+using Ryujinx.Ava.UI.Models.Input;
+
+namespace Ryujinx.Ava.UI.ViewModels.Input
+{
+ public class KeyboardInputViewModel : BaseModel
+ {
+ private KeyboardInputConfig _config;
+ public KeyboardInputConfig Config
+ {
+ get => _config;
+ set
+ {
+ _config = value;
+ OnPropertyChanged();
+ }
+ }
+
+ private bool _isLeft;
+ public bool IsLeft
+ {
+ get => _isLeft;
+ set
+ {
+ _isLeft = value;
+ OnPropertyChanged();
+ OnPropertyChanged(nameof(HasSides));
+ }
+ }
+
+ private bool _isRight;
+ public bool IsRight
+ {
+ get => _isRight;
+ set
+ {
+ _isRight = value;
+ OnPropertyChanged();
+ OnPropertyChanged(nameof(HasSides));
+ }
+ }
+
+ public bool HasSides => IsLeft ^ IsRight;
+
+ private SvgImage _image;
+ public SvgImage Image
+ {
+ get => _image;
+ set
+ {
+ _image = value;
+ OnPropertyChanged();
+ }
+ }
+
+ public InputViewModel parentModel;
+
+ public KeyboardInputViewModel(InputViewModel model, KeyboardInputConfig config)
+ {
+ parentModel = model;
+ model.NotifyChangesEvent += OnParentModelChanged;
+ OnParentModelChanged();
+ Config = config;
+ }
+
+ public void OnParentModelChanged()
+ {
+ IsLeft = parentModel.IsLeft;
+ IsRight = parentModel.IsRight;
+ Image = parentModel.Image;
+ }
+ }
+}
diff --git a/src/Ryujinx.Ava/UI/ViewModels/MotionInputViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/Input/MotionInputViewModel.cs
similarity index 97%
rename from src/Ryujinx.Ava/UI/ViewModels/MotionInputViewModel.cs
rename to src/Ryujinx.Ava/UI/ViewModels/Input/MotionInputViewModel.cs
index 0b12a51f6c..c9ed8f2d46 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/MotionInputViewModel.cs
+++ b/src/Ryujinx.Ava/UI/ViewModels/Input/MotionInputViewModel.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.Ava.UI.ViewModels
+namespace Ryujinx.Ava.UI.ViewModels.Input
{
public class MotionInputViewModel : BaseModel
{
diff --git a/src/Ryujinx.Ava/UI/ViewModels/RumbleInputViewModel.cs b/src/Ryujinx.Ava/UI/ViewModels/Input/RumbleInputViewModel.cs
similarity index 92%
rename from src/Ryujinx.Ava/UI/ViewModels/RumbleInputViewModel.cs
rename to src/Ryujinx.Ava/UI/ViewModels/Input/RumbleInputViewModel.cs
index 49de19937d..8ad33cf4ce 100644
--- a/src/Ryujinx.Ava/UI/ViewModels/RumbleInputViewModel.cs
+++ b/src/Ryujinx.Ava/UI/ViewModels/Input/RumbleInputViewModel.cs
@@ -1,4 +1,4 @@
-namespace Ryujinx.Ava.UI.ViewModels
+namespace Ryujinx.Ava.UI.ViewModels.Input
{
public class RumbleInputViewModel : BaseModel
{
diff --git a/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml b/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml
index d636873a3a..08bdf90f4c 100644
--- a/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml
@@ -1,13 +1,11 @@
@@ -34,191 +33,10 @@
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Orientation="Vertical">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ MinHeight="450">
@@ -257,9 +75,9 @@
VerticalAlignment="Center"
Text="{locale:Locale ControllerSettingsTriggerZL}"
TextAlignment="Center" />
-
+
@@ -273,9 +91,9 @@
VerticalAlignment="Center"
Text="{locale:Locale ControllerSettingsTriggerL}"
TextAlignment="Center" />
-
+
@@ -289,9 +107,9 @@
VerticalAlignment="Center"
Text="{locale:Locale ControllerSettingsButtonMinus}"
TextAlignment="Center" />
-
+
@@ -311,100 +129,8 @@
Margin="0,0,0,10"
HorizontalAlignment="Center"
Text="{locale:Locale ControllerSettingsLStick}" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -415,9 +141,9 @@
VerticalAlignment="Center"
Text="{locale:Locale ControllerSettingsStickButton}"
TextAlignment="Center" />
-
+
@@ -432,22 +158,22 @@
VerticalAlignment="Center"
Text="{locale:Locale ControllerSettingsStickStick}"
TextAlignment="Center" />
-
+
-
+
-
+
-
+
+ Value="{Binding Config.DeadzoneLeft, Mode=TwoWay}" />
+ Text="{Binding Config.DeadzoneLeft, StringFormat=\{0:0.00\}}" />
+ Value="{Binding Config.RangeLeft, Mode=TwoWay}" />
+ Text="{Binding Config.RangeLeft, StringFormat=\{0:0.00\}}" />
@@ -525,9 +251,9 @@
VerticalAlignment="Center"
Text="{locale:Locale ControllerSettingsDPadUp}"
TextAlignment="Center" />
-
+
@@ -542,9 +268,9 @@
VerticalAlignment="Center"
Text="{locale:Locale ControllerSettingsDPadDown}"
TextAlignment="Center" />
-
+
@@ -559,9 +285,9 @@
VerticalAlignment="Center"
Text="{locale:Locale ControllerSettingsDPadLeft}"
TextAlignment="Center" />
-
+
@@ -576,9 +302,9 @@
VerticalAlignment="Center"
Text="{locale:Locale ControllerSettingsDPadRight}"
TextAlignment="Center" />
-
+
@@ -591,6 +317,13 @@
Grid.Column="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
+
+
+ Value="{Binding Config.TriggerThreshold, Mode=TwoWay}" />
+ Text="{Binding Config.TriggerThreshold, StringFormat=\{0:0.00\}}" />
-
+
-
+ IsVisible="{Binding IsLeft}"
+ Orientation="Horizontal">
-
-
-
-
+
+
+
+
-
+ IsVisible="{Binding IsLeft}"
+ Orientation="Horizontal">
-
-
-
-
+
+
+
+
-
+ IsVisible="{Binding IsRight}"
+ Orientation="Horizontal">
-
-
-
-
+
+
+
+
-
+ IsVisible="{Binding IsRight}"
+ Orientation="Horizontal">
-
+
+
+
+
-
-
+ HorizontalAlignment="Stretch">
@@ -720,7 +449,7 @@
Margin="10"
MinWidth="0"
Grid.Column="0"
- IsChecked="{ReflectionBinding Configuration.EnableMotion, Mode=TwoWay}">
+ IsChecked="{Binding Config.EnableMotion, Mode=TwoWay}">
@@ -811,9 +539,9 @@
VerticalAlignment="Center"
Text="{locale:Locale ControllerSettingsTriggerR}"
TextAlignment="Center" />
-
+
@@ -829,15 +557,15 @@
VerticalAlignment="Center"
Text="{locale:Locale ControllerSettingsButtonPlus}"
TextAlignment="Center" />
-
+
-
+
-
+
@@ -881,9 +609,9 @@
VerticalAlignment="Center"
Text="{locale:Locale ControllerSettingsButtonB}"
TextAlignment="Center" />
-
+
@@ -898,9 +626,9 @@
VerticalAlignment="Center"
Text="{locale:Locale ControllerSettingsButtonX}"
TextAlignment="Center" />
-
+
@@ -915,9 +643,9 @@
VerticalAlignment="Center"
Text="{locale:Locale ControllerSettingsButtonY}"
TextAlignment="Center" />
-
+
@@ -937,100 +665,8 @@
Margin="0,0,0,10"
HorizontalAlignment="Center"
Text="{locale:Locale ControllerSettingsRStick}" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -1041,9 +677,9 @@
VerticalAlignment="Center"
Text="{locale:Locale ControllerSettingsStickButton}"
TextAlignment="Center" />
-
+
@@ -1059,20 +695,20 @@
VerticalAlignment="Center"
Text="{locale:Locale ControllerSettingsStickStick}"
TextAlignment="Center" />
-
+
-
+
-
+
-
+
@@ -1093,11 +729,11 @@
Padding="0"
VerticalAlignment="Center"
Minimum="0"
- Value="{ReflectionBinding Configuration.DeadzoneRight, Mode=TwoWay}" />
+ Value="{Binding Config.DeadzoneRight, Mode=TwoWay}" />
+ Text="{Binding Config.DeadzoneRight, StringFormat=\{0:0.00\}}" />
+ Value="{Binding Config.RangeRight, Mode=TwoWay}" />
+ Text="{Binding Config.RangeRight, StringFormat=\{0:0.00\}}" />
diff --git a/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml.cs
index 3512970602..52fc62389e 100644
--- a/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Views/Input/ControllerInputView.axaml.cs
@@ -1,35 +1,28 @@
+using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.LogicalTree;
-using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.UI.Helpers;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.Ava.UI.ViewModels;
+using Ryujinx.Ava.UI.ViewModels.Input;
using Ryujinx.Common.Configuration.Hid.Controller;
using Ryujinx.Input;
using Ryujinx.Input.Assigner;
-using System;
namespace Ryujinx.Ava.UI.Views.Input
{
public partial class ControllerInputView : UserControl
{
- private bool _dialogOpen;
-
private ButtonKeyAssigner _currentAssigner;
- internal ControllerInputViewModel ViewModel { get; set; }
public ControllerInputView()
{
- DataContext = ViewModel = new ControllerInputViewModel(this);
-
InitializeComponent();
foreach (ILogical visual in SettingButtons.GetLogicalDescendants())
{
- if (visual is ToggleButton button && visual is not CheckBox)
+ if (visual is ToggleButton button and not CheckBox)
{
button.IsCheckedChanged += Button_IsCheckedChanged;
}
@@ -59,7 +52,7 @@ namespace Ryujinx.Ava.UI.Views.Input
bool isStick = button.Tag != null && button.Tag.ToString() == "stick";
- if (_currentAssigner == null)
+ if (_currentAssigner == null && (bool)button.IsChecked)
{
_currentAssigner = new ButtonKeyAssigner(button);
@@ -67,14 +60,86 @@ namespace Ryujinx.Ava.UI.Views.Input
PointerPressed += MouseClick;
- IKeyboard keyboard = (IKeyboard)ViewModel.AvaloniaKeyboardDriver.GetGamepad("0"); // Open Avalonia keyboard for cancel operations.
+ IKeyboard keyboard = (IKeyboard)(DataContext as ControllerInputViewModel).parentModel.AvaloniaKeyboardDriver.GetGamepad("0"); // Open Avalonia keyboard for cancel operations.
IButtonAssigner assigner = CreateButtonAssigner(isStick);
_currentAssigner.ButtonAssigned += (sender, e) =>
{
- if (e.IsAssigned)
+ if (e.ButtonValue.HasValue)
{
- ViewModel.IsModified = true;
+ var viewModel = (DataContext as ControllerInputViewModel);
+ var buttonValue = e.ButtonValue.Value;
+ viewModel.parentModel.IsModified = true;
+
+ switch (button.Name)
+ {
+ case "ButtonZl":
+ viewModel.Config.ButtonZl = buttonValue.AsGamepadButtonInputId();
+ break;
+ case "ButtonL":
+ viewModel.Config.ButtonL = buttonValue.AsGamepadButtonInputId();
+ break;
+ case "ButtonMinus":
+ viewModel.Config.ButtonMinus = buttonValue.AsGamepadButtonInputId();
+ break;
+ case "LeftStickButton":
+ viewModel.Config.LeftStickButton = buttonValue.AsGamepadButtonInputId();
+ break;
+ case "LeftJoystick":
+ viewModel.Config.LeftJoystick = buttonValue.AsGamepadStickId();
+ break;
+ case "DpadUp":
+ viewModel.Config.DpadUp = buttonValue.AsGamepadButtonInputId();
+ break;
+ case "DpadDown":
+ viewModel.Config.DpadDown = buttonValue.AsGamepadButtonInputId();
+ break;
+ case "DpadLeft":
+ viewModel.Config.DpadLeft = buttonValue.AsGamepadButtonInputId();
+ break;
+ case "DpadRight":
+ viewModel.Config.DpadRight = buttonValue.AsGamepadButtonInputId();
+ break;
+ case "LeftButtonSr":
+ viewModel.Config.LeftButtonSr = buttonValue.AsGamepadButtonInputId();
+ break;
+ case "LeftButtonSl":
+ viewModel.Config.LeftButtonSl = buttonValue.AsGamepadButtonInputId();
+ break;
+ case "RightButtonSr":
+ viewModel.Config.RightButtonSr = buttonValue.AsGamepadButtonInputId();
+ break;
+ case "RightButtonSl":
+ viewModel.Config.RightButtonSl = buttonValue.AsGamepadButtonInputId();
+ break;
+ case "ButtonZr":
+ viewModel.Config.ButtonZr = buttonValue.AsGamepadButtonInputId();
+ break;
+ case "ButtonR":
+ viewModel.Config.ButtonR = buttonValue.AsGamepadButtonInputId();
+ break;
+ case "ButtonPlus":
+ viewModel.Config.ButtonPlus = buttonValue.AsGamepadButtonInputId();
+ break;
+ case "ButtonA":
+ viewModel.Config.ButtonA = buttonValue.AsGamepadButtonInputId();
+ break;
+ case "ButtonB":
+ viewModel.Config.ButtonB = buttonValue.AsGamepadButtonInputId();
+ break;
+ case "ButtonX":
+ viewModel.Config.ButtonX = buttonValue.AsGamepadButtonInputId();
+ break;
+ case "ButtonY":
+ viewModel.Config.ButtonY = buttonValue.AsGamepadButtonInputId();
+ break;
+ case "RightStickButton":
+ viewModel.Config.RightStickButton = buttonValue.AsGamepadButtonInputId();
+ break;
+ case "RightJoystick":
+ viewModel.Config.RightJoystick = buttonValue.AsGamepadStickId();
+ break;
+ }
}
};
@@ -100,82 +165,29 @@ namespace Ryujinx.Ava.UI.Views.Input
}
}
- public void SaveCurrentProfile()
- {
- ViewModel.Save();
- }
-
- private IButtonAssigner CreateButtonAssigner(bool forStick)
- {
- IButtonAssigner assigner;
-
- var device = ViewModel.Devices[ViewModel.Device];
-
- if (device.Type == DeviceType.Keyboard)
- {
- assigner = new KeyboardKeyAssigner((IKeyboard)ViewModel.SelectedGamepad);
- }
- else if (device.Type == DeviceType.Controller)
- {
- assigner = new GamepadButtonAssigner(ViewModel.SelectedGamepad, (ViewModel.Config as StandardControllerInputConfig).TriggerThreshold, forStick);
- }
- else
- {
- throw new Exception("Controller not supported");
- }
-
- return assigner;
- }
-
private void MouseClick(object sender, PointerPressedEventArgs e)
{
- bool shouldUnbind = false;
-
- if (e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed)
- {
- shouldUnbind = true;
- }
+ bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed;
_currentAssigner?.Cancel(shouldUnbind);
PointerPressed -= MouseClick;
}
- private async void PlayerIndexBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
+ private IButtonAssigner CreateButtonAssigner(bool forStick)
{
- if (ViewModel.IsModified && !_dialogOpen)
- {
- _dialogOpen = true;
+ IButtonAssigner assigner;
- var result = await ContentDialogHelper.CreateConfirmationDialog(
- LocaleManager.Instance[LocaleKeys.DialogControllerSettingsModifiedConfirmMessage],
- LocaleManager.Instance[LocaleKeys.DialogControllerSettingsModifiedConfirmSubMessage],
- LocaleManager.Instance[LocaleKeys.InputDialogYes],
- LocaleManager.Instance[LocaleKeys.InputDialogNo],
- LocaleManager.Instance[LocaleKeys.RyujinxConfirm]);
+ assigner = new GamepadButtonAssigner((DataContext as ControllerInputViewModel).parentModel.SelectedGamepad, ((DataContext as ControllerInputViewModel).parentModel.Config as StandardControllerInputConfig).TriggerThreshold, forStick);
- if (result == UserResult.Yes)
- {
- ViewModel.Save();
- }
-
- _dialogOpen = false;
-
- ViewModel.IsModified = false;
-
- if (e.AddedItems.Count > 0)
- {
- var player = (PlayerModel)e.AddedItems[0];
- ViewModel.PlayerId = player.Id;
- }
- }
+ return assigner;
}
- public void Dispose()
+ protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
{
+ base.OnDetachedFromVisualTree(e);
_currentAssigner?.Cancel();
_currentAssigner = null;
- ViewModel.Dispose();
}
}
}
diff --git a/src/Ryujinx.Ava/UI/Views/Input/InputView.axaml b/src/Ryujinx.Ava/UI/Views/Input/InputView.axaml
new file mode 100644
index 0000000000..b4940941cc
--- /dev/null
+++ b/src/Ryujinx.Ava/UI/Views/Input/InputView.axaml
@@ -0,0 +1,225 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Ryujinx.Ava/UI/Views/Input/InputView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Input/InputView.axaml.cs
new file mode 100644
index 0000000000..356381a8aa
--- /dev/null
+++ b/src/Ryujinx.Ava/UI/Views/Input/InputView.axaml.cs
@@ -0,0 +1,61 @@
+using Avalonia.Controls;
+using Ryujinx.Ava.Common.Locale;
+using Ryujinx.Ava.UI.Helpers;
+using Ryujinx.Ava.UI.Models;
+using Ryujinx.Ava.UI.ViewModels.Input;
+
+namespace Ryujinx.Ava.UI.Views.Input
+{
+ public partial class InputView : UserControl
+ {
+ private bool _dialogOpen;
+ private InputViewModel ViewModel { get; set; }
+
+ public InputView()
+ {
+ DataContext = ViewModel = new InputViewModel(this);
+
+ InitializeComponent();
+ }
+
+ public void SaveCurrentProfile()
+ {
+ ViewModel.Save();
+ }
+
+ private async void PlayerIndexBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if (ViewModel.IsModified && !_dialogOpen)
+ {
+ _dialogOpen = true;
+
+ var result = await ContentDialogHelper.CreateConfirmationDialog(
+ LocaleManager.Instance[LocaleKeys.DialogControllerSettingsModifiedConfirmMessage],
+ LocaleManager.Instance[LocaleKeys.DialogControllerSettingsModifiedConfirmSubMessage],
+ LocaleManager.Instance[LocaleKeys.InputDialogYes],
+ LocaleManager.Instance[LocaleKeys.InputDialogNo],
+ LocaleManager.Instance[LocaleKeys.RyujinxConfirm]);
+
+ if (result == UserResult.Yes)
+ {
+ ViewModel.Save();
+ }
+
+ _dialogOpen = false;
+
+ ViewModel.IsModified = false;
+
+ if (e.AddedItems.Count > 0)
+ {
+ var player = (PlayerModel)e.AddedItems[0];
+ ViewModel.PlayerId = player.Id;
+ }
+ }
+ }
+
+ public void Dispose()
+ {
+ ViewModel.Dispose();
+ }
+ }
+}
diff --git a/src/Ryujinx.Ava/UI/Views/Input/KeyboardInputView.axaml b/src/Ryujinx.Ava/UI/Views/Input/KeyboardInputView.axaml
new file mode 100644
index 0000000000..e4566f463d
--- /dev/null
+++ b/src/Ryujinx.Ava/UI/Views/Input/KeyboardInputView.axaml
@@ -0,0 +1,675 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Ryujinx.Ava/UI/Views/Input/KeyboardInputView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Input/KeyboardInputView.axaml.cs
new file mode 100644
index 0000000000..f7024c5d1a
--- /dev/null
+++ b/src/Ryujinx.Ava/UI/Views/Input/KeyboardInputView.axaml.cs
@@ -0,0 +1,210 @@
+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;
+
+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 != null && _currentAssigner.ToggledButton != null && !_currentAssigner.ToggledButton.IsPointerOver)
+ {
+ _currentAssigner.Cancel();
+ }
+ }
+
+ private void Button_IsCheckedChanged(object sender, RoutedEventArgs e)
+ {
+ if (sender is ToggleButton button)
+ {
+ if ((bool)button.IsChecked)
+ {
+ if (_currentAssigner != null && button == _currentAssigner.ToggledButton)
+ {
+ return;
+ }
+
+ bool isStick = button.Tag != null && button.Tag.ToString() == "stick";
+
+ if (_currentAssigner == null && (bool)button.IsChecked)
+ {
+ _currentAssigner = new ButtonKeyAssigner(button);
+
+ this.Focus(NavigationMethod.Pointer);
+
+ PointerPressed += MouseClick;
+
+ IKeyboard keyboard = (IKeyboard)(DataContext as KeyboardInputViewModel).parentModel.AvaloniaKeyboardDriver.GetGamepad("0"); // Open Avalonia keyboard for cancel operations.
+ IButtonAssigner assigner = CreateButtonAssigner(isStick);
+
+ _currentAssigner.ButtonAssigned += (sender, e) =>
+ {
+ if (e.ButtonValue.HasValue)
+ {
+ var viewModel = (DataContext as KeyboardInputViewModel);
+ var buttonValue = e.ButtonValue.Value;
+ viewModel.parentModel.IsModified = true;
+
+ switch (button.Name)
+ {
+ case "ButtonZl":
+ viewModel.Config.ButtonZl = buttonValue.AsKey();
+ break;
+ case "ButtonL":
+ viewModel.Config.ButtonL = buttonValue.AsKey();
+ break;
+ case "ButtonMinus":
+ viewModel.Config.ButtonMinus = buttonValue.AsKey();
+ break;
+ case "LeftStickButton":
+ viewModel.Config.LeftStickButton = buttonValue.AsKey();
+ break;
+ case "LeftStickUp":
+ viewModel.Config.LeftStickUp = buttonValue.AsKey();
+ break;
+ case "LeftStickDown":
+ viewModel.Config.LeftStickDown = buttonValue.AsKey();
+ break;
+ case "LeftStickRight":
+ viewModel.Config.LeftStickRight = buttonValue.AsKey();
+ break;
+ case "LeftStickLeft":
+ viewModel.Config.LeftStickLeft = buttonValue.AsKey();
+ break;
+ case "DpadUp":
+ viewModel.Config.DpadUp = buttonValue.AsKey();
+ break;
+ case "DpadDown":
+ viewModel.Config.DpadDown = buttonValue.AsKey();
+ break;
+ case "DpadLeft":
+ viewModel.Config.DpadLeft = buttonValue.AsKey();
+ break;
+ case "DpadRight":
+ viewModel.Config.DpadRight = buttonValue.AsKey();
+ break;
+ case "LeftButtonSr":
+ viewModel.Config.LeftButtonSr = buttonValue.AsKey();
+ break;
+ case "LeftButtonSl":
+ viewModel.Config.LeftButtonSl = buttonValue.AsKey();
+ break;
+ case "RightButtonSr":
+ viewModel.Config.RightButtonSr = buttonValue.AsKey();
+ break;
+ case "RightButtonSl":
+ viewModel.Config.RightButtonSl = buttonValue.AsKey();
+ break;
+ case "ButtonZr":
+ viewModel.Config.ButtonZr = buttonValue.AsKey();
+ break;
+ case "ButtonR":
+ viewModel.Config.ButtonR = buttonValue.AsKey();
+ break;
+ case "ButtonPlus":
+ viewModel.Config.ButtonPlus = buttonValue.AsKey();
+ break;
+ case "ButtonA":
+ viewModel.Config.ButtonA = buttonValue.AsKey();
+ break;
+ case "ButtonB":
+ viewModel.Config.ButtonB = buttonValue.AsKey();
+ break;
+ case "ButtonX":
+ viewModel.Config.ButtonX = buttonValue.AsKey();
+ break;
+ case "ButtonY":
+ viewModel.Config.ButtonY = buttonValue.AsKey();
+ break;
+ case "RightStickButton":
+ viewModel.Config.RightStickButton = buttonValue.AsKey();
+ break;
+ case "RightStickUp":
+ viewModel.Config.RightStickUp = buttonValue.AsKey();
+ break;
+ case "RightStickDown":
+ viewModel.Config.RightStickDown = buttonValue.AsKey();
+ break;
+ case "RightStickRight":
+ viewModel.Config.RightStickRight = buttonValue.AsKey();
+ break;
+ case "RightStickLeft":
+ viewModel.Config.RightStickLeft = buttonValue.AsKey();
+ break;
+ }
+ }
+ };
+
+ _currentAssigner.GetInputAndAssign(assigner, keyboard);
+ }
+ else
+ {
+ if (_currentAssigner != null)
+ {
+ ToggleButton oldButton = _currentAssigner.ToggledButton;
+
+ _currentAssigner.Cancel();
+ _currentAssigner = null;
+ button.IsChecked = false;
+ }
+ }
+ }
+ else
+ {
+ _currentAssigner?.Cancel();
+ _currentAssigner = null;
+ }
+ }
+ }
+
+ private void MouseClick(object sender, PointerPressedEventArgs e)
+ {
+ bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed;
+
+ _currentAssigner?.Cancel(shouldUnbind);
+
+ PointerPressed -= MouseClick;
+ }
+
+ private IButtonAssigner CreateButtonAssigner(bool forStick)
+ {
+ IButtonAssigner assigner;
+
+ assigner = new KeyboardKeyAssigner((IKeyboard)(DataContext as KeyboardInputViewModel).parentModel.SelectedGamepad);
+
+ return assigner;
+ }
+
+ protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
+ {
+ base.OnDetachedFromVisualTree(e);
+ _currentAssigner?.Cancel();
+ _currentAssigner = null;
+ }
+ }
+}
diff --git a/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml b/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml
index a6b587f671..0d018e297a 100644
--- a/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml
@@ -6,7 +6,7 @@
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
+ xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels.Input"
mc:Ignorable="d"
x:Class="Ryujinx.Ava.UI.Views.Input.MotionInputView"
x:DataType="viewModels:MotionInputViewModel"
diff --git a/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml.cs
index 1b340752b1..2304364b67 100644
--- a/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Views/Input/MotionInputView.axaml.cs
@@ -1,9 +1,7 @@
using Avalonia.Controls;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.Common.Configuration.Hid.Controller;
+using Ryujinx.Ava.UI.ViewModels.Input;
using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Views.Input
@@ -19,7 +17,7 @@ namespace Ryujinx.Ava.UI.Views.Input
public MotionInputView(ControllerInputViewModel viewModel)
{
- var config = viewModel.Configuration as InputConfiguration;
+ var config = viewModel.Config;
_viewModel = new MotionInputViewModel
{
@@ -51,7 +49,7 @@ namespace Ryujinx.Ava.UI.Views.Input
};
contentDialog.PrimaryButtonClick += (sender, args) =>
{
- var config = viewModel.Configuration as InputConfiguration;
+ var config = viewModel.Config;
config.Slot = content._viewModel.Slot;
config.Sensitivity = content._viewModel.Sensitivity;
config.GyroDeadzone = content._viewModel.GyroDeadzone;
diff --git a/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml b/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml
index 5b7087a470..1beb1f06e8 100644
--- a/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml
@@ -5,7 +5,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
+ xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels.Input"
mc:Ignorable="d"
x:Class="Ryujinx.Ava.UI.Views.Input.RumbleInputView"
x:DataType="viewModels:RumbleInputViewModel"
diff --git a/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml.cs
index 9307f872c3..58a4b416b6 100644
--- a/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Views/Input/RumbleInputView.axaml.cs
@@ -1,9 +1,7 @@
using Avalonia.Controls;
using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Ava.UI.Models;
-using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.Common.Configuration.Hid.Controller;
+using Ryujinx.Ava.UI.ViewModels.Input;
using System.Threading.Tasks;
namespace Ryujinx.Ava.UI.Views.Input
@@ -19,7 +17,7 @@ namespace Ryujinx.Ava.UI.Views.Input
public RumbleInputView(ControllerInputViewModel viewModel)
{
- var config = viewModel.Configuration as InputConfiguration;
+ var config = viewModel.Config;
_viewModel = new RumbleInputViewModel
{
@@ -47,7 +45,7 @@ namespace Ryujinx.Ava.UI.Views.Input
contentDialog.PrimaryButtonClick += (sender, args) =>
{
- var config = viewModel.Configuration as InputConfiguration;
+ var config = viewModel.Config;
config.StrongRumble = content._viewModel.StrongRumble;
config.WeakRumble = content._viewModel.WeakRumble;
};
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml b/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml
index 81f4b68b74..55c2ed6e3c 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml
+++ b/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml
@@ -27,9 +27,9 @@
-
+ Name="InputView" />
diff --git a/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml.cs b/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml.cs
index 8a0cb8ab9c..85ccffccd5 100644
--- a/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Views/Settings/SettingsInputView.axaml.cs
@@ -11,7 +11,7 @@ namespace Ryujinx.Ava.UI.Views.Settings
public void Dispose()
{
- ControllerSettings.Dispose();
+ InputView.Dispose();
}
}
}
diff --git a/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml.cs b/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml.cs
index d7bb0b8837..314501c525 100644
--- a/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml.cs
+++ b/src/Ryujinx.Ava/UI/Windows/SettingsWindow.axaml.cs
@@ -37,7 +37,7 @@ namespace Ryujinx.Ava.UI.Windows
public void SaveSettings()
{
- InputPage.ControllerSettings?.SaveCurrentProfile();
+ InputPage.InputView?.SaveCurrentProfile();
if (Owner is MainWindow window && ViewModel.DirectoryChanged)
{
diff --git a/src/Ryujinx.Input/Assigner/GamepadButtonAssigner.cs b/src/Ryujinx.Input/Assigner/GamepadButtonAssigner.cs
index 388ebcc07a..bf8319a6a9 100644
--- a/src/Ryujinx.Input/Assigner/GamepadButtonAssigner.cs
+++ b/src/Ryujinx.Input/Assigner/GamepadButtonAssigner.cs
@@ -59,16 +59,16 @@ namespace Ryujinx.Input.Assigner
return _gamepad == null || !_gamepad.IsConnected;
}
- public string GetPressedButton()
+ public ButtonValue? GetPressedButton()
{
IEnumerable pressedButtons = _detector.GetPressedButtons();
if (pressedButtons.Any())
{
- return !_forStick ? pressedButtons.First().ToString() : ((StickInputId)pressedButtons.First()).ToString();
+ return !_forStick ? new(pressedButtons.First()) : new(((StickInputId)pressedButtons.First()));
}
- return "";
+ return null;
}
private void CollectButtonStats()
diff --git a/src/Ryujinx.Input/Assigner/IButtonAssigner.cs b/src/Ryujinx.Input/Assigner/IButtonAssigner.cs
index 76a9fece49..6537171339 100644
--- a/src/Ryujinx.Input/Assigner/IButtonAssigner.cs
+++ b/src/Ryujinx.Input/Assigner/IButtonAssigner.cs
@@ -31,6 +31,6 @@ namespace Ryujinx.Input.Assigner
/// Get the pressed button that was read in by the button assigner.
///
/// The pressed button that was read
- string GetPressedButton();
+ ButtonValue? GetPressedButton();
}
}
diff --git a/src/Ryujinx.Input/Assigner/KeyboardKeyAssigner.cs b/src/Ryujinx.Input/Assigner/KeyboardKeyAssigner.cs
index e52ef4a2ce..c66812ba03 100644
--- a/src/Ryujinx.Input/Assigner/KeyboardKeyAssigner.cs
+++ b/src/Ryujinx.Input/Assigner/KeyboardKeyAssigner.cs
@@ -23,7 +23,7 @@ namespace Ryujinx.Input.Assigner
public bool HasAnyButtonPressed()
{
- return GetPressedButton().Length != 0;
+ return GetPressedButton() is not null;
}
public bool ShouldCancel()
@@ -31,20 +31,20 @@ namespace Ryujinx.Input.Assigner
return _keyboardState.IsPressed(Key.Escape);
}
- public string GetPressedButton()
+ public ButtonValue? GetPressedButton()
{
- string keyPressed = "";
+ ButtonValue? keyPressed = null;
for (Key key = Key.Unknown; key < Key.Count; key++)
{
if (_keyboardState.IsPressed(key))
{
- keyPressed = key.ToString();
+ keyPressed = new(key);
break;
}
}
- return !ShouldCancel() ? keyPressed : "";
+ return !ShouldCancel() ? keyPressed : null;
}
}
}
diff --git a/src/Ryujinx.Input/ButtonValue.cs b/src/Ryujinx.Input/ButtonValue.cs
new file mode 100644
index 0000000000..f037e6b60a
--- /dev/null
+++ b/src/Ryujinx.Input/ButtonValue.cs
@@ -0,0 +1,48 @@
+using System.Diagnostics;
+
+namespace Ryujinx.Input
+{
+ public enum ButtonValueType { Key, GamepadButtonInputId, StickId }
+
+ public readonly struct ButtonValue
+ {
+ private readonly ButtonValueType _type;
+ private readonly uint _rawValue;
+
+ public ButtonValue(Key key)
+ {
+ _type = ButtonValueType.Key;
+ _rawValue = (uint)key;
+ }
+
+ public ButtonValue(GamepadButtonInputId gamepad)
+ {
+ _type = ButtonValueType.GamepadButtonInputId;
+ _rawValue = (uint)gamepad;
+ }
+
+ public ButtonValue(StickInputId stick)
+ {
+ _type = ButtonValueType.StickId;
+ _rawValue = (uint)stick;
+ }
+
+ public Common.Configuration.Hid.Key AsKey()
+ {
+ Debug.Assert(_type == ButtonValueType.Key);
+ return (Common.Configuration.Hid.Key)_rawValue;
+ }
+
+ public Common.Configuration.Hid.Controller.GamepadInputId AsGamepadButtonInputId()
+ {
+ Debug.Assert(_type == ButtonValueType.GamepadButtonInputId);
+ return (Common.Configuration.Hid.Controller.GamepadInputId)_rawValue;
+ }
+
+ public Common.Configuration.Hid.Controller.StickInputId AsGamepadStickId()
+ {
+ Debug.Assert(_type == ButtonValueType.StickId);
+ return (Common.Configuration.Hid.Controller.StickInputId)_rawValue;
+ }
+ }
+}
diff --git a/src/Ryujinx/Ui/Windows/ControllerWindow.cs b/src/Ryujinx/Ui/Windows/ControllerWindow.cs
index ebf22ab607..52cad5c858 100644
--- a/src/Ryujinx/Ui/Windows/ControllerWindow.cs
+++ b/src/Ryujinx/Ui/Windows/ControllerWindow.cs
@@ -893,7 +893,7 @@ namespace Ryujinx.Ui.Windows
}
}
- string pressedButton = assigner.GetPressedButton();
+ string pressedButton = assigner.GetPressedButton().ToString();
Application.Invoke(delegate
{