forked from Mirror/Ryujinx
Ava UI: Input Menu Refactor (#5826)
* Refactor * Apply suggestions from code review Co-authored-by: Ac_K <Acoustik666@gmail.com> * Update src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml.cs Co-authored-by: Ac_K <Acoustik666@gmail.com> * Update src/Ryujinx.Input/ButtonValueType.cs Co-authored-by: Ac_K <Acoustik666@gmail.com> * Add empty line * Requested renames * Update src/Ryujinx/UI/Views/Settings/SettingsHotkeysView.axaml.cs Co-authored-by: gdkchan <gab.dark.100@gmail.com> * Make parent models private readonly * Fix ControllerInputView * Make line shorter * Mac keys in locale * Double line break * Fix build * Get rid of _isValid * Fix potential race condition * Rename HasAnyButtonPressed to IsAnyButtonPressed * Use switches * Simplify enumeration --------- Co-authored-by: Ac_K <Acoustik666@gmail.com> Co-authored-by: gdkchan <gab.dark.100@gmail.com> Co-authored-by: TSR Berry <20988865+TSRBerry@users.noreply.github.com>
This commit is contained in:
parent
8884d1fd73
commit
446f2854a5
38 changed files with 3402 additions and 1275 deletions
|
@ -1,7 +1,5 @@
|
||||||
namespace Ryujinx.Common.Configuration.Hid
|
namespace Ryujinx.Common.Configuration.Hid
|
||||||
{
|
{
|
||||||
// NOTE: Please don't change this to struct.
|
|
||||||
// This breaks Avalonia's TwoWay binding, which makes us unable to save new KeyboardHotkeys.
|
|
||||||
public class KeyboardHotkeys
|
public class KeyboardHotkeys
|
||||||
{
|
{
|
||||||
public Key ToggleVsync { get; set; }
|
public Key ToggleVsync { get; set; }
|
||||||
|
|
158
src/Ryujinx.Gtk3/UI/Helper/ButtonHelper.cs
Normal file
158
src/Ryujinx.Gtk3/UI/Helper/ButtonHelper.cs
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
using Ryujinx.Common.Configuration.Hid.Controller;
|
||||||
|
using Ryujinx.Input;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Key = Ryujinx.Common.Configuration.Hid.Key;
|
||||||
|
using StickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
|
||||||
|
|
||||||
|
namespace Ryujinx.UI.Helper
|
||||||
|
{
|
||||||
|
public static class ButtonHelper
|
||||||
|
{
|
||||||
|
private static readonly Dictionary<Key, string> _keysMap = new()
|
||||||
|
{
|
||||||
|
{ Key.Unknown, "Unknown" },
|
||||||
|
{ Key.ShiftLeft, "ShiftLeft" },
|
||||||
|
{ Key.ShiftRight, "ShiftRight" },
|
||||||
|
{ Key.ControlLeft, "CtrlLeft" },
|
||||||
|
{ Key.ControlRight, "CtrlRight" },
|
||||||
|
{ Key.AltLeft, OperatingSystem.IsMacOS() ? "OptLeft" : "AltLeft" },
|
||||||
|
{ Key.AltRight, OperatingSystem.IsMacOS() ? "OptRight" : "AltRight" },
|
||||||
|
{ Key.WinLeft, OperatingSystem.IsMacOS() ? "CmdLeft" : "WinLeft" },
|
||||||
|
{ Key.WinRight, OperatingSystem.IsMacOS() ? "CmdRight" : "WinRight" },
|
||||||
|
{ Key.Up, "Up" },
|
||||||
|
{ Key.Down, "Down" },
|
||||||
|
{ Key.Left, "Left" },
|
||||||
|
{ Key.Right, "Right" },
|
||||||
|
{ Key.Enter, "Enter" },
|
||||||
|
{ Key.Escape, "Escape" },
|
||||||
|
{ Key.Space, "Space" },
|
||||||
|
{ Key.Tab, "Tab" },
|
||||||
|
{ Key.BackSpace, "Backspace" },
|
||||||
|
{ Key.Insert, "Insert" },
|
||||||
|
{ Key.Delete, "Delete" },
|
||||||
|
{ Key.PageUp, "PageUp" },
|
||||||
|
{ Key.PageDown, "PageDown" },
|
||||||
|
{ Key.Home, "Home" },
|
||||||
|
{ Key.End, "End" },
|
||||||
|
{ Key.CapsLock, "CapsLock" },
|
||||||
|
{ Key.ScrollLock, "ScrollLock" },
|
||||||
|
{ Key.PrintScreen, "PrintScreen" },
|
||||||
|
{ Key.Pause, "Pause" },
|
||||||
|
{ Key.NumLock, "NumLock" },
|
||||||
|
{ Key.Clear, "Clear" },
|
||||||
|
{ Key.Keypad0, "Keypad0" },
|
||||||
|
{ Key.Keypad1, "Keypad1" },
|
||||||
|
{ Key.Keypad2, "Keypad2" },
|
||||||
|
{ Key.Keypad3, "Keypad3" },
|
||||||
|
{ Key.Keypad4, "Keypad4" },
|
||||||
|
{ Key.Keypad5, "Keypad5" },
|
||||||
|
{ Key.Keypad6, "Keypad6" },
|
||||||
|
{ Key.Keypad7, "Keypad7" },
|
||||||
|
{ Key.Keypad8, "Keypad8" },
|
||||||
|
{ Key.Keypad9, "Keypad9" },
|
||||||
|
{ Key.KeypadDivide, "KeypadDivide" },
|
||||||
|
{ Key.KeypadMultiply, "KeypadMultiply" },
|
||||||
|
{ Key.KeypadSubtract, "KeypadSubtract" },
|
||||||
|
{ Key.KeypadAdd, "KeypadAdd" },
|
||||||
|
{ Key.KeypadDecimal, "KeypadDecimal" },
|
||||||
|
{ Key.KeypadEnter, "KeypadEnter" },
|
||||||
|
{ Key.Number0, "0" },
|
||||||
|
{ Key.Number1, "1" },
|
||||||
|
{ Key.Number2, "2" },
|
||||||
|
{ Key.Number3, "3" },
|
||||||
|
{ Key.Number4, "4" },
|
||||||
|
{ Key.Number5, "5" },
|
||||||
|
{ Key.Number6, "6" },
|
||||||
|
{ Key.Number7, "7" },
|
||||||
|
{ Key.Number8, "8" },
|
||||||
|
{ Key.Number9, "9" },
|
||||||
|
{ Key.Tilde, "~" },
|
||||||
|
{ Key.Grave, "`" },
|
||||||
|
{ Key.Minus, "-" },
|
||||||
|
{ Key.Plus, "+" },
|
||||||
|
{ Key.BracketLeft, "[" },
|
||||||
|
{ Key.BracketRight, "]" },
|
||||||
|
{ Key.Semicolon, ";" },
|
||||||
|
{ Key.Quote, "'" },
|
||||||
|
{ Key.Comma, "," },
|
||||||
|
{ Key.Period, "." },
|
||||||
|
{ Key.Slash, "/" },
|
||||||
|
{ Key.BackSlash, "\\" },
|
||||||
|
{ Key.Unbound, "Unbound" },
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly Dictionary<GamepadInputId, string> _gamepadInputIdMap = new()
|
||||||
|
{
|
||||||
|
{ GamepadInputId.LeftStick, "LeftStick" },
|
||||||
|
{ GamepadInputId.RightStick, "RightStick" },
|
||||||
|
{ GamepadInputId.LeftShoulder, "LeftShoulder" },
|
||||||
|
{ GamepadInputId.RightShoulder, "RightShoulder" },
|
||||||
|
{ GamepadInputId.LeftTrigger, "LeftTrigger" },
|
||||||
|
{ GamepadInputId.RightTrigger, "RightTrigger" },
|
||||||
|
{ GamepadInputId.DpadUp, "DpadUp" },
|
||||||
|
{ GamepadInputId.DpadDown, "DpadDown" },
|
||||||
|
{ GamepadInputId.DpadLeft, "DpadLeft" },
|
||||||
|
{ GamepadInputId.DpadRight, "DpadRight" },
|
||||||
|
{ GamepadInputId.Minus, "Minus" },
|
||||||
|
{ GamepadInputId.Plus, "Plus" },
|
||||||
|
{ GamepadInputId.Guide, "Guide" },
|
||||||
|
{ GamepadInputId.Misc1, "Misc1" },
|
||||||
|
{ GamepadInputId.Paddle1, "Paddle1" },
|
||||||
|
{ GamepadInputId.Paddle2, "Paddle2" },
|
||||||
|
{ GamepadInputId.Paddle3, "Paddle3" },
|
||||||
|
{ GamepadInputId.Paddle4, "Paddle4" },
|
||||||
|
{ GamepadInputId.Touchpad, "Touchpad" },
|
||||||
|
{ GamepadInputId.SingleLeftTrigger0, "SingleLeftTrigger0" },
|
||||||
|
{ GamepadInputId.SingleRightTrigger0, "SingleRightTrigger0" },
|
||||||
|
{ GamepadInputId.SingleLeftTrigger1, "SingleLeftTrigger1" },
|
||||||
|
{ GamepadInputId.SingleRightTrigger1, "SingleRightTrigger1" },
|
||||||
|
{ GamepadInputId.Unbound, "Unbound" },
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly Dictionary<StickInputId, string> _stickInputIdMap = new()
|
||||||
|
{
|
||||||
|
{ StickInputId.Left, "StickLeft" },
|
||||||
|
{ StickInputId.Right, "StickRight" },
|
||||||
|
{ StickInputId.Unbound, "Unbound" },
|
||||||
|
};
|
||||||
|
|
||||||
|
public static string ToString(Button button)
|
||||||
|
{
|
||||||
|
string keyString = "";
|
||||||
|
|
||||||
|
switch (button.Type)
|
||||||
|
{
|
||||||
|
case ButtonType.Key:
|
||||||
|
var key = button.AsHidType<Key>();
|
||||||
|
|
||||||
|
if (!_keysMap.TryGetValue(button.AsHidType<Key>(), out keyString))
|
||||||
|
{
|
||||||
|
keyString = key.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case ButtonType.GamepadButtonInputId:
|
||||||
|
var gamepadButton = button.AsHidType<GamepadInputId>();
|
||||||
|
|
||||||
|
if (!_gamepadInputIdMap.TryGetValue(button.AsHidType<GamepadInputId>(), out keyString))
|
||||||
|
{
|
||||||
|
keyString = gamepadButton.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case ButtonType.StickId:
|
||||||
|
var stickInput = button.AsHidType<StickInputId>();
|
||||||
|
|
||||||
|
if (!_stickInputIdMap.TryGetValue(button.AsHidType<StickInputId>(), out keyString))
|
||||||
|
{
|
||||||
|
keyString = stickInput.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return keyString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ using Ryujinx.Input;
|
||||||
using Ryujinx.Input.Assigner;
|
using Ryujinx.Input.Assigner;
|
||||||
using Ryujinx.Input.GTK3;
|
using Ryujinx.Input.GTK3;
|
||||||
using Ryujinx.UI.Common.Configuration;
|
using Ryujinx.UI.Common.Configuration;
|
||||||
|
using Ryujinx.UI.Helper;
|
||||||
using Ryujinx.UI.Widgets;
|
using Ryujinx.UI.Widgets;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -17,6 +18,7 @@ using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using Button = Ryujinx.Input.Button;
|
||||||
using ConfigGamepadInputId = Ryujinx.Common.Configuration.Hid.Controller.GamepadInputId;
|
using ConfigGamepadInputId = Ryujinx.Common.Configuration.Hid.Controller.GamepadInputId;
|
||||||
using ConfigStickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
|
using ConfigStickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
|
||||||
using GUI = Gtk.Builder.ObjectAttribute;
|
using GUI = Gtk.Builder.ObjectAttribute;
|
||||||
|
@ -887,13 +889,13 @@ namespace Ryujinx.UI.Windows
|
||||||
Thread.Sleep(10);
|
Thread.Sleep(10);
|
||||||
assigner.ReadInput();
|
assigner.ReadInput();
|
||||||
|
|
||||||
if (_mousePressed || keyboard.IsPressed(Ryujinx.Input.Key.Escape) || assigner.HasAnyButtonPressed() || assigner.ShouldCancel())
|
if (_mousePressed || keyboard.IsPressed(Ryujinx.Input.Key.Escape) || assigner.IsAnyButtonPressed() || assigner.ShouldCancel())
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string pressedButton = assigner.GetPressedButton();
|
string pressedButton = ButtonHelper.ToString(assigner.GetPressedButton() ?? new Button(Input.Key.Unknown));
|
||||||
|
|
||||||
Application.Invoke(delegate
|
Application.Invoke(delegate
|
||||||
{
|
{
|
||||||
|
|
|
@ -49,9 +49,9 @@ namespace Ryujinx.Input.Assigner
|
||||||
CollectButtonStats();
|
CollectButtonStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasAnyButtonPressed()
|
public bool IsAnyButtonPressed()
|
||||||
{
|
{
|
||||||
return _detector.HasAnyButtonPressed();
|
return _detector.IsAnyButtonPressed();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ShouldCancel()
|
public bool ShouldCancel()
|
||||||
|
@ -59,16 +59,11 @@ namespace Ryujinx.Input.Assigner
|
||||||
return _gamepad == null || !_gamepad.IsConnected;
|
return _gamepad == null || !_gamepad.IsConnected;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetPressedButton()
|
public Button? GetPressedButton()
|
||||||
{
|
{
|
||||||
IEnumerable<GamepadButtonInputId> pressedButtons = _detector.GetPressedButtons();
|
IEnumerable<GamepadButtonInputId> pressedButtons = _detector.GetPressedButtons();
|
||||||
|
|
||||||
if (pressedButtons.Any())
|
return !_forStick ? new(pressedButtons.FirstOrDefault()) : new((StickInputId)pressedButtons.FirstOrDefault());
|
||||||
{
|
|
||||||
return !_forStick ? pressedButtons.First().ToString() : ((StickInputId)pressedButtons.First()).ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CollectButtonStats()
|
private void CollectButtonStats()
|
||||||
|
@ -123,7 +118,7 @@ namespace Ryujinx.Input.Assigner
|
||||||
_stats = new Dictionary<GamepadButtonInputId, InputSummary>();
|
_stats = new Dictionary<GamepadButtonInputId, InputSummary>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasAnyButtonPressed()
|
public bool IsAnyButtonPressed()
|
||||||
{
|
{
|
||||||
return _stats.Values.Any(CheckButtonPressed);
|
return _stats.Values.Any(CheckButtonPressed);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace Ryujinx.Input.Assigner
|
||||||
/// Check if a button was pressed.
|
/// Check if a button was pressed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>True if a button was pressed</returns>
|
/// <returns>True if a button was pressed</returns>
|
||||||
bool HasAnyButtonPressed();
|
bool IsAnyButtonPressed();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicate if the user of this API should cancel operations. This is triggered for example when a gamepad get disconnected or when a user cancel assignation operations.
|
/// Indicate if the user of this API should cancel operations. This is triggered for example when a gamepad get disconnected or when a user cancel assignation operations.
|
||||||
|
@ -31,6 +31,6 @@ namespace Ryujinx.Input.Assigner
|
||||||
/// Get the pressed button that was read in <see cref="ReadInput"/> by the button assigner.
|
/// Get the pressed button that was read in <see cref="ReadInput"/> by the button assigner.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>The pressed button that was read</returns>
|
/// <returns>The pressed button that was read</returns>
|
||||||
string GetPressedButton();
|
Button? GetPressedButton();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,9 @@ namespace Ryujinx.Input.Assigner
|
||||||
_keyboardState = _keyboard.GetKeyboardStateSnapshot();
|
_keyboardState = _keyboard.GetKeyboardStateSnapshot();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasAnyButtonPressed()
|
public bool IsAnyButtonPressed()
|
||||||
{
|
{
|
||||||
return GetPressedButton().Length != 0;
|
return GetPressedButton() is not null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ShouldCancel()
|
public bool ShouldCancel()
|
||||||
|
@ -31,20 +31,20 @@ namespace Ryujinx.Input.Assigner
|
||||||
return _keyboardState.IsPressed(Key.Escape);
|
return _keyboardState.IsPressed(Key.Escape);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetPressedButton()
|
public Button? GetPressedButton()
|
||||||
{
|
{
|
||||||
string keyPressed = "";
|
Button? keyPressed = null;
|
||||||
|
|
||||||
for (Key key = Key.Unknown; key < Key.Count; key++)
|
for (Key key = Key.Unknown; key < Key.Count; key++)
|
||||||
{
|
{
|
||||||
if (_keyboardState.IsPressed(key))
|
if (_keyboardState.IsPressed(key))
|
||||||
{
|
{
|
||||||
keyPressed = key.ToString();
|
keyPressed = new(key);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return !ShouldCancel() ? keyPressed : "";
|
return !ShouldCancel() ? keyPressed : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
33
src/Ryujinx.Input/Button.cs
Normal file
33
src/Ryujinx.Input/Button.cs
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Ryujinx.Input
|
||||||
|
{
|
||||||
|
public readonly struct Button
|
||||||
|
{
|
||||||
|
public readonly ButtonType Type;
|
||||||
|
private readonly uint _rawValue;
|
||||||
|
|
||||||
|
public Button(Key key)
|
||||||
|
{
|
||||||
|
Type = ButtonType.Key;
|
||||||
|
_rawValue = (uint)key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button(GamepadButtonInputId gamepad)
|
||||||
|
{
|
||||||
|
Type = ButtonType.GamepadButtonInputId;
|
||||||
|
_rawValue = (uint)gamepad;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Button(StickInputId stick)
|
||||||
|
{
|
||||||
|
Type = ButtonType.StickId;
|
||||||
|
_rawValue = (uint)stick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T AsHidType<T>() where T : Enum
|
||||||
|
{
|
||||||
|
return (T)Enum.ToObject(typeof(T), _rawValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
src/Ryujinx.Input/ButtonType.cs
Normal file
9
src/Ryujinx.Input/ButtonType.cs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
namespace Ryujinx.Input
|
||||||
|
{
|
||||||
|
public enum ButtonType
|
||||||
|
{
|
||||||
|
Key,
|
||||||
|
GamepadButtonInputId,
|
||||||
|
StickId,
|
||||||
|
}
|
||||||
|
}
|
|
@ -203,8 +203,6 @@ namespace Ryujinx.Input.HLE
|
||||||
new(Key.NumLock, 10),
|
new(Key.NumLock, 10),
|
||||||
};
|
};
|
||||||
|
|
||||||
private bool _isValid;
|
|
||||||
|
|
||||||
private MotionInput _leftMotionInput;
|
private MotionInput _leftMotionInput;
|
||||||
private MotionInput _rightMotionInput;
|
private MotionInput _rightMotionInput;
|
||||||
|
|
||||||
|
@ -222,7 +220,6 @@ namespace Ryujinx.Input.HLE
|
||||||
{
|
{
|
||||||
State = default;
|
State = default;
|
||||||
Id = null;
|
Id = null;
|
||||||
_isValid = false;
|
|
||||||
_cemuHookClient = cemuHookClient;
|
_cemuHookClient = cemuHookClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,11 +231,10 @@ namespace Ryujinx.Input.HLE
|
||||||
|
|
||||||
Id = config.Id;
|
Id = config.Id;
|
||||||
_gamepad = GamepadDriver.GetGamepad(Id);
|
_gamepad = GamepadDriver.GetGamepad(Id);
|
||||||
_isValid = _gamepad != null;
|
|
||||||
|
|
||||||
UpdateUserConfiguration(config);
|
UpdateUserConfiguration(config);
|
||||||
|
|
||||||
return _isValid;
|
return _gamepad != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateUserConfiguration(InputConfig config)
|
public void UpdateUserConfiguration(InputConfig config)
|
||||||
|
@ -262,10 +258,7 @@ namespace Ryujinx.Input.HLE
|
||||||
|
|
||||||
_config = config;
|
_config = config;
|
||||||
|
|
||||||
if (_isValid)
|
_gamepad?.SetConfiguration(config);
|
||||||
{
|
|
||||||
_gamepad.SetConfiguration(config);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateMotionInput(MotionConfigController motionConfig)
|
private void UpdateMotionInput(MotionConfigController motionConfig)
|
||||||
|
@ -282,18 +275,21 @@ namespace Ryujinx.Input.HLE
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
if (_isValid && GamepadDriver != null)
|
// _gamepad may be altered by other threads
|
||||||
|
var gamepad = _gamepad;
|
||||||
|
|
||||||
|
if (gamepad != null && GamepadDriver != null)
|
||||||
{
|
{
|
||||||
State = _gamepad.GetMappedStateSnapshot();
|
State = gamepad.GetMappedStateSnapshot();
|
||||||
|
|
||||||
if (_config is StandardControllerInputConfig controllerConfig && controllerConfig.Motion.EnableMotion)
|
if (_config is StandardControllerInputConfig controllerConfig && controllerConfig.Motion.EnableMotion)
|
||||||
{
|
{
|
||||||
if (controllerConfig.Motion.MotionBackend == MotionInputBackendType.GamepadDriver)
|
if (controllerConfig.Motion.MotionBackend == MotionInputBackendType.GamepadDriver)
|
||||||
{
|
{
|
||||||
if (_gamepad.Features.HasFlag(GamepadFeaturesFlag.Motion))
|
if (gamepad.Features.HasFlag(GamepadFeaturesFlag.Motion))
|
||||||
{
|
{
|
||||||
Vector3 accelerometer = _gamepad.GetMotionData(MotionInputId.Accelerometer);
|
Vector3 accelerometer = gamepad.GetMotionData(MotionInputId.Accelerometer);
|
||||||
Vector3 gyroscope = _gamepad.GetMotionData(MotionInputId.Gyroscope);
|
Vector3 gyroscope = gamepad.GetMotionData(MotionInputId.Gyroscope);
|
||||||
|
|
||||||
accelerometer = new Vector3(accelerometer.X, -accelerometer.Z, accelerometer.Y);
|
accelerometer = new Vector3(accelerometer.X, -accelerometer.Z, accelerometer.Y);
|
||||||
gyroscope = new Vector3(gyroscope.X, -gyroscope.Z, gyroscope.Y);
|
gyroscope = new Vector3(gyroscope.X, -gyroscope.Z, gyroscope.Y);
|
||||||
|
|
|
@ -266,6 +266,107 @@
|
||||||
"ControllerSettingsMotionGyroDeadzone": "Gyro Deadzone:",
|
"ControllerSettingsMotionGyroDeadzone": "Gyro Deadzone:",
|
||||||
"ControllerSettingsSave": "Save",
|
"ControllerSettingsSave": "Save",
|
||||||
"ControllerSettingsClose": "Close",
|
"ControllerSettingsClose": "Close",
|
||||||
|
"KeyUnknown": "Unknown",
|
||||||
|
"KeyShiftLeft": "Shift Left",
|
||||||
|
"KeyShiftRight": "Shift Right",
|
||||||
|
"KeyControlLeft": "Ctrl Left",
|
||||||
|
"KeyMacControlLeft": "⌃ Left",
|
||||||
|
"KeyControlRight": "Ctrl Right",
|
||||||
|
"KeyMacControlRight": "⌃ Right",
|
||||||
|
"KeyAltLeft": "Alt Left",
|
||||||
|
"KeyMacAltLeft": "⌥ Left",
|
||||||
|
"KeyAltRight": "Alt Right",
|
||||||
|
"KeyMacAltRight": "⌥ Right",
|
||||||
|
"KeyWinLeft": "⊞ Left",
|
||||||
|
"KeyMacWinLeft": "⌘ Left",
|
||||||
|
"KeyWinRight": "⊞ Right",
|
||||||
|
"KeyMacWinRight": "⌘ 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": "L Stick Button",
|
||||||
|
"GamepadRightStick": "R 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:",
|
"UserProfilesSelectedUserProfile": "Selected User Profile:",
|
||||||
"UserProfilesSaveProfileName": "Save Profile Name",
|
"UserProfilesSaveProfileName": "Save Profile Name",
|
||||||
"UserProfilesChangeProfileImage": "Change Profile Image",
|
"UserProfilesChangeProfileImage": "Change Profile Image",
|
||||||
|
|
|
@ -15,8 +15,7 @@
|
||||||
<MenuItem Header="Test 2" />
|
<MenuItem Header="Test 2" />
|
||||||
<MenuItem Header="Test 3">
|
<MenuItem Header="Test 3">
|
||||||
<MenuItem.Icon>
|
<MenuItem.Icon>
|
||||||
<CheckBox Margin="0"
|
<CheckBox Margin="0" />
|
||||||
IsChecked="{ReflectionBinding Checkbox, Mode=TwoWay}" />
|
|
||||||
</MenuItem.Icon>
|
</MenuItem.Icon>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
using Avalonia.Controls;
|
|
||||||
using Avalonia.Controls.Primitives;
|
using Avalonia.Controls.Primitives;
|
||||||
using Avalonia.LogicalTree;
|
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using Ryujinx.Input;
|
using Ryujinx.Input;
|
||||||
using Ryujinx.Input.Assigner;
|
using Ryujinx.Input.Assigner;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Helpers
|
namespace Ryujinx.Ava.UI.Helpers
|
||||||
|
@ -15,12 +12,12 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||||
internal class ButtonAssignedEventArgs : EventArgs
|
internal class ButtonAssignedEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public ToggleButton Button { get; }
|
public ToggleButton Button { get; }
|
||||||
public bool IsAssigned { get; }
|
public Button? ButtonValue { get; }
|
||||||
|
|
||||||
public ButtonAssignedEventArgs(ToggleButton button, bool isAssigned)
|
public ButtonAssignedEventArgs(ToggleButton button, Button? buttonValue)
|
||||||
{
|
{
|
||||||
Button = button;
|
Button = button;
|
||||||
IsAssigned = isAssigned;
|
ButtonValue = buttonValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +66,7 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||||
|
|
||||||
assigner.ReadInput();
|
assigner.ReadInput();
|
||||||
|
|
||||||
if (assigner.HasAnyButtonPressed() || assigner.ShouldCancel() || (keyboard != null && keyboard.IsPressed(Key.Escape)))
|
if (assigner.IsAnyButtonPressed() || assigner.ShouldCancel() || (keyboard != null && keyboard.IsPressed(Key.Escape)))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -78,15 +75,11 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||||
|
|
||||||
await Dispatcher.UIThread.InvokeAsync(() =>
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
string pressedButton = assigner.GetPressedButton();
|
Button? pressedButton = assigner.GetPressedButton();
|
||||||
|
|
||||||
if (_shouldUnbind)
|
if (_shouldUnbind)
|
||||||
{
|
{
|
||||||
SetButtonText(ToggledButton, "Unbound");
|
pressedButton = null;
|
||||||
}
|
|
||||||
else if (pressedButton != "")
|
|
||||||
{
|
|
||||||
SetButtonText(ToggledButton, pressedButton);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_shouldUnbind = false;
|
_shouldUnbind = false;
|
||||||
|
@ -94,17 +87,8 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||||
|
|
||||||
ToggledButton.IsChecked = false;
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
using Avalonia.Data.Converters;
|
using Avalonia.Data.Converters;
|
||||||
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Common.Configuration.Hid;
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
using Ryujinx.Common.Configuration.Hid.Controller;
|
using Ryujinx.Common.Configuration.Hid.Controller;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Helpers
|
namespace Ryujinx.Ava.UI.Helpers
|
||||||
|
@ -10,37 +12,173 @@ namespace Ryujinx.Ava.UI.Helpers
|
||||||
{
|
{
|
||||||
public static KeyValueConverter Instance = new();
|
public static KeyValueConverter Instance = new();
|
||||||
|
|
||||||
|
private static readonly Dictionary<Key, LocaleKeys> _keysMap = new()
|
||||||
|
{
|
||||||
|
{ Key.Unknown, LocaleKeys.KeyUnknown },
|
||||||
|
{ Key.ShiftLeft, LocaleKeys.KeyShiftLeft },
|
||||||
|
{ Key.ShiftRight, LocaleKeys.KeyShiftRight },
|
||||||
|
{ Key.ControlLeft, LocaleKeys.KeyControlLeft },
|
||||||
|
{ Key.ControlRight, LocaleKeys.KeyControlRight },
|
||||||
|
{ Key.AltLeft, LocaleKeys.KeyControlLeft },
|
||||||
|
{ Key.AltRight, LocaleKeys.KeyControlRight },
|
||||||
|
{ Key.WinLeft, LocaleKeys.KeyWinLeft },
|
||||||
|
{ Key.WinRight, 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<GamepadInputId, LocaleKeys> _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<StickInputId, LocaleKeys> _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)
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
if (value == null)
|
string keyString = "";
|
||||||
|
LocaleKeys localeKey;
|
||||||
|
|
||||||
|
switch (value)
|
||||||
{
|
{
|
||||||
return null;
|
case Key key:
|
||||||
|
if (_keysMap.TryGetValue(key, out localeKey))
|
||||||
|
{
|
||||||
|
if (OperatingSystem.IsMacOS())
|
||||||
|
{
|
||||||
|
localeKey = localeKey switch
|
||||||
|
{
|
||||||
|
LocaleKeys.KeyControlLeft => LocaleKeys.KeyMacControlLeft,
|
||||||
|
LocaleKeys.KeyControlRight => LocaleKeys.KeyMacControlRight,
|
||||||
|
LocaleKeys.KeyAltLeft => LocaleKeys.KeyMacAltLeft,
|
||||||
|
LocaleKeys.KeyAltRight => LocaleKeys.KeyMacAltRight,
|
||||||
|
LocaleKeys.KeyWinLeft => LocaleKeys.KeyMacWinLeft,
|
||||||
|
LocaleKeys.KeyWinRight => LocaleKeys.KeyMacWinRight,
|
||||||
|
_ => localeKey
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
keyString = LocaleManager.Instance[localeKey];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
keyString = key.ToString();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GamepadInputId gamepadInputId:
|
||||||
|
if (_gamepadInputIdMap.TryGetValue(gamepadInputId, out localeKey))
|
||||||
|
{
|
||||||
|
keyString = LocaleManager.Instance[localeKey];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
keyString = gamepadInputId.ToString();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case StickInputId stickInputId:
|
||||||
|
if (_stickInputIdMap.TryGetValue(stickInputId, out localeKey))
|
||||||
|
{
|
||||||
|
keyString = LocaleManager.Instance[localeKey];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
keyString = stickInputId.ToString();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return value.ToString();
|
return keyString;
|
||||||
}
|
}
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
object key = null;
|
throw new NotSupportedException();
|
||||||
|
|
||||||
if (value != null)
|
|
||||||
{
|
|
||||||
if (targetType == typeof(Key))
|
|
||||||
{
|
|
||||||
key = Enum.Parse<Key>(value.ToString());
|
|
||||||
}
|
|
||||||
else if (targetType == typeof(GamepadInputId))
|
|
||||||
{
|
|
||||||
key = Enum.Parse<GamepadInputId>(value.ToString());
|
|
||||||
}
|
|
||||||
else if (targetType == typeof(StickInputId))
|
|
||||||
{
|
|
||||||
key = Enum.Parse<StickInputId>(value.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return key;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
580
src/Ryujinx/UI/Models/Input/GamepadInputConfig.cs
Normal file
580
src/Ryujinx/UI/Models/Input/GamepadInputConfig.cs
Normal file
|
@ -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 GamepadInputConfig : 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 GamepadInputConfig(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<GamepadInputId>
|
||||||
|
{
|
||||||
|
DpadUp = DpadUp,
|
||||||
|
DpadDown = DpadDown,
|
||||||
|
DpadLeft = DpadLeft,
|
||||||
|
DpadRight = DpadRight,
|
||||||
|
ButtonL = ButtonL,
|
||||||
|
ButtonMinus = ButtonMinus,
|
||||||
|
ButtonSl = LeftButtonSl,
|
||||||
|
ButtonSr = LeftButtonSr,
|
||||||
|
ButtonZl = ButtonZl,
|
||||||
|
},
|
||||||
|
RightJoycon = new RightJoyconCommonConfig<GamepadInputId>
|
||||||
|
{
|
||||||
|
ButtonA = ButtonA,
|
||||||
|
ButtonB = ButtonB,
|
||||||
|
ButtonX = ButtonX,
|
||||||
|
ButtonY = ButtonY,
|
||||||
|
ButtonPlus = ButtonPlus,
|
||||||
|
ButtonSl = RightButtonSl,
|
||||||
|
ButtonSr = RightButtonSr,
|
||||||
|
ButtonR = ButtonR,
|
||||||
|
ButtonZr = ButtonZr,
|
||||||
|
},
|
||||||
|
LeftJoyconStick = new JoyconConfigControllerStick<GamepadInputId, StickInputId>
|
||||||
|
{
|
||||||
|
Joystick = LeftJoystick,
|
||||||
|
InvertStickX = LeftInvertStickX,
|
||||||
|
InvertStickY = LeftInvertStickY,
|
||||||
|
Rotate90CW = LeftRotate90,
|
||||||
|
StickButton = LeftStickButton,
|
||||||
|
},
|
||||||
|
RightJoyconStick = new JoyconConfigControllerStick<GamepadInputId, StickInputId>
|
||||||
|
{
|
||||||
|
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 StandardMotionConfigController
|
||||||
|
{
|
||||||
|
EnableMotion = EnableMotion,
|
||||||
|
MotionBackend = MotionInputBackendType.GamepadDriver,
|
||||||
|
GyroDeadzone = GyroDeadzone,
|
||||||
|
Sensitivity = Sensitivity,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
141
src/Ryujinx/UI/Models/Input/HotkeyConfig.cs
Normal file
141
src/Ryujinx/UI/Models/Input/HotkeyConfig.cs
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
|
|
||||||
|
namespace Ryujinx.Ava.UI.Models.Input
|
||||||
|
{
|
||||||
|
public class HotkeyConfig : BaseModel
|
||||||
|
{
|
||||||
|
private Key _toggleVsync;
|
||||||
|
public Key ToggleVsync
|
||||||
|
{
|
||||||
|
get => _toggleVsync;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_toggleVsync = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Key _screenshot;
|
||||||
|
public Key Screenshot
|
||||||
|
{
|
||||||
|
get => _screenshot;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_screenshot = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Key _showUI;
|
||||||
|
public Key ShowUI
|
||||||
|
{
|
||||||
|
get => _showUI;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_showUI = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Key _pause;
|
||||||
|
public Key Pause
|
||||||
|
{
|
||||||
|
get => _pause;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_pause = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Key _toggleMute;
|
||||||
|
public Key ToggleMute
|
||||||
|
{
|
||||||
|
get => _toggleMute;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_toggleMute = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Key _resScaleUp;
|
||||||
|
public Key ResScaleUp
|
||||||
|
{
|
||||||
|
get => _resScaleUp;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_resScaleUp = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Key _resScaleDown;
|
||||||
|
public Key ResScaleDown
|
||||||
|
{
|
||||||
|
get => _resScaleDown;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_resScaleDown = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Key _volumeUp;
|
||||||
|
public Key VolumeUp
|
||||||
|
{
|
||||||
|
get => _volumeUp;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_volumeUp = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Key _volumeDown;
|
||||||
|
public Key VolumeDown
|
||||||
|
{
|
||||||
|
get => _volumeDown;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_volumeDown = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public HotkeyConfig(KeyboardHotkeys config)
|
||||||
|
{
|
||||||
|
if (config != null)
|
||||||
|
{
|
||||||
|
ToggleVsync = config.ToggleVsync;
|
||||||
|
Screenshot = config.Screenshot;
|
||||||
|
ShowUI = config.ShowUI;
|
||||||
|
Pause = config.Pause;
|
||||||
|
ToggleMute = config.ToggleMute;
|
||||||
|
ResScaleUp = config.ResScaleUp;
|
||||||
|
ResScaleDown = config.ResScaleDown;
|
||||||
|
VolumeUp = config.VolumeUp;
|
||||||
|
VolumeDown = config.VolumeDown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyboardHotkeys GetConfig()
|
||||||
|
{
|
||||||
|
var config = new KeyboardHotkeys
|
||||||
|
{
|
||||||
|
ToggleVsync = ToggleVsync,
|
||||||
|
Screenshot = Screenshot,
|
||||||
|
ShowUI = ShowUI,
|
||||||
|
Pause = Pause,
|
||||||
|
ToggleMute = ToggleMute,
|
||||||
|
ResScaleUp = ResScaleUp,
|
||||||
|
ResScaleDown = ResScaleDown,
|
||||||
|
VolumeUp = VolumeUp,
|
||||||
|
VolumeDown = VolumeDown,
|
||||||
|
};
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
422
src/Ryujinx/UI/Models/Input/KeyboardInputConfig.cs
Normal file
422
src/Ryujinx/UI/Models/Input/KeyboardInputConfig.cs
Normal file
|
@ -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<Key>
|
||||||
|
{
|
||||||
|
DpadUp = DpadUp,
|
||||||
|
DpadDown = DpadDown,
|
||||||
|
DpadLeft = DpadLeft,
|
||||||
|
DpadRight = DpadRight,
|
||||||
|
ButtonL = ButtonL,
|
||||||
|
ButtonMinus = ButtonMinus,
|
||||||
|
ButtonZl = ButtonZl,
|
||||||
|
ButtonSl = LeftButtonSl,
|
||||||
|
ButtonSr = LeftButtonSr,
|
||||||
|
},
|
||||||
|
RightJoycon = new RightJoyconCommonConfig<Key>
|
||||||
|
{
|
||||||
|
ButtonA = ButtonA,
|
||||||
|
ButtonB = ButtonB,
|
||||||
|
ButtonX = ButtonX,
|
||||||
|
ButtonY = ButtonY,
|
||||||
|
ButtonPlus = ButtonPlus,
|
||||||
|
ButtonSl = RightButtonSl,
|
||||||
|
ButtonSr = RightButtonSr,
|
||||||
|
ButtonR = ButtonR,
|
||||||
|
ButtonZr = ButtonZr,
|
||||||
|
},
|
||||||
|
LeftJoyconStick = new JoyconConfigKeyboardStick<Key>
|
||||||
|
{
|
||||||
|
StickUp = LeftStickUp,
|
||||||
|
StickDown = LeftStickDown,
|
||||||
|
StickRight = LeftStickRight,
|
||||||
|
StickLeft = LeftStickLeft,
|
||||||
|
StickButton = LeftStickButton,
|
||||||
|
},
|
||||||
|
RightJoyconStick = new JoyconConfigKeyboardStick<Key>
|
||||||
|
{
|
||||||
|
StickUp = RightStickUp,
|
||||||
|
StickDown = RightStickDown,
|
||||||
|
StickLeft = RightStickLeft,
|
||||||
|
StickRight = RightStickRight,
|
||||||
|
StickButton = RightStickButton,
|
||||||
|
},
|
||||||
|
Version = InputConfig.CurrentVersion,
|
||||||
|
};
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<TKey, TStick> : 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; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Controller id
|
|
||||||
/// </summary>
|
|
||||||
public string Id { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Controller's Type
|
|
||||||
/// </summary>
|
|
||||||
public ControllerType ControllerType { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Player's Index for the controller
|
|
||||||
/// </summary>
|
|
||||||
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<Key>
|
|
||||||
{
|
|
||||||
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<Key>
|
|
||||||
{
|
|
||||||
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<Key>
|
|
||||||
{
|
|
||||||
StickUp = (Key)(object)LeftStickUp,
|
|
||||||
StickDown = (Key)(object)LeftStickDown,
|
|
||||||
StickRight = (Key)(object)LeftStickRight,
|
|
||||||
StickLeft = (Key)(object)LeftStickLeft,
|
|
||||||
StickButton = (Key)(object)LeftKeyboardStickButton,
|
|
||||||
},
|
|
||||||
RightJoyconStick = new JoyconConfigKeyboardStick<Key>
|
|
||||||
{
|
|
||||||
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<GamepadInputId>
|
|
||||||
{
|
|
||||||
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<GamepadInputId>
|
|
||||||
{
|
|
||||||
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<GamepadInputId, StickInputId>
|
|
||||||
{
|
|
||||||
Joystick = (StickInputId)(object)LeftJoystick,
|
|
||||||
InvertStickX = LeftInvertStickX,
|
|
||||||
InvertStickY = LeftInvertStickY,
|
|
||||||
Rotate90CW = LeftRotate90,
|
|
||||||
StickButton = (GamepadInputId)(object)LeftControllerStickButton,
|
|
||||||
},
|
|
||||||
RightJoyconStick = new JoyconConfigControllerStick<GamepadInputId, StickInputId>
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
84
src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs
Normal file
84
src/Ryujinx/UI/ViewModels/Input/ControllerInputViewModel.cs
Normal file
|
@ -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 GamepadInputConfig _config;
|
||||||
|
public GamepadInputConfig 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 readonly InputViewModel ParentModel;
|
||||||
|
|
||||||
|
public ControllerInputViewModel(InputViewModel model, GamepadInputConfig 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.Input;
|
using Ryujinx.Ava.Input;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.Models;
|
using Ryujinx.Ava.UI.Models;
|
||||||
using Ryujinx.Ava.UI.Views.Input;
|
using Ryujinx.Ava.UI.Models.Input;
|
||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration;
|
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 ConfigStickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
|
||||||
using Key = Ryujinx.Common.Configuration.Hid.Key;
|
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 Disabled = "disabled";
|
||||||
private const string ProControllerResource = "Ryujinx.UI.Common/Resources/Controller_ProCon.svg";
|
private const string ProControllerResource = "Ryujinx.UI.Common/Resources/Controller_ProCon.svg";
|
||||||
|
@ -48,7 +48,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
private int _controllerNumber;
|
private int _controllerNumber;
|
||||||
private string _controllerImage;
|
private string _controllerImage;
|
||||||
private int _device;
|
private int _device;
|
||||||
private object _configuration;
|
private object _configViewModel;
|
||||||
private string _profileName;
|
private string _profileName;
|
||||||
private bool _isLoaded;
|
private bool _isLoaded;
|
||||||
|
|
||||||
|
@ -71,13 +71,14 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
public bool IsLeft { get; set; }
|
public bool IsLeft { get; set; }
|
||||||
|
|
||||||
public bool IsModified { get; set; }
|
public bool IsModified { get; set; }
|
||||||
|
public event Action NotifyChangesEvent;
|
||||||
|
|
||||||
public object Configuration
|
public object ConfigViewModel
|
||||||
{
|
{
|
||||||
get => _configuration;
|
get => _configViewModel;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_configuration = value;
|
_configViewModel = value;
|
||||||
|
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
|
@ -232,7 +233,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
|
|
||||||
public InputConfig Config { get; set; }
|
public InputConfig Config { get; set; }
|
||||||
|
|
||||||
public ControllerInputViewModel(UserControl owner) : this()
|
public InputViewModel(UserControl owner) : this()
|
||||||
{
|
{
|
||||||
if (Program.PreviewerDetached)
|
if (Program.PreviewerDetached)
|
||||||
{
|
{
|
||||||
|
@ -255,7 +256,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ControllerInputViewModel()
|
public InputViewModel()
|
||||||
{
|
{
|
||||||
PlayerIndexes = new ObservableCollection<PlayerModel>();
|
PlayerIndexes = new ObservableCollection<PlayerModel>();
|
||||||
Controllers = new ObservableCollection<ControllerModel>();
|
Controllers = new ObservableCollection<ControllerModel>();
|
||||||
|
@ -282,12 +283,12 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
|
|
||||||
if (Config is StandardKeyboardInputConfig keyboardInputConfig)
|
if (Config is StandardKeyboardInputConfig keyboardInputConfig)
|
||||||
{
|
{
|
||||||
Configuration = new InputConfiguration<Key, ConfigStickInputId>(keyboardInputConfig);
|
ConfigViewModel = new KeyboardInputViewModel(this, new KeyboardInputConfig(keyboardInputConfig));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config is StandardControllerInputConfig controllerInputConfig)
|
if (Config is StandardControllerInputConfig controllerInputConfig)
|
||||||
{
|
{
|
||||||
Configuration = new InputConfiguration<ConfigGamepadInputId, ConfigStickInputId>(controllerInputConfig);
|
ConfigViewModel = new ControllerInputViewModel(this, new GamepadInputConfig(controllerInputConfig));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,16 +324,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()
|
private void LoadInputDriver()
|
||||||
{
|
{
|
||||||
if (_device < 0)
|
if (_device < 0)
|
||||||
|
@ -740,7 +731,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Configuration == null)
|
if (ConfigViewModel == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -751,35 +742,37 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
|
|
||||||
return;
|
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<Key, ConfigStickInputId>).GetConfig();
|
|
||||||
}
|
|
||||||
else if (IsController)
|
|
||||||
{
|
|
||||||
config = (Configuration as InputConfiguration<GamepadInputId, ConfigStickInputId>).GetConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
config.ControllerType = Controllers[_controller].Type;
|
|
||||||
|
|
||||||
string jsonString = JsonHelper.Serialize(config, _serializerContext.InputConfig);
|
|
||||||
|
|
||||||
await File.WriteAllTextAsync(path, jsonString);
|
|
||||||
|
|
||||||
LoadProfiles();
|
|
||||||
}
|
|
||||||
else
|
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 +823,18 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
|
|
||||||
if (device.Type == DeviceType.Keyboard)
|
if (device.Type == DeviceType.Keyboard)
|
||||||
{
|
{
|
||||||
var inputConfig = Configuration as InputConfiguration<Key, ConfigStickInputId>;
|
var inputConfig = (ConfigViewModel as KeyboardInputViewModel).Config;
|
||||||
inputConfig.Id = device.Id;
|
inputConfig.Id = device.Id;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var inputConfig = Configuration as InputConfiguration<GamepadInputId, ConfigStickInputId>;
|
var inputConfig = (ConfigViewModel as ControllerInputViewModel).Config;
|
||||||
inputConfig.Id = device.Id.Split(" ")[0];
|
inputConfig.Id = device.Id.Split(" ")[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
var config = !IsController
|
var config = !IsController
|
||||||
? (Configuration as InputConfiguration<Key, ConfigStickInputId>).GetConfig()
|
? (ConfigViewModel as KeyboardInputViewModel).Config.GetConfig()
|
||||||
: (Configuration as InputConfiguration<GamepadInputId, ConfigStickInputId>).GetConfig();
|
: (ConfigViewModel as ControllerInputViewModel).Config.GetConfig();
|
||||||
config.ControllerType = Controllers[_controller].Type;
|
config.ControllerType = Controllers[_controller].Type;
|
||||||
config.PlayerIndex = _playerId;
|
config.PlayerIndex = _playerId;
|
||||||
|
|
||||||
|
@ -872,12 +865,13 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
|
|
||||||
public void NotifyChanges()
|
public void NotifyChanges()
|
||||||
{
|
{
|
||||||
OnPropertyChanged(nameof(Configuration));
|
OnPropertyChanged(nameof(ConfigViewModel));
|
||||||
OnPropertyChanged(nameof(IsController));
|
OnPropertyChanged(nameof(IsController));
|
||||||
OnPropertyChanged(nameof(ShowSettings));
|
OnPropertyChanged(nameof(ShowSettings));
|
||||||
OnPropertyChanged(nameof(IsKeyboard));
|
OnPropertyChanged(nameof(IsKeyboard));
|
||||||
OnPropertyChanged(nameof(IsRight));
|
OnPropertyChanged(nameof(IsRight));
|
||||||
OnPropertyChanged(nameof(IsLeft));
|
OnPropertyChanged(nameof(IsLeft));
|
||||||
|
NotifyChangesEvent?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
73
src/Ryujinx/UI/ViewModels/Input/KeyboardInputViewModel.cs
Normal file
73
src/Ryujinx/UI/ViewModels/Input/KeyboardInputViewModel.cs
Normal file
|
@ -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 readonly 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Ryujinx.Ava.UI.ViewModels
|
namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
{
|
{
|
||||||
public class MotionInputViewModel : BaseModel
|
public class MotionInputViewModel : BaseModel
|
||||||
{
|
{
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Ryujinx.Ava.UI.ViewModels
|
namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
{
|
{
|
||||||
public class RumbleInputViewModel : BaseModel
|
public class RumbleInputViewModel : BaseModel
|
||||||
{
|
{
|
|
@ -7,9 +7,9 @@ using Ryujinx.Audio.Backends.SDL2;
|
||||||
using Ryujinx.Audio.Backends.SoundIo;
|
using Ryujinx.Audio.Backends.SoundIo;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
|
using Ryujinx.Ava.UI.Models.Input;
|
||||||
using Ryujinx.Ava.UI.Windows;
|
using Ryujinx.Ava.UI.Windows;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Configuration.Hid;
|
|
||||||
using Ryujinx.Common.Configuration.Multiplayer;
|
using Ryujinx.Common.Configuration.Multiplayer;
|
||||||
using Ryujinx.Common.GraphicsDriver;
|
using Ryujinx.Common.GraphicsDriver;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
|
@ -46,7 +46,6 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
private bool _isVulkanAvailable = true;
|
private bool _isVulkanAvailable = true;
|
||||||
private bool _directoryChanged;
|
private bool _directoryChanged;
|
||||||
private readonly List<string> _gpuIds = new();
|
private readonly List<string> _gpuIds = new();
|
||||||
private KeyboardHotkeys _keyboardHotkeys;
|
|
||||||
private int _graphicsBackendIndex;
|
private int _graphicsBackendIndex;
|
||||||
private int _scalingFilter;
|
private int _scalingFilter;
|
||||||
private int _scalingFilterLevel;
|
private int _scalingFilterLevel;
|
||||||
|
@ -237,16 +236,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
get => new(_networkInterfaces.Keys);
|
get => new(_networkInterfaces.Keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyboardHotkeys KeyboardHotkeys
|
public HotkeyConfig KeyboardHotkey { get; set; }
|
||||||
{
|
|
||||||
get => _keyboardHotkeys;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_keyboardHotkeys = value;
|
|
||||||
|
|
||||||
OnPropertyChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int NetworkInterfaceIndex
|
public int NetworkInterfaceIndex
|
||||||
{
|
{
|
||||||
|
@ -413,7 +403,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
EnableMouse = config.Hid.EnableMouse;
|
EnableMouse = config.Hid.EnableMouse;
|
||||||
|
|
||||||
// Keyboard Hotkeys
|
// Keyboard Hotkeys
|
||||||
KeyboardHotkeys = config.Hid.Hotkeys.Value;
|
KeyboardHotkey = new HotkeyConfig(config.Hid.Hotkeys.Value);
|
||||||
|
|
||||||
// System
|
// System
|
||||||
Region = (int)config.System.Region.Value;
|
Region = (int)config.System.Region.Value;
|
||||||
|
@ -500,7 +490,7 @@ namespace Ryujinx.Ava.UI.ViewModels
|
||||||
config.Hid.EnableMouse.Value = EnableMouse;
|
config.Hid.EnableMouse.Value = EnableMouse;
|
||||||
|
|
||||||
// Keyboard Hotkeys
|
// Keyboard Hotkeys
|
||||||
config.Hid.Hotkeys.Value = KeyboardHotkeys;
|
config.Hid.Hotkeys.Value = KeyboardHotkey.GetConfig();
|
||||||
|
|
||||||
// System
|
// System
|
||||||
config.System.Region.Value = (Region)Region;
|
config.System.Region.Value = (Region)Region;
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
<UserControl
|
<UserControl
|
||||||
xmlns="https://github.com/avaloniaui"
|
xmlns="https://github.com/avaloniaui"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
|
||||||
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
|
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
|
||||||
xmlns:models="clr-namespace:Ryujinx.Ava.UI.Models"
|
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels.Input"
|
||||||
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
|
|
||||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
|
@ -15,6 +13,7 @@
|
||||||
d:DesignWidth="800"
|
d:DesignWidth="800"
|
||||||
x:Class="Ryujinx.Ava.UI.Views.Input.ControllerInputView"
|
x:Class="Ryujinx.Ava.UI.Views.Input.ControllerInputView"
|
||||||
x:DataType="viewModels:ControllerInputViewModel"
|
x:DataType="viewModels:ControllerInputViewModel"
|
||||||
|
x:CompileBindings="True"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Focusable="True">
|
Focusable="True">
|
||||||
<Design.DataContext>
|
<Design.DataContext>
|
||||||
|
@ -34,192 +33,10 @@
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
Orientation="Vertical">
|
Orientation="Vertical">
|
||||||
<StackPanel
|
|
||||||
Margin="0 0 0 5"
|
|
||||||
Orientation="Vertical"
|
|
||||||
Spacing="5">
|
|
||||||
<Grid>
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="*" />
|
|
||||||
<ColumnDefinition Width="10" />
|
|
||||||
<ColumnDefinition Width="*" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<!-- Player Selection -->
|
|
||||||
<Grid
|
|
||||||
Grid.Column="0"
|
|
||||||
Margin="2"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Center">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
<ColumnDefinition Width="*" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<TextBlock
|
|
||||||
Margin="5,0,10,0"
|
|
||||||
Width="90"
|
|
||||||
HorizontalAlignment="Left"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{locale:Locale ControllerSettingsPlayer}" />
|
|
||||||
<ComboBox
|
|
||||||
Grid.Column="1"
|
|
||||||
Name="PlayerIndexBox"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
SelectionChanged="PlayerIndexBox_OnSelectionChanged"
|
|
||||||
ItemsSource="{Binding PlayerIndexes}"
|
|
||||||
SelectedIndex="{Binding PlayerId}">
|
|
||||||
<ComboBox.ItemTemplate>
|
|
||||||
<DataTemplate>
|
|
||||||
<TextBlock Text="{Binding Name}" />
|
|
||||||
</DataTemplate>
|
|
||||||
</ComboBox.ItemTemplate>
|
|
||||||
</ComboBox>
|
|
||||||
</Grid>
|
|
||||||
<!-- Profile Selection -->
|
|
||||||
<Grid
|
|
||||||
Grid.Column="2"
|
|
||||||
Margin="2"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Center">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
<ColumnDefinition Width="*" />
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<TextBlock
|
|
||||||
Margin="5,0,10,0"
|
|
||||||
Width="90"
|
|
||||||
HorizontalAlignment="Left"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{locale:Locale ControllerSettingsProfile}" />
|
|
||||||
<ui:FAComboBox
|
|
||||||
Grid.Column="1"
|
|
||||||
IsEditable="True"
|
|
||||||
Name="ProfileBox"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
SelectedIndex="0"
|
|
||||||
ItemsSource="{Binding ProfilesList}"
|
|
||||||
Text="{Binding ProfileName, Mode=TwoWay}" />
|
|
||||||
<Button
|
|
||||||
Grid.Column="2"
|
|
||||||
MinWidth="0"
|
|
||||||
Margin="5,0,0,0"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
ToolTip.Tip="{locale:Locale ControllerSettingsLoadProfileToolTip}"
|
|
||||||
Command="{ReflectionBinding LoadProfile}">
|
|
||||||
<ui:SymbolIcon
|
|
||||||
Symbol="Upload"
|
|
||||||
FontSize="15"
|
|
||||||
Height="20" />
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
Grid.Column="3"
|
|
||||||
MinWidth="0"
|
|
||||||
Margin="5,0,0,0"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
ToolTip.Tip="{locale:Locale ControllerSettingsSaveProfileToolTip}"
|
|
||||||
Command="{ReflectionBinding SaveProfile}">
|
|
||||||
<ui:SymbolIcon
|
|
||||||
Symbol="Save"
|
|
||||||
FontSize="15"
|
|
||||||
Height="20" />
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
Grid.Column="4"
|
|
||||||
MinWidth="0"
|
|
||||||
Margin="5,0,0,0"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
ToolTip.Tip="{locale:Locale ControllerSettingsRemoveProfileToolTip}"
|
|
||||||
Command="{ReflectionBinding RemoveProfile}">
|
|
||||||
<ui:SymbolIcon
|
|
||||||
Symbol="Delete"
|
|
||||||
FontSize="15"
|
|
||||||
Height="20" />
|
|
||||||
</Button>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
<Separator />
|
|
||||||
<Grid>
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="*" />
|
|
||||||
<ColumnDefinition Width="10" />
|
|
||||||
<ColumnDefinition Width="*" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<!-- Input Device -->
|
|
||||||
<Grid
|
|
||||||
Grid.Column="0"
|
|
||||||
Margin="2"
|
|
||||||
HorizontalAlignment="Stretch">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
<ColumnDefinition Width="*"/>
|
|
||||||
<ColumnDefinition Width="Auto" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<TextBlock
|
|
||||||
Grid.Column="0"
|
|
||||||
Margin="5,0,10,0"
|
|
||||||
Width="90"
|
|
||||||
HorizontalAlignment="Left"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{locale:Locale ControllerSettingsInputDevice}" />
|
|
||||||
<ComboBox
|
|
||||||
Grid.Column="1"
|
|
||||||
Name="DeviceBox"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
ItemsSource="{Binding DeviceList}"
|
|
||||||
SelectedIndex="{Binding Device}" />
|
|
||||||
<Button
|
|
||||||
Grid.Column="2"
|
|
||||||
MinWidth="0"
|
|
||||||
Margin="5,0,0,0"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Command="{ReflectionBinding LoadDevices}">
|
|
||||||
<ui:SymbolIcon
|
|
||||||
Symbol="Refresh"
|
|
||||||
FontSize="15"
|
|
||||||
Height="20"/>
|
|
||||||
</Button>
|
|
||||||
</Grid>
|
|
||||||
<!-- Controller Type -->
|
|
||||||
<Grid
|
|
||||||
Grid.Column="2"
|
|
||||||
Margin="2"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Center">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
<ColumnDefinition Width="*" />
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<TextBlock
|
|
||||||
Margin="5,0,10,0"
|
|
||||||
Width="90"
|
|
||||||
HorizontalAlignment="Left"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{locale:Locale ControllerSettingsControllerType}" />
|
|
||||||
<ComboBox
|
|
||||||
Grid.Column="1"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
ItemsSource="{Binding Controllers}"
|
|
||||||
SelectedIndex="{Binding Controller}">
|
|
||||||
<ComboBox.ItemTemplate>
|
|
||||||
<DataTemplate DataType="models:ControllerModel">
|
|
||||||
<TextBlock Text="{Binding Name}" />
|
|
||||||
</DataTemplate>
|
|
||||||
</ComboBox.ItemTemplate>
|
|
||||||
</ComboBox>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</StackPanel>
|
|
||||||
<!-- Button / JoyStick Settings -->
|
<!-- Button / JoyStick Settings -->
|
||||||
<Grid
|
<Grid
|
||||||
Name="SettingButtons"
|
Name="SettingButtons"
|
||||||
MinHeight="450"
|
MinHeight="450">
|
||||||
FlowDirection="LeftToRight"
|
|
||||||
IsVisible="{Binding ShowSettings}">
|
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
|
@ -258,9 +75,9 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsTriggerZL}"
|
Text="{locale:Locale ControllerSettingsTriggerZL}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
<ToggleButton>
|
<ToggleButton Name="ButtonZl">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ReflectionBinding Configuration.ButtonZl, Mode=TwoWay, Converter={StaticResource Key}}"
|
Text="{Binding Config.ButtonZl, Converter={StaticResource Key}}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
@ -274,9 +91,9 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsTriggerL}"
|
Text="{locale:Locale ControllerSettingsTriggerL}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
<ToggleButton>
|
<ToggleButton Name="ButtonL">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ReflectionBinding Configuration.ButtonL, Mode=TwoWay, Converter={StaticResource Key}}"
|
Text="{Binding Config.ButtonL, Converter={StaticResource Key}}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
@ -290,9 +107,9 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsButtonMinus}"
|
Text="{locale:Locale ControllerSettingsButtonMinus}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
<ToggleButton>
|
<ToggleButton Name="ButtonMinus">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ReflectionBinding Configuration.ButtonMinus, Mode=TwoWay, Converter={StaticResource Key}}"
|
Text="{Binding Config.ButtonMinus, Converter={StaticResource Key}}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
@ -312,100 +129,8 @@
|
||||||
Margin="0,0,0,10"
|
Margin="0,0,0,10"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsLStick}" />
|
Text="{locale:Locale ControllerSettingsLStick}" />
|
||||||
<!-- Left Joystick Keyboard -->
|
|
||||||
<StackPanel
|
|
||||||
IsVisible="{Binding !IsController}"
|
|
||||||
Orientation="Vertical">
|
|
||||||
<!-- Left Joystick Button -->
|
|
||||||
<StackPanel
|
|
||||||
Margin="0,0,0,4"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
<TextBlock
|
|
||||||
Margin="0,0,10,0"
|
|
||||||
Width="120"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{locale:Locale ControllerSettingsStickButton}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
<ToggleButton>
|
|
||||||
<TextBlock
|
|
||||||
Text="{ReflectionBinding Configuration.LeftKeyboardStickButton, Mode=TwoWay, Converter={StaticResource Key}}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
</ToggleButton>
|
|
||||||
</StackPanel>
|
|
||||||
<!-- Left Joystick Up -->
|
|
||||||
<StackPanel
|
|
||||||
Margin="0,0,0,4"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
<TextBlock
|
|
||||||
Margin="0,0,10,0"
|
|
||||||
Width="120"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{locale:Locale ControllerSettingsStickUp}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
<ToggleButton>
|
|
||||||
<TextBlock
|
|
||||||
Text="{ReflectionBinding Configuration.LeftStickUp, Mode=TwoWay, Converter={StaticResource Key}}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
</ToggleButton>
|
|
||||||
</StackPanel>
|
|
||||||
<!-- Left Joystick Down -->
|
|
||||||
<StackPanel
|
|
||||||
Margin="0,0,0,4"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
<TextBlock
|
|
||||||
Margin="0,0,10,0"
|
|
||||||
Width="120"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{locale:Locale ControllerSettingsStickDown}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
<ToggleButton>
|
|
||||||
<TextBlock
|
|
||||||
Text="{ReflectionBinding Configuration.LeftStickDown, Mode=TwoWay, Converter={StaticResource Key}}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
</ToggleButton>
|
|
||||||
</StackPanel>
|
|
||||||
<!-- Left Joystick Left -->
|
|
||||||
<StackPanel
|
|
||||||
Margin="0,0,0,4"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
<TextBlock
|
|
||||||
Margin="0,0,10,0"
|
|
||||||
Width="120"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{locale:Locale ControllerSettingsStickLeft}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
<ToggleButton>
|
|
||||||
<TextBlock
|
|
||||||
Text="{ReflectionBinding Configuration.LeftStickLeft, Mode=TwoWay, Converter={StaticResource Key}}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
</ToggleButton>
|
|
||||||
</StackPanel>
|
|
||||||
<!-- Left Joystick Right -->
|
|
||||||
<StackPanel
|
|
||||||
Margin="0,0,0,4"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
<TextBlock
|
|
||||||
Margin="0,0,10,0"
|
|
||||||
Width="120"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{locale:Locale ControllerSettingsStickRight}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
<ToggleButton>
|
|
||||||
<TextBlock
|
|
||||||
Text="{ReflectionBinding Configuration.LeftStickRight, Mode=TwoWay, Converter={StaticResource Key}}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
</ToggleButton>
|
|
||||||
</StackPanel>
|
|
||||||
</StackPanel>
|
|
||||||
<!-- Left Joystick Controller -->
|
<!-- Left Joystick Controller -->
|
||||||
<StackPanel
|
<StackPanel Orientation="Vertical">
|
||||||
IsVisible="{Binding IsController}"
|
|
||||||
Orientation="Vertical">
|
|
||||||
<!-- Left Joystick Button -->
|
<!-- Left Joystick Button -->
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Orientation="Horizontal">
|
Orientation="Horizontal">
|
||||||
|
@ -416,9 +141,9 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsStickButton}"
|
Text="{locale:Locale ControllerSettingsStickButton}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
<ToggleButton>
|
<ToggleButton Name="LeftStickButton">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ReflectionBinding Configuration.LeftControllerStickButton, Mode=TwoWay, Converter={StaticResource Key}}"
|
Text="{Binding Config.LeftStickButton, Converter={StaticResource Key}}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
@ -433,22 +158,22 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsStickStick}"
|
Text="{locale:Locale ControllerSettingsStickStick}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
<ToggleButton Tag="stick">
|
<ToggleButton Name="LeftJoystick" Tag="stick">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ReflectionBinding Configuration.LeftJoystick, Mode=TwoWay, Converter={StaticResource Key}}"
|
Text="{Binding Config.LeftJoystick, Converter={StaticResource Key}}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<Separator
|
<Separator
|
||||||
Margin="0,8,0,8"
|
Margin="0,8,0,8"
|
||||||
Height="1" />
|
Height="1" />
|
||||||
<CheckBox IsChecked="{ReflectionBinding Configuration.LeftInvertStickX}">
|
<CheckBox IsChecked="{Binding Config.LeftInvertStickX}">
|
||||||
<TextBlock Text="{locale:Locale ControllerSettingsStickInvertXAxis}" />
|
<TextBlock Text="{locale:Locale ControllerSettingsStickInvertXAxis}" />
|
||||||
</CheckBox>
|
</CheckBox>
|
||||||
<CheckBox IsChecked="{ReflectionBinding Configuration.LeftInvertStickY}">
|
<CheckBox IsChecked="{Binding Config.LeftInvertStickY}">
|
||||||
<TextBlock Text="{locale:Locale ControllerSettingsStickInvertYAxis}" />
|
<TextBlock Text="{locale:Locale ControllerSettingsStickInvertYAxis}" />
|
||||||
</CheckBox>
|
</CheckBox>
|
||||||
<CheckBox IsChecked="{ReflectionBinding Configuration.LeftRotate90}">
|
<CheckBox IsChecked="{Binding Config.LeftRotate90}">
|
||||||
<TextBlock Text="{locale:Locale ControllerSettingsRotate90}" />
|
<TextBlock Text="{locale:Locale ControllerSettingsRotate90}" />
|
||||||
</CheckBox>
|
</CheckBox>
|
||||||
<Separator
|
<Separator
|
||||||
|
@ -469,11 +194,11 @@
|
||||||
IsSnapToTickEnabled="True"
|
IsSnapToTickEnabled="True"
|
||||||
SmallChange="0.01"
|
SmallChange="0.01"
|
||||||
Minimum="0"
|
Minimum="0"
|
||||||
Value="{ReflectionBinding Configuration.DeadzoneLeft, Mode=TwoWay}" />
|
Value="{Binding Config.DeadzoneLeft, Mode=TwoWay}" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Width="25"
|
Width="25"
|
||||||
Text="{ReflectionBinding Configuration.DeadzoneLeft, StringFormat=\{0:0.00\}}" />
|
Text="{Binding Config.DeadzoneLeft, StringFormat=\{0:0.00\}}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<TextBlock
|
<TextBlock
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
|
@ -489,11 +214,11 @@
|
||||||
IsSnapToTickEnabled="True"
|
IsSnapToTickEnabled="True"
|
||||||
SmallChange="0.01"
|
SmallChange="0.01"
|
||||||
Minimum="0"
|
Minimum="0"
|
||||||
Value="{ReflectionBinding Configuration.RangeLeft, Mode=TwoWay}" />
|
Value="{Binding Config.RangeLeft, Mode=TwoWay}" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Width="25"
|
Width="25"
|
||||||
Text="{ReflectionBinding Configuration.RangeLeft, StringFormat=\{0:0.00\}}" />
|
Text="{Binding Config.RangeLeft, StringFormat=\{0:0.00\}}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
@ -526,9 +251,9 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsDPadUp}"
|
Text="{locale:Locale ControllerSettingsDPadUp}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
<ToggleButton>
|
<ToggleButton Name="DpadUp">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ReflectionBinding Configuration.DpadUp, Mode=TwoWay, Converter={StaticResource Key}}"
|
Text="{Binding Config.DpadUp, Converter={StaticResource Key}}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
@ -543,9 +268,9 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsDPadDown}"
|
Text="{locale:Locale ControllerSettingsDPadDown}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
<ToggleButton>
|
<ToggleButton Name="DpadDown">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ReflectionBinding Configuration.DpadDown, Mode=TwoWay, Converter={StaticResource Key}}"
|
Text="{Binding Config.DpadDown, Converter={StaticResource Key}}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
@ -560,9 +285,9 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsDPadLeft}"
|
Text="{locale:Locale ControllerSettingsDPadLeft}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
<ToggleButton>
|
<ToggleButton Name="DpadLeft">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ReflectionBinding Configuration.DpadLeft, Mode=TwoWay, Converter={StaticResource Key}}"
|
Text="{Binding Config.DpadLeft, Converter={StaticResource Key}}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
@ -577,9 +302,9 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsDPadRight}"
|
Text="{locale:Locale ControllerSettingsDPadRight}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
<ToggleButton>
|
<ToggleButton Name="DpadRight">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ReflectionBinding Configuration.DpadRight, Mode=TwoWay, Converter={StaticResource Key}}"
|
Text="{Binding Config.DpadRight, Converter={StaticResource Key}}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
@ -592,6 +317,13 @@
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
VerticalAlignment="Stretch">
|
VerticalAlignment="Stretch">
|
||||||
|
<!-- Controller Picture -->
|
||||||
|
<Image
|
||||||
|
Margin="0,10"
|
||||||
|
MaxHeight="300"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
Source="{Binding Image}" />
|
||||||
<Border
|
<Border
|
||||||
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
|
@ -613,92 +345,89 @@
|
||||||
IsSnapToTickEnabled="True"
|
IsSnapToTickEnabled="True"
|
||||||
SmallChange="0.01"
|
SmallChange="0.01"
|
||||||
Minimum="0"
|
Minimum="0"
|
||||||
Value="{ReflectionBinding Configuration.TriggerThreshold, Mode=TwoWay}" />
|
Value="{Binding Config.TriggerThreshold, Mode=TwoWay}" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Width="25"
|
Width="25"
|
||||||
Text="{ReflectionBinding Configuration.TriggerThreshold, StringFormat=\{0:0.00\}}" />
|
Text="{Binding Config.TriggerThreshold, StringFormat=\{0:0.00\}}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Margin="0,4,0,0"
|
Orientation="Vertical"
|
||||||
HorizontalAlignment="Center"
|
IsVisible="{Binding HasSides}">
|
||||||
VerticalAlignment="Center"
|
<StackPanel
|
||||||
IsVisible="{Binding !IsRight}"
|
Margin="0,4,0,0"
|
||||||
Orientation="Horizontal">
|
|
||||||
<TextBlock
|
|
||||||
Width="20"
|
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsLeftSR}"
|
IsVisible="{Binding IsLeft}"
|
||||||
TextAlignment="Center" />
|
Orientation="Horizontal">
|
||||||
<ToggleButton>
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ReflectionBinding Configuration.LeftButtonSr, Mode=TwoWay, Converter={StaticResource Key}}"
|
Width="20"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsLeftSR}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
<ToggleButton Name="LeftButtonSr">
|
||||||
</StackPanel>
|
<TextBlock
|
||||||
<StackPanel
|
Text="{Binding Config.LeftButtonSr, Converter={StaticResource Key}}"
|
||||||
Margin="0,4,0,0"
|
TextAlignment="Center" />
|
||||||
HorizontalAlignment="Center"
|
</ToggleButton>
|
||||||
VerticalAlignment="Center"
|
</StackPanel>
|
||||||
IsVisible="{Binding !IsRight}"
|
<StackPanel
|
||||||
Orientation="Horizontal">
|
Margin="0,4,0,0"
|
||||||
<TextBlock
|
|
||||||
Width="20"
|
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsLeftSL}"
|
IsVisible="{Binding IsLeft}"
|
||||||
TextAlignment="Center" />
|
Orientation="Horizontal">
|
||||||
<ToggleButton>
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ReflectionBinding Configuration.LeftButtonSl, Mode=TwoWay, Converter={StaticResource Key}}"
|
Width="20"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsLeftSL}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
<ToggleButton Name="LeftButtonSl">
|
||||||
</StackPanel>
|
<TextBlock
|
||||||
<StackPanel
|
Text="{Binding Config.LeftButtonSl, Converter={StaticResource Key}}"
|
||||||
Margin="0,4,0,0"
|
TextAlignment="Center" />
|
||||||
HorizontalAlignment="Center"
|
</ToggleButton>
|
||||||
VerticalAlignment="Center"
|
</StackPanel>
|
||||||
IsVisible="{Binding !IsLeft}"
|
<StackPanel
|
||||||
Orientation="Horizontal">
|
Margin="0,4,0,0"
|
||||||
<TextBlock
|
|
||||||
Width="20"
|
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsRightSR}"
|
IsVisible="{Binding IsRight}"
|
||||||
TextAlignment="Center" />
|
Orientation="Horizontal">
|
||||||
<ToggleButton>
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ReflectionBinding Configuration.RightButtonSr, Mode=TwoWay, Converter={StaticResource Key}}"
|
Width="20"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsRightSR}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
<ToggleButton Name="RightButtonSr">
|
||||||
</StackPanel>
|
<TextBlock
|
||||||
<StackPanel
|
Text="{Binding Config.RightButtonSr, Converter={StaticResource Key}}"
|
||||||
Margin="0,4,0,0"
|
TextAlignment="Center" />
|
||||||
HorizontalAlignment="Center"
|
</ToggleButton>
|
||||||
VerticalAlignment="Center"
|
</StackPanel>
|
||||||
IsVisible="{Binding !IsLeft}"
|
<StackPanel
|
||||||
Orientation="Horizontal">
|
Margin="0,4,0,0"
|
||||||
<TextBlock
|
|
||||||
Width="20"
|
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsRightSL}"
|
IsVisible="{Binding IsRight}"
|
||||||
TextAlignment="Center" />
|
Orientation="Horizontal">
|
||||||
<ToggleButton>
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ReflectionBinding Configuration.RightButtonSl, Mode=TwoWay, Converter={StaticResource Key}}"
|
Width="20"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsRightSL}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
<ToggleButton Name="RightButtonSl">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.RightButtonSl, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
<!-- Controller Picture -->
|
|
||||||
<Image
|
|
||||||
Margin="0,10,0,0"
|
|
||||||
MaxHeight="300"
|
|
||||||
HorizontalAlignment="Stretch"
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
Source="{Binding Image}" />
|
|
||||||
<!-- Motion + Rumble -->
|
<!-- Motion + Rumble -->
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Margin="0,10,0,0"
|
Margin="0,10,0,0"
|
||||||
|
@ -710,8 +439,7 @@
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
CornerRadius="5"
|
CornerRadius="5"
|
||||||
VerticalAlignment="Bottom"
|
VerticalAlignment="Bottom"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch">
|
||||||
IsVisible="{Binding IsController}">
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
|
@ -721,7 +449,7 @@
|
||||||
Margin="10"
|
Margin="10"
|
||||||
MinWidth="0"
|
MinWidth="0"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
IsChecked="{ReflectionBinding Configuration.EnableMotion, Mode=TwoWay}">
|
IsChecked="{Binding Config.EnableMotion, Mode=TwoWay}">
|
||||||
<TextBlock Text="{locale:Locale ControllerSettingsMotion}" />
|
<TextBlock Text="{locale:Locale ControllerSettingsMotion}" />
|
||||||
</CheckBox>
|
</CheckBox>
|
||||||
<Button
|
<Button
|
||||||
|
@ -737,7 +465,6 @@
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
CornerRadius="5"
|
CornerRadius="5"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
IsVisible="{Binding IsController}"
|
|
||||||
Margin="0,-1,0,0">
|
Margin="0,-1,0,0">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
|
@ -748,7 +475,7 @@
|
||||||
Margin="10"
|
Margin="10"
|
||||||
MinWidth="0"
|
MinWidth="0"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
IsChecked="{ReflectionBinding Configuration.EnableRumble, Mode=TwoWay}">
|
IsChecked="{Binding Config.EnableRumble, Mode=TwoWay}">
|
||||||
<TextBlock Text="{locale:Locale ControllerSettingsRumble}" />
|
<TextBlock Text="{locale:Locale ControllerSettingsRumble}" />
|
||||||
</CheckBox>
|
</CheckBox>
|
||||||
<Button
|
<Button
|
||||||
|
@ -794,9 +521,9 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsTriggerZR}"
|
Text="{locale:Locale ControllerSettingsTriggerZR}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
<ToggleButton>
|
<ToggleButton Name="ButtonZr">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ReflectionBinding Configuration.ButtonZr, Mode=TwoWay, Converter={StaticResource Key}}"
|
Text="{Binding Config.ButtonZr, Converter={StaticResource Key}}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
@ -812,9 +539,9 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsTriggerR}"
|
Text="{locale:Locale ControllerSettingsTriggerR}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
<ToggleButton>
|
<ToggleButton Name="ButtonR">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ReflectionBinding Configuration.ButtonR, Mode=TwoWay, Converter={StaticResource Key}}"
|
Text="{Binding Config.ButtonR, Converter={StaticResource Key}}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
@ -830,15 +557,15 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsButtonPlus}"
|
Text="{locale:Locale ControllerSettingsButtonPlus}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
<ToggleButton>
|
<ToggleButton Name="ButtonPlus">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ReflectionBinding Configuration.ButtonPlus, Mode=TwoWay, Converter={StaticResource Key}}"
|
Text="{Binding Config.ButtonPlus, Converter={StaticResource Key}}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Border>
|
</Border>
|
||||||
<!-- Right Joystick -->
|
<!-- Right Buttons -->
|
||||||
<Border
|
<Border
|
||||||
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||||
BorderThickness="1"
|
BorderThickness="1"
|
||||||
|
@ -865,9 +592,9 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsButtonA}"
|
Text="{locale:Locale ControllerSettingsButtonA}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
<ToggleButton>
|
<ToggleButton Name="ButtonA">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ReflectionBinding Configuration.ButtonA, Mode=TwoWay, Converter={StaticResource Key}}"
|
Text="{Binding Config.ButtonA, Converter={StaticResource Key}}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
@ -882,9 +609,9 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsButtonB}"
|
Text="{locale:Locale ControllerSettingsButtonB}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
<ToggleButton>
|
<ToggleButton Name="ButtonB">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ReflectionBinding Configuration.ButtonB, Mode=TwoWay, Converter={StaticResource Key}}"
|
Text="{Binding Config.ButtonB, Converter={StaticResource Key}}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
@ -899,9 +626,9 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsButtonX}"
|
Text="{locale:Locale ControllerSettingsButtonX}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
<ToggleButton>
|
<ToggleButton Name="ButtonX">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ReflectionBinding Configuration.ButtonX, Mode=TwoWay, Converter={StaticResource Key}}"
|
Text="{Binding Config.ButtonX, Converter={StaticResource Key}}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
@ -916,9 +643,9 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsButtonY}"
|
Text="{locale:Locale ControllerSettingsButtonY}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
<ToggleButton>
|
<ToggleButton Name="ButtonY">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ReflectionBinding Configuration.ButtonY, Mode=TwoWay, Converter={StaticResource Key}}"
|
Text="{Binding Config.ButtonY, Converter={StaticResource Key}}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
@ -938,100 +665,8 @@
|
||||||
Margin="0,0,0,10"
|
Margin="0,0,0,10"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsRStick}" />
|
Text="{locale:Locale ControllerSettingsRStick}" />
|
||||||
<!-- Right Joystick Keyboard -->
|
|
||||||
<StackPanel
|
|
||||||
IsVisible="{Binding !IsController}"
|
|
||||||
Orientation="Vertical">
|
|
||||||
<!-- Right Joystick Button -->
|
|
||||||
<StackPanel
|
|
||||||
Margin="0,0,0,4"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
<TextBlock
|
|
||||||
Margin="0,0,10,0"
|
|
||||||
Width="120"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{locale:Locale ControllerSettingsStickButton}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
<ToggleButton>
|
|
||||||
<TextBlock
|
|
||||||
Text="{ReflectionBinding Configuration.RightKeyboardStickButton, Mode=TwoWay, Converter={StaticResource Key}}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
</ToggleButton>
|
|
||||||
</StackPanel>
|
|
||||||
<!-- Right Joystick Up -->
|
|
||||||
<StackPanel
|
|
||||||
Margin="0,0,0,4"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
<TextBlock
|
|
||||||
Margin="0,0,10,0"
|
|
||||||
Width="120"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{locale:Locale ControllerSettingsStickUp}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
<ToggleButton>
|
|
||||||
<TextBlock
|
|
||||||
Text="{ReflectionBinding Configuration.RightStickUp, Mode=TwoWay, Converter={StaticResource Key}}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
</ToggleButton>
|
|
||||||
</StackPanel>
|
|
||||||
<!-- Right Joystick Down -->
|
|
||||||
<StackPanel
|
|
||||||
Margin="0,0,0,4"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
<TextBlock
|
|
||||||
Margin="0,0,10,0"
|
|
||||||
Width="120"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{locale:Locale ControllerSettingsStickDown}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
<ToggleButton>
|
|
||||||
<TextBlock
|
|
||||||
Text="{ReflectionBinding Configuration.RightStickDown, Mode=TwoWay, Converter={StaticResource Key}}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
</ToggleButton>
|
|
||||||
</StackPanel>
|
|
||||||
<!-- Right Joystick Left -->
|
|
||||||
<StackPanel
|
|
||||||
Margin="0,0,0,4"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
<TextBlock
|
|
||||||
Margin="0,0,10,0"
|
|
||||||
Width="120"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{locale:Locale ControllerSettingsStickLeft}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
<ToggleButton>
|
|
||||||
<TextBlock
|
|
||||||
Text="{ReflectionBinding Configuration.RightStickLeft, Mode=TwoWay, Converter={StaticResource Key}}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
</ToggleButton>
|
|
||||||
</StackPanel>
|
|
||||||
<!-- Right Joystick Right -->
|
|
||||||
<StackPanel
|
|
||||||
Margin="0,0,0,4"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
<TextBlock
|
|
||||||
Margin="0,0,10,0"
|
|
||||||
Width="120"
|
|
||||||
HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{locale:Locale ControllerSettingsStickRight}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
<ToggleButton>
|
|
||||||
<TextBlock
|
|
||||||
Text="{ReflectionBinding Configuration.RightStickRight, Mode=TwoWay, Converter={StaticResource Key}}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
</ToggleButton>
|
|
||||||
</StackPanel>
|
|
||||||
</StackPanel>
|
|
||||||
<!-- Right Joystick Controller -->
|
<!-- Right Joystick Controller -->
|
||||||
<StackPanel
|
<StackPanel Orientation="Vertical">
|
||||||
IsVisible="{Binding IsController}"
|
|
||||||
Orientation="Vertical">
|
|
||||||
<!-- Right Joystick Button -->
|
<!-- Right Joystick Button -->
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Orientation="Horizontal">
|
Orientation="Horizontal">
|
||||||
|
@ -1042,9 +677,9 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsStickButton}"
|
Text="{locale:Locale ControllerSettingsStickButton}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
<ToggleButton>
|
<ToggleButton Name="RightStickButton">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ReflectionBinding Configuration.RightControllerStickButton, Mode=TwoWay, Converter={StaticResource Key}}"
|
Text="{Binding Config.RightStickButton, Converter={StaticResource Key}}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
@ -1060,20 +695,20 @@
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Text="{locale:Locale ControllerSettingsStickStick}"
|
Text="{locale:Locale ControllerSettingsStickStick}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
<ToggleButton Tag="stick">
|
<ToggleButton Name="RightJoystick" Tag="stick">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{ReflectionBinding Configuration.RightJoystick, Mode=TwoWay, Converter={StaticResource Key}}"
|
Text="{Binding Config.RightJoystick, Converter={StaticResource Key}}"
|
||||||
TextAlignment="Center" />
|
TextAlignment="Center" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<Separator Margin="0,8,0,8" Height="1" />
|
<Separator Margin="0,8,0,8" Height="1" />
|
||||||
<CheckBox IsChecked="{ReflectionBinding Configuration.RightInvertStickX}">
|
<CheckBox IsChecked="{Binding Config.RightInvertStickX}">
|
||||||
<TextBlock Text="{locale:Locale ControllerSettingsStickInvertXAxis}" />
|
<TextBlock Text="{locale:Locale ControllerSettingsStickInvertXAxis}" />
|
||||||
</CheckBox>
|
</CheckBox>
|
||||||
<CheckBox IsChecked="{ReflectionBinding Configuration.RightInvertStickY}">
|
<CheckBox IsChecked="{Binding Config.RightInvertStickY}">
|
||||||
<TextBlock Text="{locale:Locale ControllerSettingsStickInvertYAxis}" />
|
<TextBlock Text="{locale:Locale ControllerSettingsStickInvertYAxis}" />
|
||||||
</CheckBox>
|
</CheckBox>
|
||||||
<CheckBox IsChecked="{ReflectionBinding Configuration.RightRotate90}">
|
<CheckBox IsChecked="{Binding Config.RightRotate90}">
|
||||||
<TextBlock Text="{locale:Locale ControllerSettingsRotate90}" />
|
<TextBlock Text="{locale:Locale ControllerSettingsRotate90}" />
|
||||||
</CheckBox>
|
</CheckBox>
|
||||||
<Separator Margin="0,8,0,8" Height="1" />
|
<Separator Margin="0,8,0,8" Height="1" />
|
||||||
|
@ -1094,11 +729,11 @@
|
||||||
Padding="0"
|
Padding="0"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Minimum="0"
|
Minimum="0"
|
||||||
Value="{ReflectionBinding Configuration.DeadzoneRight, Mode=TwoWay}" />
|
Value="{Binding Config.DeadzoneRight, Mode=TwoWay}" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Width="25"
|
Width="25"
|
||||||
Text="{ReflectionBinding Configuration.DeadzoneRight, StringFormat=\{0:0.00\}}" />
|
Text="{Binding Config.DeadzoneRight, StringFormat=\{0:0.00\}}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<TextBlock
|
<TextBlock
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
|
@ -1114,11 +749,11 @@
|
||||||
IsSnapToTickEnabled="True"
|
IsSnapToTickEnabled="True"
|
||||||
SmallChange="0.01"
|
SmallChange="0.01"
|
||||||
Minimum="0"
|
Minimum="0"
|
||||||
Value="{ReflectionBinding Configuration.RangeRight, Mode=TwoWay}" />
|
Value="{Binding Config.RangeRight, Mode=TwoWay}" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Width="25"
|
Width="25"
|
||||||
Text="{ReflectionBinding Configuration.RangeRight, StringFormat=\{0:0.00\}}" />
|
Text="{Binding Config.RangeRight, StringFormat=\{0:0.00\}}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
|
@ -1,35 +1,29 @@
|
||||||
|
using Avalonia;
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using Avalonia.Controls.Primitives;
|
using Avalonia.Controls.Primitives;
|
||||||
using Avalonia.Input;
|
using Avalonia.Input;
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Avalonia.LogicalTree;
|
using Avalonia.LogicalTree;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.Models;
|
using Ryujinx.Ava.UI.ViewModels.Input;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
|
||||||
using Ryujinx.Common.Configuration.Hid.Controller;
|
using Ryujinx.Common.Configuration.Hid.Controller;
|
||||||
using Ryujinx.Input;
|
using Ryujinx.Input;
|
||||||
using Ryujinx.Input.Assigner;
|
using Ryujinx.Input.Assigner;
|
||||||
using System;
|
using StickInputId = Ryujinx.Common.Configuration.Hid.Controller.StickInputId;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Views.Input
|
namespace Ryujinx.Ava.UI.Views.Input
|
||||||
{
|
{
|
||||||
public partial class ControllerInputView : UserControl
|
public partial class ControllerInputView : UserControl
|
||||||
{
|
{
|
||||||
private bool _dialogOpen;
|
|
||||||
|
|
||||||
private ButtonKeyAssigner _currentAssigner;
|
private ButtonKeyAssigner _currentAssigner;
|
||||||
internal ControllerInputViewModel ViewModel { get; set; }
|
|
||||||
|
|
||||||
public ControllerInputView()
|
public ControllerInputView()
|
||||||
{
|
{
|
||||||
DataContext = ViewModel = new ControllerInputViewModel(this);
|
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
foreach (ILogical visual in SettingButtons.GetLogicalDescendants())
|
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;
|
button.IsCheckedChanged += Button_IsCheckedChanged;
|
||||||
}
|
}
|
||||||
|
@ -67,14 +61,87 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||||
|
|
||||||
PointerPressed += MouseClick;
|
PointerPressed += MouseClick;
|
||||||
|
|
||||||
IKeyboard keyboard = (IKeyboard)ViewModel.AvaloniaKeyboardDriver.GetGamepad("0"); // Open Avalonia keyboard for cancel operations.
|
var viewModel = (DataContext as ControllerInputViewModel);
|
||||||
|
|
||||||
|
IKeyboard keyboard = (IKeyboard)viewModel.ParentModel.AvaloniaKeyboardDriver.GetGamepad("0"); // Open Avalonia keyboard for cancel operations.
|
||||||
IButtonAssigner assigner = CreateButtonAssigner(isStick);
|
IButtonAssigner assigner = CreateButtonAssigner(isStick);
|
||||||
|
|
||||||
_currentAssigner.ButtonAssigned += (sender, e) =>
|
_currentAssigner.ButtonAssigned += (sender, e) =>
|
||||||
{
|
{
|
||||||
if (e.IsAssigned)
|
if (e.ButtonValue.HasValue)
|
||||||
{
|
{
|
||||||
ViewModel.IsModified = true;
|
var buttonValue = e.ButtonValue.Value;
|
||||||
|
viewModel.ParentModel.IsModified = true;
|
||||||
|
|
||||||
|
switch (button.Name)
|
||||||
|
{
|
||||||
|
case "ButtonZl":
|
||||||
|
viewModel.Config.ButtonZl = buttonValue.AsHidType<GamepadInputId>();
|
||||||
|
break;
|
||||||
|
case "ButtonL":
|
||||||
|
viewModel.Config.ButtonL = buttonValue.AsHidType<GamepadInputId>();
|
||||||
|
break;
|
||||||
|
case "ButtonMinus":
|
||||||
|
viewModel.Config.ButtonMinus = buttonValue.AsHidType<GamepadInputId>();
|
||||||
|
break;
|
||||||
|
case "LeftStickButton":
|
||||||
|
viewModel.Config.LeftStickButton = buttonValue.AsHidType<GamepadInputId>();
|
||||||
|
break;
|
||||||
|
case "LeftJoystick":
|
||||||
|
viewModel.Config.LeftJoystick = buttonValue.AsHidType<StickInputId>();
|
||||||
|
break;
|
||||||
|
case "DpadUp":
|
||||||
|
viewModel.Config.DpadUp = buttonValue.AsHidType<GamepadInputId>();
|
||||||
|
break;
|
||||||
|
case "DpadDown":
|
||||||
|
viewModel.Config.DpadDown = buttonValue.AsHidType<GamepadInputId>();
|
||||||
|
break;
|
||||||
|
case "DpadLeft":
|
||||||
|
viewModel.Config.DpadLeft = buttonValue.AsHidType<GamepadInputId>();
|
||||||
|
break;
|
||||||
|
case "DpadRight":
|
||||||
|
viewModel.Config.DpadRight = buttonValue.AsHidType<GamepadInputId>();
|
||||||
|
break;
|
||||||
|
case "LeftButtonSr":
|
||||||
|
viewModel.Config.LeftButtonSr = buttonValue.AsHidType<GamepadInputId>();
|
||||||
|
break;
|
||||||
|
case "LeftButtonSl":
|
||||||
|
viewModel.Config.LeftButtonSl = buttonValue.AsHidType<GamepadInputId>();
|
||||||
|
break;
|
||||||
|
case "RightButtonSr":
|
||||||
|
viewModel.Config.RightButtonSr = buttonValue.AsHidType<GamepadInputId>();
|
||||||
|
break;
|
||||||
|
case "RightButtonSl":
|
||||||
|
viewModel.Config.RightButtonSl = buttonValue.AsHidType<GamepadInputId>();
|
||||||
|
break;
|
||||||
|
case "ButtonZr":
|
||||||
|
viewModel.Config.ButtonZr = buttonValue.AsHidType<GamepadInputId>();
|
||||||
|
break;
|
||||||
|
case "ButtonR":
|
||||||
|
viewModel.Config.ButtonR = buttonValue.AsHidType<GamepadInputId>();
|
||||||
|
break;
|
||||||
|
case "ButtonPlus":
|
||||||
|
viewModel.Config.ButtonPlus = buttonValue.AsHidType<GamepadInputId>();
|
||||||
|
break;
|
||||||
|
case "ButtonA":
|
||||||
|
viewModel.Config.ButtonA = buttonValue.AsHidType<GamepadInputId>();
|
||||||
|
break;
|
||||||
|
case "ButtonB":
|
||||||
|
viewModel.Config.ButtonB = buttonValue.AsHidType<GamepadInputId>();
|
||||||
|
break;
|
||||||
|
case "ButtonX":
|
||||||
|
viewModel.Config.ButtonX = buttonValue.AsHidType<GamepadInputId>();
|
||||||
|
break;
|
||||||
|
case "ButtonY":
|
||||||
|
viewModel.Config.ButtonY = buttonValue.AsHidType<GamepadInputId>();
|
||||||
|
break;
|
||||||
|
case "RightStickButton":
|
||||||
|
viewModel.Config.RightStickButton = buttonValue.AsHidType<GamepadInputId>();
|
||||||
|
break;
|
||||||
|
case "RightJoystick":
|
||||||
|
viewModel.Config.RightJoystick = buttonValue.AsHidType<StickInputId>();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -84,8 +151,6 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||||
{
|
{
|
||||||
if (_currentAssigner != null)
|
if (_currentAssigner != null)
|
||||||
{
|
{
|
||||||
ToggleButton oldButton = _currentAssigner.ToggledButton;
|
|
||||||
|
|
||||||
_currentAssigner.Cancel();
|
_currentAssigner.Cancel();
|
||||||
_currentAssigner = null;
|
_currentAssigner = null;
|
||||||
button.IsChecked = false;
|
button.IsChecked = false;
|
||||||
|
@ -100,82 +165,34 @@ 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)
|
private void MouseClick(object sender, PointerPressedEventArgs e)
|
||||||
{
|
{
|
||||||
bool shouldUnbind = false;
|
bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed;
|
||||||
|
|
||||||
if (e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed)
|
|
||||||
{
|
|
||||||
shouldUnbind = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentAssigner?.Cancel(shouldUnbind);
|
_currentAssigner?.Cancel(shouldUnbind);
|
||||||
|
|
||||||
PointerPressed -= MouseClick;
|
PointerPressed -= MouseClick;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void PlayerIndexBox_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
private IButtonAssigner CreateButtonAssigner(bool forStick)
|
||||||
{
|
{
|
||||||
if (ViewModel.IsModified && !_dialogOpen)
|
IButtonAssigner assigner;
|
||||||
{
|
|
||||||
_dialogOpen = true;
|
|
||||||
|
|
||||||
var result = await ContentDialogHelper.CreateConfirmationDialog(
|
var controllerInputViewModel = DataContext as ControllerInputViewModel;
|
||||||
LocaleManager.Instance[LocaleKeys.DialogControllerSettingsModifiedConfirmMessage],
|
|
||||||
LocaleManager.Instance[LocaleKeys.DialogControllerSettingsModifiedConfirmSubMessage],
|
|
||||||
LocaleManager.Instance[LocaleKeys.InputDialogYes],
|
|
||||||
LocaleManager.Instance[LocaleKeys.InputDialogNo],
|
|
||||||
LocaleManager.Instance[LocaleKeys.RyujinxConfirm]);
|
|
||||||
|
|
||||||
if (result == UserResult.Yes)
|
assigner = new GamepadButtonAssigner(
|
||||||
{
|
controllerInputViewModel.ParentModel.SelectedGamepad,
|
||||||
ViewModel.Save();
|
(controllerInputViewModel.ParentModel.Config as StandardControllerInputConfig).TriggerThreshold,
|
||||||
}
|
forStick);
|
||||||
|
|
||||||
_dialogOpen = false;
|
return assigner;
|
||||||
|
|
||||||
ViewModel.IsModified = false;
|
|
||||||
|
|
||||||
if (e.AddedItems.Count > 0)
|
|
||||||
{
|
|
||||||
var player = (PlayerModel)e.AddedItems[0];
|
|
||||||
ViewModel.PlayerId = player.Id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
|
||||||
{
|
{
|
||||||
|
base.OnDetachedFromVisualTree(e);
|
||||||
_currentAssigner?.Cancel();
|
_currentAssigner?.Cancel();
|
||||||
_currentAssigner = null;
|
_currentAssigner = null;
|
||||||
ViewModel.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
225
src/Ryujinx/UI/Views/Input/InputView.axaml
Normal file
225
src/Ryujinx/UI/Views/Input/InputView.axaml
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
<UserControl
|
||||||
|
xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||||
|
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:models="clr-namespace:Ryujinx.Ava.UI.Models"
|
||||||
|
xmlns:views="clr-namespace:Ryujinx.Ava.UI.Views.Input"
|
||||||
|
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels.Input"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
d:DesignHeight="800"
|
||||||
|
d:DesignWidth="800"
|
||||||
|
x:Class="Ryujinx.Ava.UI.Views.Input.InputView"
|
||||||
|
x:DataType="viewModels:InputViewModel"
|
||||||
|
x:CompileBindings="True"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Focusable="True">
|
||||||
|
<Design.DataContext>
|
||||||
|
<viewModels:InputViewModel />
|
||||||
|
</Design.DataContext>
|
||||||
|
<UserControl.Styles>
|
||||||
|
<Style Selector="ToggleButton">
|
||||||
|
<Setter Property="Width" Value="90" />
|
||||||
|
<Setter Property="Height" Value="27" />
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||||
|
</Style>
|
||||||
|
</UserControl.Styles>
|
||||||
|
<StackPanel
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
Orientation="Vertical">
|
||||||
|
<StackPanel
|
||||||
|
Margin="0 0 0 5"
|
||||||
|
Orientation="Vertical"
|
||||||
|
Spacing="5">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="10" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<!-- Player Selection -->
|
||||||
|
<Grid
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="2"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Center">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBlock
|
||||||
|
Margin="5,0,10,0"
|
||||||
|
Width="90"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsPlayer}" />
|
||||||
|
<ComboBox
|
||||||
|
Grid.Column="1"
|
||||||
|
Name="PlayerIndexBox"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
SelectionChanged="PlayerIndexBox_OnSelectionChanged"
|
||||||
|
ItemsSource="{Binding PlayerIndexes}"
|
||||||
|
SelectedIndex="{Binding PlayerId}">
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<TextBlock Text="{Binding Name}" />
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
|
</ComboBox>
|
||||||
|
</Grid>
|
||||||
|
<!-- Profile Selection -->
|
||||||
|
<Grid
|
||||||
|
Grid.Column="2"
|
||||||
|
Margin="2"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Center">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBlock
|
||||||
|
Margin="5,0,10,0"
|
||||||
|
Width="90"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsProfile}" />
|
||||||
|
<ui:FAComboBox
|
||||||
|
Grid.Column="1"
|
||||||
|
IsEditable="True"
|
||||||
|
Name="ProfileBox"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
SelectedIndex="0"
|
||||||
|
ItemsSource="{Binding ProfilesList}"
|
||||||
|
Text="{Binding ProfileName, Mode=TwoWay}" />
|
||||||
|
<Button
|
||||||
|
Grid.Column="2"
|
||||||
|
MinWidth="0"
|
||||||
|
Margin="5,0,0,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
ToolTip.Tip="{locale:Locale ControllerSettingsLoadProfileToolTip}"
|
||||||
|
Command="{Binding LoadProfile}">
|
||||||
|
<ui:SymbolIcon
|
||||||
|
Symbol="Upload"
|
||||||
|
FontSize="15"
|
||||||
|
Height="20" />
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
Grid.Column="3"
|
||||||
|
MinWidth="0"
|
||||||
|
Margin="5,0,0,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
ToolTip.Tip="{locale:Locale ControllerSettingsSaveProfileToolTip}"
|
||||||
|
Command="{Binding SaveProfile}">
|
||||||
|
<ui:SymbolIcon
|
||||||
|
Symbol="Save"
|
||||||
|
FontSize="15"
|
||||||
|
Height="20" />
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
Grid.Column="4"
|
||||||
|
MinWidth="0"
|
||||||
|
Margin="5,0,0,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
ToolTip.Tip="{locale:Locale ControllerSettingsRemoveProfileToolTip}"
|
||||||
|
Command="{Binding RemoveProfile}">
|
||||||
|
<ui:SymbolIcon
|
||||||
|
Symbol="Delete"
|
||||||
|
FontSize="15"
|
||||||
|
Height="20" />
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
<Separator />
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="10" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<!-- Input Device -->
|
||||||
|
<Grid
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="2"
|
||||||
|
HorizontalAlignment="Stretch">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBlock
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="5,0,10,0"
|
||||||
|
Width="90"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsInputDevice}" />
|
||||||
|
<ComboBox
|
||||||
|
Grid.Column="1"
|
||||||
|
Name="DeviceBox"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
ItemsSource="{Binding DeviceList}"
|
||||||
|
SelectedIndex="{Binding Device}" />
|
||||||
|
<Button
|
||||||
|
Grid.Column="2"
|
||||||
|
MinWidth="0"
|
||||||
|
Margin="5,0,0,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Command="{Binding LoadDevices}">
|
||||||
|
<ui:SymbolIcon
|
||||||
|
Symbol="Refresh"
|
||||||
|
FontSize="15"
|
||||||
|
Height="20"/>
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
<!-- Controller Type -->
|
||||||
|
<Grid
|
||||||
|
Grid.Column="2"
|
||||||
|
Margin="2"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Center">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBlock
|
||||||
|
Margin="5,0,10,0"
|
||||||
|
Width="90"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsControllerType}" />
|
||||||
|
<ComboBox
|
||||||
|
Grid.Column="1"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
ItemsSource="{Binding Controllers}"
|
||||||
|
SelectedIndex="{Binding Controller}">
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate DataType="models:ControllerModel">
|
||||||
|
<TextBlock Text="{Binding Name}" />
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
|
</ComboBox>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</StackPanel>
|
||||||
|
<ContentControl Content="{Binding ConfigViewModel}" IsVisible="{Binding ShowSettings}">
|
||||||
|
<ContentControl.DataTemplates>
|
||||||
|
<DataTemplate DataType="viewModels:ControllerInputViewModel">
|
||||||
|
<views:ControllerInputView />
|
||||||
|
</DataTemplate>
|
||||||
|
<DataTemplate DataType="viewModels:KeyboardInputViewModel">
|
||||||
|
<views:KeyboardInputView />
|
||||||
|
</DataTemplate>
|
||||||
|
</ContentControl.DataTemplates>
|
||||||
|
</ContentControl>
|
||||||
|
</StackPanel>
|
||||||
|
</UserControl>
|
61
src/Ryujinx/UI/Views/Input/InputView.axaml.cs
Normal file
61
src/Ryujinx/UI/Views/Input/InputView.axaml.cs
Normal file
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
675
src/Ryujinx/UI/Views/Input/KeyboardInputView.axaml
Normal file
675
src/Ryujinx/UI/Views/Input/KeyboardInputView.axaml
Normal file
|
@ -0,0 +1,675 @@
|
||||||
|
<UserControl
|
||||||
|
xmlns="https://github.com/avaloniaui"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels.Input"
|
||||||
|
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
d:DesignHeight="800"
|
||||||
|
d:DesignWidth="800"
|
||||||
|
x:Class="Ryujinx.Ava.UI.Views.Input.KeyboardInputView"
|
||||||
|
x:DataType="viewModels:KeyboardInputViewModel"
|
||||||
|
x:CompileBindings="True"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Focusable="True">
|
||||||
|
<Design.DataContext>
|
||||||
|
<viewModels:KeyboardInputViewModel />
|
||||||
|
</Design.DataContext>
|
||||||
|
<UserControl.Resources>
|
||||||
|
<helpers:KeyValueConverter x:Key="Key" />
|
||||||
|
</UserControl.Resources>
|
||||||
|
<UserControl.Styles>
|
||||||
|
<Style Selector="ToggleButton">
|
||||||
|
<Setter Property="Width" Value="90" />
|
||||||
|
<Setter Property="Height" Value="27" />
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||||
|
</Style>
|
||||||
|
</UserControl.Styles>
|
||||||
|
<StackPanel
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
Orientation="Vertical">
|
||||||
|
<!-- Button / JoyStick Settings -->
|
||||||
|
<Grid
|
||||||
|
Name="SettingButtons"
|
||||||
|
MinHeight="450">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<!-- Left Controls -->
|
||||||
|
<StackPanel
|
||||||
|
Orientation="Vertical"
|
||||||
|
Margin="0,0,5,0"
|
||||||
|
Grid.Column="0">
|
||||||
|
<!-- Left Triggers -->
|
||||||
|
<Border
|
||||||
|
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||||
|
BorderThickness="1"
|
||||||
|
IsVisible="{Binding IsLeft}"
|
||||||
|
MinHeight="90"
|
||||||
|
CornerRadius="5">
|
||||||
|
<Grid
|
||||||
|
Margin="10"
|
||||||
|
HorizontalAlignment="Stretch">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition />
|
||||||
|
<RowDefinition />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<StackPanel
|
||||||
|
Grid.Column="0"
|
||||||
|
Grid.Row="0"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Width="20"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsTriggerZL}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="ButtonZl">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.ButtonZl, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel
|
||||||
|
Grid.Column="0"
|
||||||
|
Grid.Row="1"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Width="20"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsTriggerL}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="ButtonL">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.ButtonL, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel
|
||||||
|
Grid.Column="1"
|
||||||
|
Grid.Row="1"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Width="20"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsButtonMinus}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="ButtonMinus">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.ButtonMinus, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
<!-- Left Joystick -->
|
||||||
|
<Border
|
||||||
|
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||||
|
BorderThickness="1"
|
||||||
|
IsVisible="{Binding IsLeft}"
|
||||||
|
Margin="0,5,0,0"
|
||||||
|
CornerRadius="5">
|
||||||
|
<StackPanel
|
||||||
|
Margin="10"
|
||||||
|
Orientation="Vertical">
|
||||||
|
<TextBlock
|
||||||
|
Margin="0,0,0,10"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsLStick}" />
|
||||||
|
<!-- Left Joystick Keyboard -->
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
<!-- Left Joystick Button -->
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,0,0,4"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
Width="120"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsStickButton}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="LeftStickButton">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.LeftStickButton, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<!-- Left Joystick Up -->
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,0,0,4"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
Width="120"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsStickUp}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="LeftStickUp">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.LeftStickUp, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<!-- Left Joystick Down -->
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,0,0,4"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
Width="120"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsStickDown}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="LeftStickDown">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.LeftStickDown, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<!-- Left Joystick Left -->
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,0,0,4"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
Width="120"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsStickLeft}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="LeftStickLeft">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.LeftStickLeft, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<!-- Left Joystick Right -->
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,0,0,4"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
Width="120"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsStickRight}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="LeftStickRight">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.LeftStickRight, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
<!-- Left DPad -->
|
||||||
|
<Border
|
||||||
|
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||||
|
BorderThickness="1"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
IsVisible="{Binding IsLeft}"
|
||||||
|
Margin="0,5,0,0"
|
||||||
|
CornerRadius="5">
|
||||||
|
<StackPanel
|
||||||
|
Margin="10"
|
||||||
|
Orientation="Vertical">
|
||||||
|
<TextBlock
|
||||||
|
Margin="0,0,0,10"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsDPad}" />
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
<!-- Left DPad Up -->
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,0,0,4"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
Width="120"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsDPadUp}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="DpadUp">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.DpadUp, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<!-- Left DPad Down -->
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,0,0,4"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
Width="120"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsDPadDown}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="DpadDown">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.DpadDown, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<!-- Left DPad Left -->
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,0,0,4"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
Width="120"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsDPadLeft}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="DpadLeft">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.DpadLeft, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<!-- Left DPad Right -->
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,0,0,4"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
Width="120"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsDPadRight}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="DpadRight">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.DpadRight, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
</StackPanel>
|
||||||
|
<!-- Triggers & Side Buttons -->
|
||||||
|
<StackPanel
|
||||||
|
Grid.Column="1"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Stretch">
|
||||||
|
<!-- Controller Picture -->
|
||||||
|
<Image
|
||||||
|
Margin="0,10"
|
||||||
|
MaxHeight="300"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
Source="{Binding Image}" />
|
||||||
|
<Border
|
||||||
|
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="5"
|
||||||
|
MinHeight="90"
|
||||||
|
IsVisible="{Binding HasSides}">
|
||||||
|
<StackPanel
|
||||||
|
Margin="8"
|
||||||
|
Orientation="Vertical">
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,4,0,0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
IsVisible="{Binding IsLeft}"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Width="20"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsLeftSR}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="LeftButtonSr">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.LeftButtonSr, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,4,0,0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
IsVisible="{Binding IsLeft}"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Width="20"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsLeftSL}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="LeftButtonSl">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.LeftButtonSl, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,4,0,0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
IsVisible="{Binding IsRight}"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Width="20"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsRightSR}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="RightButtonSr">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.RightButtonSr, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,4,0,0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
IsVisible="{Binding IsRight}"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Width="20"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsRightSL}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="RightButtonSl">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.RightButtonSl, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
</StackPanel>
|
||||||
|
<!-- Right Controls -->
|
||||||
|
<StackPanel
|
||||||
|
Orientation="Vertical"
|
||||||
|
Margin="5,0,0,0"
|
||||||
|
Grid.Column="2">
|
||||||
|
<!-- Right Triggers -->
|
||||||
|
<Border
|
||||||
|
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||||
|
BorderThickness="1"
|
||||||
|
IsVisible="{Binding IsRight}"
|
||||||
|
MinHeight="90"
|
||||||
|
CornerRadius="5">
|
||||||
|
<Grid
|
||||||
|
Margin="10"
|
||||||
|
HorizontalAlignment="Stretch">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition />
|
||||||
|
<RowDefinition />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<StackPanel
|
||||||
|
Grid.Column="1"
|
||||||
|
Grid.Row="0"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Width="20"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsTriggerZR}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="ButtonZr">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.ButtonZr, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel
|
||||||
|
Grid.Column="1"
|
||||||
|
Grid.Row="1"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Width="20"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsTriggerR}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="ButtonR">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.ButtonR, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel
|
||||||
|
Grid.Column="0"
|
||||||
|
Grid.Row="1"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Width="20"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsButtonPlus}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="ButtonPlus">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.ButtonPlus, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
<!-- Right Buttons -->
|
||||||
|
<Border
|
||||||
|
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||||
|
BorderThickness="1"
|
||||||
|
IsVisible="{Binding IsRight}"
|
||||||
|
Margin="0,5,0,0"
|
||||||
|
CornerRadius="5">
|
||||||
|
<StackPanel
|
||||||
|
Margin="10"
|
||||||
|
Orientation="Vertical">
|
||||||
|
<TextBlock
|
||||||
|
Margin="0,0,0,10"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsButtons}" />
|
||||||
|
<StackPanel
|
||||||
|
Orientation="Vertical">
|
||||||
|
<!-- Right Buttons A -->
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,0,0,4"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Width="120"
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsButtonA}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="ButtonA">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.ButtonA, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<!-- Right Buttons B -->
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,0,0,4"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Width="120"
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsButtonB}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="ButtonB">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.ButtonB, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<!-- Right Buttons X -->
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,0,0,4"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Width="120"
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsButtonX}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="ButtonX">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.ButtonX, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<!-- Right Buttons Y -->
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,0,0,4"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Width="120"
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsButtonY}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="ButtonY">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.ButtonY, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
<!-- Right DPad -->
|
||||||
|
<Border
|
||||||
|
Padding="10"
|
||||||
|
BorderBrush="{DynamicResource ThemeControlBorderColor}"
|
||||||
|
BorderThickness="1"
|
||||||
|
CornerRadius="5"
|
||||||
|
IsVisible="{Binding IsRight}"
|
||||||
|
Margin="0,5,0,0">
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
<TextBlock
|
||||||
|
Margin="0,0,0,10"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsRStick}" />
|
||||||
|
<!-- Right Joystick Keyboard -->
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
<!-- Right Joystick Button -->
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,0,0,4"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
Width="120"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsStickButton}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="RightStickButton">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.RightStickButton, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<!-- Right Joystick Up -->
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,0,0,4"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
Width="120"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsStickUp}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="RightStickUp">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.RightStickUp, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<!-- Right Joystick Down -->
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,0,0,4"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
Width="120"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsStickDown}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="RightStickDown">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.RightStickDown, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<!-- Right Joystick Left -->
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,0,0,4"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
Width="120"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsStickLeft}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="RightStickLeft">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.RightStickLeft, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
<!-- Right Joystick Right -->
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,0,0,4"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
Width="120"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{locale:Locale ControllerSettingsStickRight}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
<ToggleButton Name="RightStickRight">
|
||||||
|
<TextBlock
|
||||||
|
Text="{Binding Config.RightStickRight, Converter={StaticResource Key}}"
|
||||||
|
TextAlignment="Center" />
|
||||||
|
</ToggleButton>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</StackPanel>
|
||||||
|
</UserControl>
|
208
src/Ryujinx/UI/Views/Input/KeyboardInputView.axaml.cs
Normal file
208
src/Ryujinx/UI/Views/Input/KeyboardInputView.axaml.cs
Normal file
|
@ -0,0 +1,208 @@
|
||||||
|
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 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 != 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_currentAssigner == null)
|
||||||
|
{
|
||||||
|
_currentAssigner = new ButtonKeyAssigner(button);
|
||||||
|
|
||||||
|
Focus(NavigationMethod.Pointer);
|
||||||
|
|
||||||
|
PointerPressed += MouseClick;
|
||||||
|
|
||||||
|
var viewModel = (DataContext as KeyboardInputViewModel);
|
||||||
|
|
||||||
|
IKeyboard keyboard = (IKeyboard)viewModel.ParentModel.AvaloniaKeyboardDriver.GetGamepad("0"); // Open Avalonia keyboard for cancel operations.
|
||||||
|
IButtonAssigner assigner = CreateButtonAssigner();
|
||||||
|
|
||||||
|
_currentAssigner.ButtonAssigned += (sender, e) =>
|
||||||
|
{
|
||||||
|
if (e.ButtonValue.HasValue)
|
||||||
|
{
|
||||||
|
var 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 MouseClick(object sender, PointerPressedEventArgs e)
|
||||||
|
{
|
||||||
|
bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed;
|
||||||
|
|
||||||
|
_currentAssigner?.Cancel(shouldUnbind);
|
||||||
|
|
||||||
|
PointerPressed -= MouseClick;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IButtonAssigner CreateButtonAssigner()
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,7 +6,7 @@
|
||||||
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
|
xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
|
||||||
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||||
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
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"
|
mc:Ignorable="d"
|
||||||
x:Class="Ryujinx.Ava.UI.Views.Input.MotionInputView"
|
x:Class="Ryujinx.Ava.UI.Views.Input.MotionInputView"
|
||||||
x:DataType="viewModels:MotionInputViewModel"
|
x:DataType="viewModels:MotionInputViewModel"
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using FluentAvalonia.UI.Controls;
|
using FluentAvalonia.UI.Controls;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.UI.Models;
|
using Ryujinx.Ava.UI.ViewModels.Input;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
|
||||||
using Ryujinx.Common.Configuration.Hid.Controller;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Views.Input
|
namespace Ryujinx.Ava.UI.Views.Input
|
||||||
|
@ -19,7 +17,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||||
|
|
||||||
public MotionInputView(ControllerInputViewModel viewModel)
|
public MotionInputView(ControllerInputViewModel viewModel)
|
||||||
{
|
{
|
||||||
var config = viewModel.Configuration as InputConfiguration<GamepadInputId, StickInputId>;
|
var config = viewModel.Config;
|
||||||
|
|
||||||
_viewModel = new MotionInputViewModel
|
_viewModel = new MotionInputViewModel
|
||||||
{
|
{
|
||||||
|
@ -51,7 +49,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||||
};
|
};
|
||||||
contentDialog.PrimaryButtonClick += (sender, args) =>
|
contentDialog.PrimaryButtonClick += (sender, args) =>
|
||||||
{
|
{
|
||||||
var config = viewModel.Configuration as InputConfiguration<GamepadInputId, StickInputId>;
|
var config = viewModel.Config;
|
||||||
config.Slot = content._viewModel.Slot;
|
config.Slot = content._viewModel.Slot;
|
||||||
config.Sensitivity = content._viewModel.Sensitivity;
|
config.Sensitivity = content._viewModel.Sensitivity;
|
||||||
config.GyroDeadzone = content._viewModel.GyroDeadzone;
|
config.GyroDeadzone = content._viewModel.GyroDeadzone;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
|
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"
|
mc:Ignorable="d"
|
||||||
x:Class="Ryujinx.Ava.UI.Views.Input.RumbleInputView"
|
x:Class="Ryujinx.Ava.UI.Views.Input.RumbleInputView"
|
||||||
x:DataType="viewModels:RumbleInputViewModel"
|
x:DataType="viewModels:RumbleInputViewModel"
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
using FluentAvalonia.UI.Controls;
|
using FluentAvalonia.UI.Controls;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.UI.Models;
|
using Ryujinx.Ava.UI.ViewModels.Input;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
|
||||||
using Ryujinx.Common.Configuration.Hid.Controller;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Views.Input
|
namespace Ryujinx.Ava.UI.Views.Input
|
||||||
|
@ -19,7 +17,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||||
|
|
||||||
public RumbleInputView(ControllerInputViewModel viewModel)
|
public RumbleInputView(ControllerInputViewModel viewModel)
|
||||||
{
|
{
|
||||||
var config = viewModel.Configuration as InputConfiguration<GamepadInputId, StickInputId>;
|
var config = viewModel.Config;
|
||||||
|
|
||||||
_viewModel = new RumbleInputViewModel
|
_viewModel = new RumbleInputViewModel
|
||||||
{
|
{
|
||||||
|
@ -47,7 +45,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||||
|
|
||||||
contentDialog.PrimaryButtonClick += (sender, args) =>
|
contentDialog.PrimaryButtonClick += (sender, args) =>
|
||||||
{
|
{
|
||||||
var config = viewModel.Configuration as InputConfiguration<GamepadInputId, StickInputId>;
|
var config = viewModel.Config;
|
||||||
config.StrongRumble = content._viewModel.StrongRumble;
|
config.StrongRumble = content._viewModel.StrongRumble;
|
||||||
config.WeakRumble = content._viewModel.WeakRumble;
|
config.WeakRumble = content._viewModel.WeakRumble;
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
x:DataType="viewModels:SettingsViewModel"
|
x:DataType="viewModels:SettingsViewModel"
|
||||||
|
x:CompileBindings="True"
|
||||||
Focusable="True">
|
Focusable="True">
|
||||||
<Design.DataContext>
|
<Design.DataContext>
|
||||||
<viewModels:SettingsViewModel />
|
<viewModels:SettingsViewModel />
|
||||||
|
@ -16,6 +17,23 @@
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<helpers:KeyValueConverter x:Key="Key" />
|
<helpers:KeyValueConverter x:Key="Key" />
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
|
<UserControl.Styles>
|
||||||
|
<Style Selector="StackPanel > StackPanel">
|
||||||
|
<Setter Property="Margin" Value="10, 0, 0, 0" />
|
||||||
|
<Setter Property="Orientation" Value="Horizontal" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="StackPanel > StackPanel > TextBlock">
|
||||||
|
<Setter Property="VerticalAlignment" Value="Center" />
|
||||||
|
<Setter Property="Width" Value="230" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="ToggleButton">
|
||||||
|
<Setter Property="Width" Value="90" />
|
||||||
|
<Setter Property="Height" Value="27" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="ToggleButton > TextBlock">
|
||||||
|
<Setter Property="TextAlignment" Value="Center" />
|
||||||
|
</Style>
|
||||||
|
</UserControl.Styles>
|
||||||
<ScrollViewer
|
<ScrollViewer
|
||||||
Name="HotkeysPage"
|
Name="HotkeysPage"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
|
@ -23,78 +41,66 @@
|
||||||
HorizontalScrollBarVisibility="Disabled"
|
HorizontalScrollBarVisibility="Disabled"
|
||||||
VerticalScrollBarVisibility="Auto">
|
VerticalScrollBarVisibility="Auto">
|
||||||
<Border Classes="settings">
|
<Border Classes="settings">
|
||||||
<StackPanel Margin="10" Orientation="Vertical" Spacing="10">
|
<StackPanel
|
||||||
<TextBlock Classes="h1" Text="{locale:Locale SettingsTabHotkeysHotkeys}" />
|
Name="SettingButtons"
|
||||||
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
Margin="10"
|
||||||
<TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysToggleVsyncHotkey}" Width="230" />
|
Orientation="Vertical"
|
||||||
<ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
|
Spacing="10">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="{Binding KeyboardHotkeys.ToggleVsync, Mode=TwoWay, Converter={StaticResource Key}}"
|
Classes="h1"
|
||||||
TextAlignment="Center" />
|
Text="{locale:Locale SettingsTabHotkeysHotkeys}" />
|
||||||
|
<StackPanel>
|
||||||
|
<TextBlock Text="{locale:Locale SettingsTabHotkeysToggleVsyncHotkey}" />
|
||||||
|
<ToggleButton Name="ToggleVsync">
|
||||||
|
<TextBlock Text="{Binding KeyboardHotkey.ToggleVsync, Converter={StaticResource Key}}" />
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
<StackPanel>
|
||||||
<TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysScreenshotHotkey}" Width="230" />
|
<TextBlock Text="{locale:Locale SettingsTabHotkeysScreenshotHotkey}" />
|
||||||
<ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
|
<ToggleButton Name="Screenshot">
|
||||||
<TextBlock
|
<TextBlock Text="{Binding KeyboardHotkey.Screenshot, Converter={StaticResource Key}}" />
|
||||||
Text="{Binding KeyboardHotkeys.Screenshot, Mode=TwoWay, Converter={StaticResource Key}}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
<StackPanel>
|
||||||
<TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysShowUiHotkey}" Width="230" />
|
<TextBlock Text="{locale:Locale SettingsTabHotkeysShowUiHotkey}" />
|
||||||
<ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
|
<ToggleButton Name="ShowUI">
|
||||||
<TextBlock
|
<TextBlock Text="{Binding KeyboardHotkey.ShowUI, Converter={StaticResource Key}}" />
|
||||||
Text="{Binding KeyboardHotkeys.ShowUI, Mode=TwoWay, Converter={StaticResource Key}}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
<StackPanel>
|
||||||
<TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysPauseHotkey}" Width="230" />
|
<TextBlock Text="{locale:Locale SettingsTabHotkeysPauseHotkey}" />
|
||||||
<ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
|
<ToggleButton Name="Pause">
|
||||||
<TextBlock
|
<TextBlock Text="{Binding KeyboardHotkey.Pause, Converter={StaticResource Key}}" />
|
||||||
Text="{Binding KeyboardHotkeys.Pause, Mode=TwoWay, Converter={StaticResource Key}}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
<StackPanel>
|
||||||
<TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysToggleMuteHotkey}" Width="230" />
|
<TextBlock Text="{locale:Locale SettingsTabHotkeysToggleMuteHotkey}" />
|
||||||
<ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
|
<ToggleButton Name="ToggleMute">
|
||||||
<TextBlock
|
<TextBlock Text="{Binding KeyboardHotkey.ToggleMute, Converter={StaticResource Key}}" />
|
||||||
Text="{Binding KeyboardHotkeys.ToggleMute, Mode=TwoWay, Converter={StaticResource Key}}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
<StackPanel>
|
||||||
<TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysResScaleUpHotkey}" Width="230" />
|
<TextBlock Text="{locale:Locale SettingsTabHotkeysResScaleUpHotkey}" />
|
||||||
<ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
|
<ToggleButton Name="ResScaleUp">
|
||||||
<TextBlock
|
<TextBlock Text="{Binding KeyboardHotkey.ResScaleUp, Converter={StaticResource Key}}" />
|
||||||
Text="{Binding KeyboardHotkeys.ResScaleUp, Mode=TwoWay, Converter={StaticResource Key}}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
<StackPanel>
|
||||||
<TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysResScaleDownHotkey}" Width="230" />
|
<TextBlock Text="{locale:Locale SettingsTabHotkeysResScaleDownHotkey}" />
|
||||||
<ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
|
<ToggleButton Name="ResScaleDown">
|
||||||
<TextBlock
|
<TextBlock Text="{Binding KeyboardHotkey.ResScaleDown, Converter={StaticResource Key}}" />
|
||||||
Text="{Binding KeyboardHotkeys.ResScaleDown, Mode=TwoWay, Converter={StaticResource Key}}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
<StackPanel>
|
||||||
<TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysVolumeUpHotkey}" Width="230" />
|
<TextBlock Text="{locale:Locale SettingsTabHotkeysVolumeUpHotkey}" />
|
||||||
<ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
|
<ToggleButton Name="VolumeUp">
|
||||||
<TextBlock
|
<TextBlock Text="{Binding KeyboardHotkey.VolumeUp, Converter={StaticResource Key}}" />
|
||||||
Text="{Binding KeyboardHotkeys.VolumeUp, Mode=TwoWay, Converter={StaticResource Key}}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Margin="10,0,0,0" Orientation="Horizontal">
|
<StackPanel>
|
||||||
<TextBlock VerticalAlignment="Center" Text="{locale:Locale SettingsTabHotkeysVolumeDownHotkey}" Width="230" />
|
<TextBlock Text="{locale:Locale SettingsTabHotkeysVolumeDownHotkey}" />
|
||||||
<ToggleButton Width="90" Height="27" Checked="Button_Checked" Unchecked="Button_Unchecked">
|
<ToggleButton Name="VolumeDown">
|
||||||
<TextBlock
|
<TextBlock Text="{Binding KeyboardHotkey.VolumeDown, Converter={StaticResource Key}}" />
|
||||||
Text="{Binding KeyboardHotkeys.VolumeDown, Mode=TwoWay, Converter={StaticResource Key}}"
|
|
||||||
TextAlignment="Center" />
|
|
||||||
</ToggleButton>
|
</ToggleButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
|
@ -2,10 +2,13 @@ using Avalonia.Controls;
|
||||||
using Avalonia.Controls.Primitives;
|
using Avalonia.Controls.Primitives;
|
||||||
using Avalonia.Input;
|
using Avalonia.Input;
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
|
using Avalonia.LogicalTree;
|
||||||
using Ryujinx.Ava.Input;
|
using Ryujinx.Ava.Input;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Input;
|
using Ryujinx.Input;
|
||||||
using Ryujinx.Input.Assigner;
|
using Ryujinx.Input.Assigner;
|
||||||
|
using Key = Ryujinx.Common.Configuration.Hid.Key;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Views.Settings
|
namespace Ryujinx.Ava.UI.Views.Settings
|
||||||
{
|
{
|
||||||
|
@ -17,9 +20,28 @@ namespace Ryujinx.Ava.UI.Views.Settings
|
||||||
public SettingsHotkeysView()
|
public SettingsHotkeysView()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
|
foreach (ILogical visual in SettingButtons.GetLogicalDescendants())
|
||||||
|
{
|
||||||
|
if (visual is ToggleButton button and not CheckBox)
|
||||||
|
{
|
||||||
|
button.IsCheckedChanged += Button_IsCheckedChanged;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_avaloniaKeyboardDriver = new AvaloniaKeyboardDriver(this);
|
_avaloniaKeyboardDriver = new AvaloniaKeyboardDriver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnPointerReleased(PointerReleasedEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnPointerReleased(e);
|
||||||
|
|
||||||
|
if (!_currentAssigner?.ToggledButton?.IsPointerOver ?? false)
|
||||||
|
{
|
||||||
|
_currentAssigner.Cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void MouseClick(object sender, PointerPressedEventArgs e)
|
private void MouseClick(object sender, PointerPressedEventArgs e)
|
||||||
{
|
{
|
||||||
bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed;
|
bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed;
|
||||||
|
@ -29,53 +51,94 @@ namespace Ryujinx.Ava.UI.Views.Settings
|
||||||
PointerPressed -= MouseClick;
|
PointerPressed -= MouseClick;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Button_Checked(object sender, RoutedEventArgs e)
|
private void Button_IsCheckedChanged(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (sender is ToggleButton button)
|
if (sender is ToggleButton button)
|
||||||
{
|
{
|
||||||
if (_currentAssigner != null && button == _currentAssigner.ToggledButton)
|
if ((bool)button.IsChecked)
|
||||||
{
|
{
|
||||||
return;
|
if (_currentAssigner != null && button == _currentAssigner.ToggledButton)
|
||||||
}
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (_currentAssigner == null && button.IsChecked != null && (bool)button.IsChecked)
|
if (_currentAssigner == null)
|
||||||
{
|
{
|
||||||
_currentAssigner = new ButtonKeyAssigner(button);
|
_currentAssigner = new ButtonKeyAssigner(button);
|
||||||
|
|
||||||
this.Focus(NavigationMethod.Pointer);
|
this.Focus(NavigationMethod.Pointer);
|
||||||
|
|
||||||
PointerPressed += MouseClick;
|
PointerPressed += MouseClick;
|
||||||
|
|
||||||
var keyboard = (IKeyboard)_avaloniaKeyboardDriver.GetGamepad(_avaloniaKeyboardDriver.GamepadsIds[0]);
|
var keyboard = (IKeyboard)_avaloniaKeyboardDriver.GetGamepad("0");
|
||||||
IButtonAssigner assigner = new KeyboardKeyAssigner(keyboard);
|
IButtonAssigner assigner = new KeyboardKeyAssigner(keyboard);
|
||||||
|
|
||||||
_currentAssigner.GetInputAndAssign(assigner);
|
_currentAssigner.ButtonAssigned += (sender, e) =>
|
||||||
|
{
|
||||||
|
if (e.ButtonValue.HasValue)
|
||||||
|
{
|
||||||
|
var viewModel = (DataContext) as SettingsViewModel;
|
||||||
|
var buttonValue = e.ButtonValue.Value;
|
||||||
|
|
||||||
|
switch (button.Name)
|
||||||
|
{
|
||||||
|
case "ToggleVsync":
|
||||||
|
viewModel.KeyboardHotkey.ToggleVsync = buttonValue.AsHidType<Key>();
|
||||||
|
break;
|
||||||
|
case "Screenshot":
|
||||||
|
viewModel.KeyboardHotkey.Screenshot = buttonValue.AsHidType<Key>();
|
||||||
|
break;
|
||||||
|
case "ShowUI":
|
||||||
|
viewModel.KeyboardHotkey.ShowUI = buttonValue.AsHidType<Key>();
|
||||||
|
break;
|
||||||
|
case "Pause":
|
||||||
|
viewModel.KeyboardHotkey.Pause = buttonValue.AsHidType<Key>();
|
||||||
|
break;
|
||||||
|
case "ToggleMute":
|
||||||
|
viewModel.KeyboardHotkey.ToggleMute = buttonValue.AsHidType<Key>();
|
||||||
|
break;
|
||||||
|
case "ResScaleUp":
|
||||||
|
viewModel.KeyboardHotkey.ResScaleUp = buttonValue.AsHidType<Key>();
|
||||||
|
break;
|
||||||
|
case "ResScaleDown":
|
||||||
|
viewModel.KeyboardHotkey.ResScaleDown = buttonValue.AsHidType<Key>();
|
||||||
|
break;
|
||||||
|
case "VolumeUp":
|
||||||
|
viewModel.KeyboardHotkey.VolumeUp = buttonValue.AsHidType<Key>();
|
||||||
|
break;
|
||||||
|
case "VolumeDown":
|
||||||
|
viewModel.KeyboardHotkey.VolumeDown = buttonValue.AsHidType<Key>();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_currentAssigner.GetInputAndAssign(assigner, keyboard);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_currentAssigner != null)
|
||||||
|
{
|
||||||
|
_currentAssigner.Cancel();
|
||||||
|
_currentAssigner = null;
|
||||||
|
button.IsChecked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_currentAssigner != null)
|
_currentAssigner?.Cancel();
|
||||||
{
|
_currentAssigner = null;
|
||||||
ToggleButton oldButton = _currentAssigner.ToggledButton;
|
|
||||||
|
|
||||||
_currentAssigner.Cancel();
|
|
||||||
_currentAssigner = null;
|
|
||||||
|
|
||||||
button.IsChecked = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Button_Unchecked(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
_currentAssigner?.Cancel();
|
|
||||||
_currentAssigner = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_currentAssigner?.Cancel();
|
_currentAssigner?.Cancel();
|
||||||
_currentAssigner = null;
|
_currentAssigner = null;
|
||||||
|
|
||||||
|
_avaloniaKeyboardDriver.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,9 +27,9 @@
|
||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<views:ControllerInputView
|
<views:InputView
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Name="ControllerSettings" />
|
Name="InputView" />
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Orientation="Vertical"
|
Orientation="Vertical"
|
||||||
Grid.Row="2">
|
Grid.Row="2">
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace Ryujinx.Ava.UI.Views.Settings
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
ControllerSettings.Dispose();
|
InputView.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace Ryujinx.Ava.UI.Windows
|
||||||
|
|
||||||
public void SaveSettings()
|
public void SaveSettings()
|
||||||
{
|
{
|
||||||
InputPage.ControllerSettings?.SaveCurrentProfile();
|
InputPage.InputView?.SaveCurrentProfile();
|
||||||
|
|
||||||
if (Owner is MainWindow window && ViewModel.DirectoryChanged)
|
if (Owner is MainWindow window && ViewModel.DirectoryChanged)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue