mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-04-24 00:17:44 +02:00
Merge branch 'Master_PR' into 'master'
Improved interaction with "Input" settings. See merge request ryubing/ryujinx!4
This commit is contained in:
commit
6b7946377c
13 changed files with 520 additions and 83 deletions
|
@ -21,6 +21,11 @@ namespace Ryujinx.Common.Configuration.Hid
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Controller name
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Controller's Type
|
/// Controller's Type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -49,7 +49,6 @@
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Classes="globalConfigMarker"/>
|
Classes="globalConfigMarker"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
</Border>
|
</Border>
|
||||||
</Design.PreviewWith>
|
</Design.PreviewWith>
|
||||||
<Style Selector="DropDownButton">
|
<Style Selector="DropDownButton">
|
||||||
|
|
|
@ -6997,6 +6997,31 @@
|
||||||
"zh_TW": "輸入裝置"
|
"zh_TW": "輸入裝置"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ID": "ControllerSettingsWaitingConnectDevice",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "",
|
||||||
|
"de_DE": "",
|
||||||
|
"el_GR": "",
|
||||||
|
"en_US": "Configuration found:\n\nName:\t{0}\nGUID:\t{1}\n\n Waiting for controller connection...",
|
||||||
|
"es_ES": "",
|
||||||
|
"fr_FR": "",
|
||||||
|
"he_IL": "",
|
||||||
|
"it_IT": "",
|
||||||
|
"ja_JP": "",
|
||||||
|
"ko_KR": "",
|
||||||
|
"no_NO": "",
|
||||||
|
"pl_PL": "",
|
||||||
|
"pt_BR": "",
|
||||||
|
"ru_RU": "",
|
||||||
|
"sv_SE": "",
|
||||||
|
"th_TH": "",
|
||||||
|
"tr_TR": "",
|
||||||
|
"uk_UA": "",
|
||||||
|
"zh_CN": "",
|
||||||
|
"zh_TW": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ID": "ControllerSettingsRefresh",
|
"ID": "ControllerSettingsRefresh",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
|
@ -7297,6 +7322,81 @@
|
||||||
"zh_TW": "新增"
|
"zh_TW": "新增"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ID": "ControllerSettingsModifiedNotification",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "(تم التعديل!)",
|
||||||
|
"de_DE": "(modifiziert!)",
|
||||||
|
"el_GR": "(τροποποιημένο!)",
|
||||||
|
"en_US": "(Modified!)",
|
||||||
|
"es_ES": "(modificado!)",
|
||||||
|
"fr_FR": "(modifié!)",
|
||||||
|
"he_IL": "(שונה!)",
|
||||||
|
"it_IT": "(modificato!)",
|
||||||
|
"ja_JP": "(変更済み!)",
|
||||||
|
"ko_KR": "(수정됨!)",
|
||||||
|
"no_NO": "(modifisert!)",
|
||||||
|
"pl_PL": "(zmodyfikowane!)",
|
||||||
|
"pt_BR": "(modificado!)",
|
||||||
|
"ru_RU": "(изменено!)",
|
||||||
|
"sv_SE": "(ändrad!)",
|
||||||
|
"th_TH": "(แก้ไขแล้ว!)",
|
||||||
|
"tr_TR": "(değiştirildi!)",
|
||||||
|
"uk_UA": "(модифіковано!)",
|
||||||
|
"zh_CN": "(已修改!)",
|
||||||
|
"zh_TW": "(已修改!)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "ControllerSettingsDisableDeviceForSaving",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "تم إعداد التحكم.\n\nفي انتظار اتصال وحدة التحكم...",
|
||||||
|
"de_DE": "Steuerung konfiguriert.\n\nWarten auf die Verbindung des Controllers...",
|
||||||
|
"el_GR": "Η διαχείριση έχει ρυθμιστεί.\n\nΑναμένεται σύνδεση του χειριστηρίου...",
|
||||||
|
"en_US": "Control configured.\n\nWaiting for controller connection...",
|
||||||
|
"es_ES": "Control configurado.\n\nEsperando la conexión del controlador...",
|
||||||
|
"fr_FR": "Contrôle configuré.\n\nEn attente de la connexion du contrôleur...",
|
||||||
|
"he_IL": "השליטה הוגדרה.\n\nממתין לחיבור הבקר...",
|
||||||
|
"it_IT": "Controllo configurato.\n\nIn attesa della connessione del controller...",
|
||||||
|
"ja_JP": "コントロールが設定されました。\n\nコントローラーの接続を待っています...",
|
||||||
|
"ko_KR": "제어가 설정되었습니다.\n\n컨트롤러 연결 대기 중...",
|
||||||
|
"no_NO": "Kontroll konfigurert.\n\nVenter på tilkobling av kontroller...",
|
||||||
|
"pl_PL": "Sterowanie skonfigurowane.\n\nOczekiwanie na połączenie kontrolera...",
|
||||||
|
"pt_BR": "Controle configurado.\n\nAguardando conexão do controle...",
|
||||||
|
"ru_RU": "Управление настроено.\n\nОжидается подключение контроллера...",
|
||||||
|
"sv_SE": "Kontroll konfigurerad.\n\nVäntar på anslutning av kontrollen...",
|
||||||
|
"th_TH": "การควบคุมได้รับการตั้งค่าแล้ว\n\nกำลังรอการเชื่อมต่อคอนโทรลเลอร์...",
|
||||||
|
"tr_TR": "Kontrol yapılandırıldı.\n\nKontrolcü bağlantısı bekleniyor...",
|
||||||
|
"uk_UA": "Керування налаштовано.\n\nОчікується підключення контролера...",
|
||||||
|
"zh_CN": "控制已配置。\n\n等待控制器连接...",
|
||||||
|
"zh_TW": "控制已設定。\n\n等待控制器連接..."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ID": "ControllerSettingsUnlink",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "إلغاء الربط",
|
||||||
|
"de_DE": "Entkoppeln",
|
||||||
|
"el_GR": "Αποσύνδεση",
|
||||||
|
"en_US": "Unlink",
|
||||||
|
"es_ES": "Desvincular",
|
||||||
|
"fr_FR": "Dissocier",
|
||||||
|
"he_IL": "ניתוק קישור",
|
||||||
|
"it_IT": "Scollega",
|
||||||
|
"ja_JP": "リンク解除",
|
||||||
|
"ko_KR": "연결 해제",
|
||||||
|
"no_NO": "Frakoble",
|
||||||
|
"pl_PL": "Odłącz",
|
||||||
|
"pt_BR": "Desvincular",
|
||||||
|
"ru_RU": "Отвязать",
|
||||||
|
"sv_SE": "Koppla från",
|
||||||
|
"th_TH": "ยกเลิกการเชื่อมโยง",
|
||||||
|
"tr_TR": "Bağlantıyı Kes",
|
||||||
|
"uk_UA": "Відв'язати",
|
||||||
|
"zh_CN": "解除绑定",
|
||||||
|
"zh_TW": "解除綁定"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ID": "ControllerSettingsRemove",
|
"ID": "ControllerSettingsRemove",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
|
@ -11947,6 +12047,31 @@
|
||||||
"zh_TW": "儲存設定檔"
|
"zh_TW": "儲存設定檔"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ID": "ControllerSettingsCancelCurrentChangesToolTip",
|
||||||
|
"Translations": {
|
||||||
|
"ar_SA": "إلغاء التغييرات الحالية",
|
||||||
|
"de_DE": "Aktuelle Änderungen abbrechen",
|
||||||
|
"el_GR": "Ακύρωση τρεχουσών αλλαγών",
|
||||||
|
"en_US": "Cancel current changes",
|
||||||
|
"es_ES": "Cancelar los cambios actuales",
|
||||||
|
"fr_FR": "Annuler les modifications en cours",
|
||||||
|
"he_IL": "ביטול השינויים הנוכחיים",
|
||||||
|
"it_IT": "Annulla le modifiche correnti",
|
||||||
|
"ja_JP": "現在の変更をキャンセル",
|
||||||
|
"ko_KR": "현재 변경 취소",
|
||||||
|
"no_NO": "Avbryt gjeldende endringer",
|
||||||
|
"pl_PL": "Anuluj bieżące zmiany",
|
||||||
|
"pt_BR": "Cancelar alterações atuais",
|
||||||
|
"ru_RU": "Отменить текущие изменения",
|
||||||
|
"sv_SE": "Avbryt aktuella ändringar",
|
||||||
|
"th_TH": "ยกเลิกการเปลี่ยนแปลงปัจจุบัน",
|
||||||
|
"tr_TR": "Geçerli değişiklikleri iptal et",
|
||||||
|
"uk_UA": "Скасувати поточні зміни",
|
||||||
|
"zh_CN": "取消当前更改",
|
||||||
|
"zh_TW": "取消當前變更"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ID": "MenuBarFileToolsTakeScreenshot",
|
"ID": "MenuBarFileToolsTakeScreenshot",
|
||||||
"Translations": {
|
"Translations": {
|
||||||
|
|
|
@ -274,6 +274,7 @@ namespace Ryujinx.Ava.Systems.Configuration
|
||||||
Version = InputConfig.CurrentVersion,
|
Version = InputConfig.CurrentVersion,
|
||||||
Backend = InputBackendType.WindowKeyboard,
|
Backend = InputBackendType.WindowKeyboard,
|
||||||
Id = "0",
|
Id = "0",
|
||||||
|
Name = "Keyboard",
|
||||||
PlayerIndex = PlayerIndex.Player1,
|
PlayerIndex = PlayerIndex.Player1,
|
||||||
ControllerType = ControllerType.ProController,
|
ControllerType = ControllerType.ProController,
|
||||||
LeftJoycon = new LeftJoyconCommonConfig<Key>
|
LeftJoycon = new LeftJoyconCommonConfig<Key>
|
||||||
|
|
|
@ -22,6 +22,8 @@ namespace Ryujinx.Ava.UI.Models.Input
|
||||||
public float StrongRumble { get; set; }
|
public float StrongRumble { get; set; }
|
||||||
|
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
public ControllerType ControllerType { get; set; }
|
public ControllerType ControllerType { get; set; }
|
||||||
public PlayerIndex PlayerIndex { get; set; }
|
public PlayerIndex PlayerIndex { get; set; }
|
||||||
|
|
||||||
|
@ -111,6 +113,7 @@ namespace Ryujinx.Ava.UI.Models.Input
|
||||||
if (config != null)
|
if (config != null)
|
||||||
{
|
{
|
||||||
Id = config.Id;
|
Id = config.Id;
|
||||||
|
Name = config.Name;
|
||||||
ControllerType = config.ControllerType;
|
ControllerType = config.ControllerType;
|
||||||
PlayerIndex = config.PlayerIndex;
|
PlayerIndex = config.PlayerIndex;
|
||||||
|
|
||||||
|
@ -201,6 +204,7 @@ namespace Ryujinx.Ava.UI.Models.Input
|
||||||
StandardControllerInputConfig config = new()
|
StandardControllerInputConfig config = new()
|
||||||
{
|
{
|
||||||
Id = Id,
|
Id = Id,
|
||||||
|
Name = Name,
|
||||||
Backend = InputBackendType.GamepadSDL2,
|
Backend = InputBackendType.GamepadSDL2,
|
||||||
PlayerIndex = PlayerIndex,
|
PlayerIndex = PlayerIndex,
|
||||||
ControllerType = ControllerType,
|
ControllerType = ControllerType,
|
||||||
|
|
|
@ -2,12 +2,14 @@ using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Common.Configuration.Hid;
|
using Ryujinx.Common.Configuration.Hid;
|
||||||
using Ryujinx.Common.Configuration.Hid.Keyboard;
|
using Ryujinx.Common.Configuration.Hid.Keyboard;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
namespace Ryujinx.Ava.UI.Models.Input
|
namespace Ryujinx.Ava.UI.Models.Input
|
||||||
{
|
{
|
||||||
public partial class KeyboardInputConfig : BaseModel
|
public partial class KeyboardInputConfig : BaseModel
|
||||||
{
|
{
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
public ControllerType ControllerType { get; set; }
|
public ControllerType ControllerType { get; set; }
|
||||||
public PlayerIndex PlayerIndex { get; set; }
|
public PlayerIndex PlayerIndex { get; set; }
|
||||||
|
|
||||||
|
@ -53,6 +55,7 @@ namespace Ryujinx.Ava.UI.Models.Input
|
||||||
if (config != null)
|
if (config != null)
|
||||||
{
|
{
|
||||||
Id = config.Id;
|
Id = config.Id;
|
||||||
|
Name = config.Name;
|
||||||
ControllerType = config.ControllerType;
|
ControllerType = config.ControllerType;
|
||||||
PlayerIndex = config.PlayerIndex;
|
PlayerIndex = config.PlayerIndex;
|
||||||
|
|
||||||
|
@ -100,6 +103,7 @@ namespace Ryujinx.Ava.UI.Models.Input
|
||||||
StandardKeyboardInputConfig config = new()
|
StandardKeyboardInputConfig config = new()
|
||||||
{
|
{
|
||||||
Id = Id,
|
Id = Id,
|
||||||
|
Name = Name,
|
||||||
Backend = InputBackendType.WindowKeyboard,
|
Backend = InputBackendType.WindowKeyboard,
|
||||||
PlayerIndex = PlayerIndex,
|
PlayerIndex = PlayerIndex,
|
||||||
ControllerType = ControllerType,
|
ControllerType = ControllerType,
|
||||||
|
|
|
@ -93,16 +93,19 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
public async void ShowMotionConfig()
|
public async void ShowMotionConfig()
|
||||||
{
|
{
|
||||||
await MotionInputView.Show(this);
|
await MotionInputView.Show(this);
|
||||||
|
ParentModel.IsModified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void ShowRumbleConfig()
|
public async void ShowRumbleConfig()
|
||||||
{
|
{
|
||||||
await RumbleInputView.Show(this);
|
await RumbleInputView.Show(this);
|
||||||
|
ParentModel.IsModified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void ShowLedConfig()
|
public async void ShowLedConfig()
|
||||||
{
|
{
|
||||||
await LedInputView.Show(this);
|
await LedInputView.Show(this);
|
||||||
|
ParentModel.IsModified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnParentModelChanged()
|
public void OnParentModelChanged()
|
||||||
|
|
|
@ -51,6 +51,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
private int _device;
|
private int _device;
|
||||||
private object _configViewModel;
|
private object _configViewModel;
|
||||||
[ObservableProperty] private string _profileName;
|
[ObservableProperty] private string _profileName;
|
||||||
|
[ObservableProperty] private bool _notificationIsVisible; // Automatically call the NotificationView property with OnPropertyChanged()
|
||||||
|
[ObservableProperty] private string _notificationText; // Automatically call the NotificationText property with OnPropertyChanged()
|
||||||
private bool _isLoaded;
|
private bool _isLoaded;
|
||||||
|
|
||||||
private static readonly InputConfigJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
|
private static readonly InputConfigJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions());
|
||||||
|
@ -88,13 +90,40 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
public bool IsKeyboard => !IsController;
|
public bool IsKeyboard => !IsController;
|
||||||
public bool IsRight { get; set; }
|
public bool IsRight { get; set; }
|
||||||
public bool IsLeft { get; set; }
|
public bool IsLeft { get; set; }
|
||||||
|
public string RevertDeviceId { get; set; }
|
||||||
public bool HasLed => SelectedGamepad.Features.HasFlag(GamepadFeaturesFlag.Led);
|
public bool HasLed => SelectedGamepad.Features.HasFlag(GamepadFeaturesFlag.Led);
|
||||||
public bool CanClearLed => SelectedGamepad.Name.ContainsIgnoreCase("DualSense");
|
public bool CanClearLed => SelectedGamepad.Name.ContainsIgnoreCase("DualSense");
|
||||||
|
|
||||||
public bool IsModified { get; set; }
|
public bool _isChangeTrackingActive;
|
||||||
|
|
||||||
|
public bool _isModified;
|
||||||
|
|
||||||
|
public bool IsModified
|
||||||
|
{
|
||||||
|
get => _isModified;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_isModified = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public event Action NotifyChangesEvent;
|
public event Action NotifyChangesEvent;
|
||||||
|
|
||||||
|
public string _profileChoose;
|
||||||
|
public string ProfileChoose
|
||||||
|
{
|
||||||
|
get => _profileChoose;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
// When you select a profile, the settings from the profile will be applied.
|
||||||
|
// To save the settings, you still need to click the apply button
|
||||||
|
_profileChoose = value;
|
||||||
|
LoadProfile();
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public object ConfigViewModel
|
public object ConfigViewModel
|
||||||
{
|
{
|
||||||
get => _configViewModel;
|
get => _configViewModel;
|
||||||
|
@ -121,13 +150,13 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
{
|
{
|
||||||
if (IsModified)
|
if (IsModified)
|
||||||
{
|
{
|
||||||
|
|
||||||
_playerIdChoose = value;
|
_playerIdChoose = value;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IsModified = false;
|
IsModified = false;
|
||||||
_playerId = value;
|
_playerId = value;
|
||||||
|
_isChangeTrackingActive = false;
|
||||||
|
|
||||||
if (!Enum.IsDefined<PlayerIndex>(_playerId))
|
if (!Enum.IsDefined<PlayerIndex>(_playerId))
|
||||||
{
|
{
|
||||||
|
@ -135,13 +164,13 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
|
|
||||||
}
|
}
|
||||||
_isLoaded = false;
|
_isLoaded = false;
|
||||||
|
|
||||||
LoadConfiguration();
|
LoadConfiguration();
|
||||||
LoadDevice();
|
LoadDevice();
|
||||||
LoadProfiles();
|
LoadProfiles();
|
||||||
|
|
||||||
|
RevertDeviceId = Devices[Device].Id;
|
||||||
_isLoaded = true;
|
_isLoaded = true;
|
||||||
|
_isChangeTrackingActive = true;
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,6 +180,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
get => _controller;
|
get => _controller;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
MarkAsChanged();
|
||||||
|
|
||||||
_controller = value;
|
_controller = value;
|
||||||
|
|
||||||
if (_controller == -1)
|
if (_controller == -1)
|
||||||
|
@ -229,6 +260,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
get => _device;
|
get => _device;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
MarkAsChanged();
|
||||||
|
|
||||||
_device = value < 0 ? 0 : value;
|
_device = value < 0 ? 0 : value;
|
||||||
|
|
||||||
if (_device >= Devices.Count)
|
if (_device >= Devices.Count)
|
||||||
|
@ -248,11 +281,13 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FindPairedDeviceInConfigFile();
|
||||||
OnPropertyChanged();
|
OnPropertyChanged();
|
||||||
NotifyChanges();
|
NotifyChanges();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public InputConfig Config { get; set; }
|
public InputConfig Config { get; set; }
|
||||||
|
|
||||||
public InputViewModel(UserControl owner) : this()
|
public InputViewModel(UserControl owner) : this()
|
||||||
|
@ -274,6 +309,8 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
|
|
||||||
PlayerId = PlayerIndex.Player1;
|
PlayerId = PlayerIndex.Player1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_isChangeTrackingActive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputViewModel()
|
public InputViewModel()
|
||||||
|
@ -311,8 +348,50 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
{
|
{
|
||||||
ConfigViewModel = new ControllerInputViewModel(this, new GamepadInputConfig(controllerInputConfig), VisualStick);
|
ConfigViewModel = new ControllerInputViewModel(this, new GamepadInputConfig(controllerInputConfig), VisualStick);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FindPairedDeviceInConfigFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void FindPairedDeviceInConfigFile()
|
||||||
|
{
|
||||||
|
// This function allows you to output a message about the device configuration found in the file
|
||||||
|
// NOTE: if the configuration is found, we display the message "Waiting for controller connection",
|
||||||
|
// but only if the id gamepad belongs to the selected player
|
||||||
|
NotificationIsVisible = Config != null && Devices.FirstOrDefault(d => d.Id == Config.Id).Id != Config.Id && Config.PlayerIndex == PlayerId;
|
||||||
|
if (NotificationIsVisible)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(Config.Name))
|
||||||
|
{
|
||||||
|
NotificationText = $"{LocaleManager.Instance[LocaleKeys.ControllerSettingsWaitingConnectDevice].Format("No information", Config.Id)}";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NotificationText = $"{LocaleManager.Instance[LocaleKeys.ControllerSettingsWaitingConnectDevice].Format(Config.Name, Config.Id)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void MarkAsChanged()
|
||||||
|
{
|
||||||
|
//If tracking is active, then allow changing the modifier
|
||||||
|
if (!IsModified && _isChangeTrackingActive)
|
||||||
|
{
|
||||||
|
RevertDeviceId = Devices[Device].Id; // Remember the device to undo changes
|
||||||
|
IsModified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void UnlinkDevice()
|
||||||
|
{
|
||||||
|
// "Disabled" mode is available after unbinding the device
|
||||||
|
// NOTE: the IsModified flag to be able to apply the settings.
|
||||||
|
NotificationIsVisible = false;
|
||||||
|
IsModified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void LoadDevice()
|
public void LoadDevice()
|
||||||
{
|
{
|
||||||
if (Config == null || Config.Backend == InputBackendType.Invalid)
|
if (Config == null || Config.Backend == InputBackendType.Invalid)
|
||||||
|
@ -378,14 +457,34 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleOnGamepadDisconnected(string id)
|
private async void HandleOnGamepadDisconnected(string id)
|
||||||
{
|
{
|
||||||
Dispatcher.UIThread.Post(LoadDevices);
|
_isChangeTrackingActive = false; // Disable configuration change tracking
|
||||||
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
||||||
|
{
|
||||||
|
LoadDevices();
|
||||||
|
|
||||||
|
IsModified = true;
|
||||||
|
RevertChanges();
|
||||||
|
FindPairedDeviceInConfigFile();
|
||||||
|
|
||||||
|
_isChangeTrackingActive = true; // Enable configuration change tracking
|
||||||
|
return System.Threading.Tasks.Task.CompletedTask;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleOnGamepadConnected(string id)
|
private async void HandleOnGamepadConnected(string id)
|
||||||
{
|
{
|
||||||
Dispatcher.UIThread.Post(LoadDevices);
|
_isChangeTrackingActive = false; // Disable configuration change tracking
|
||||||
|
await Dispatcher.UIThread.InvokeAsync(() =>
|
||||||
|
{
|
||||||
|
LoadDevices();
|
||||||
|
|
||||||
|
IsModified = true;
|
||||||
|
RevertChanges();
|
||||||
|
|
||||||
|
_isChangeTrackingActive = true;// Enable configuration change tracking
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GetCurrentGamepadId()
|
private string GetCurrentGamepadId()
|
||||||
|
@ -558,12 +657,14 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
if (activeDevice.Type == DeviceType.Keyboard)
|
if (activeDevice.Type == DeviceType.Keyboard)
|
||||||
{
|
{
|
||||||
string id = activeDevice.Id;
|
string id = activeDevice.Id;
|
||||||
|
string name = activeDevice.Name;
|
||||||
|
|
||||||
config = new StandardKeyboardInputConfig
|
config = new StandardKeyboardInputConfig
|
||||||
{
|
{
|
||||||
Version = InputConfig.CurrentVersion,
|
Version = InputConfig.CurrentVersion,
|
||||||
Backend = InputBackendType.WindowKeyboard,
|
Backend = InputBackendType.WindowKeyboard,
|
||||||
Id = id,
|
Id = id,
|
||||||
|
Name = name,
|
||||||
ControllerType = ControllerType.ProController,
|
ControllerType = ControllerType.ProController,
|
||||||
LeftJoycon = new LeftJoyconCommonConfig<Key>
|
LeftJoycon = new LeftJoyconCommonConfig<Key>
|
||||||
{
|
{
|
||||||
|
@ -613,12 +714,14 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
bool isNintendoStyle = Devices.ToList().FirstOrDefault(x => x.Id == activeDevice.Id).Name.Contains("Nintendo");
|
bool isNintendoStyle = Devices.ToList().FirstOrDefault(x => x.Id == activeDevice.Id).Name.Contains("Nintendo");
|
||||||
|
|
||||||
string id = activeDevice.Id.Split(" ")[0];
|
string id = activeDevice.Id.Split(" ")[0];
|
||||||
|
string name = activeDevice.Name;
|
||||||
|
|
||||||
config = new StandardControllerInputConfig
|
config = new StandardControllerInputConfig
|
||||||
{
|
{
|
||||||
Version = InputConfig.CurrentVersion,
|
Version = InputConfig.CurrentVersion,
|
||||||
Backend = InputBackendType.GamepadSDL2,
|
Backend = InputBackendType.GamepadSDL2,
|
||||||
Id = id,
|
Id = id,
|
||||||
|
Name = name,
|
||||||
ControllerType = ControllerType.ProController,
|
ControllerType = ControllerType.ProController,
|
||||||
DeadzoneLeft = 0.1f,
|
DeadzoneLeft = 0.1f,
|
||||||
DeadzoneRight = 0.1f,
|
DeadzoneRight = 0.1f,
|
||||||
|
@ -688,6 +791,12 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void LoadProfileButton()
|
||||||
|
{
|
||||||
|
LoadProfile();
|
||||||
|
IsModified = true;
|
||||||
|
}
|
||||||
|
|
||||||
public async void LoadProfile()
|
public async void LoadProfile()
|
||||||
{
|
{
|
||||||
if (Device == 0)
|
if (Device == 0)
|
||||||
|
@ -739,9 +848,11 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
{
|
{
|
||||||
_isLoaded = false;
|
_isLoaded = false;
|
||||||
|
|
||||||
|
config.Id = Config.Id; // Set current device id instead of changing device(independent profiles)
|
||||||
|
|
||||||
LoadConfiguration(config);
|
LoadConfiguration(config);
|
||||||
|
|
||||||
LoadDevice();
|
//LoadDevice(); This line of code hard-links profiles to controllers, the commented line allows profiles to be applied to all controllers
|
||||||
|
|
||||||
_isLoaded = true;
|
_isLoaded = true;
|
||||||
|
|
||||||
|
@ -751,6 +862,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
|
|
||||||
public async void SaveProfile()
|
public async void SaveProfile()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (Device == 0)
|
if (Device == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -793,12 +905,15 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
await File.WriteAllTextAsync(path, jsonString);
|
await File.WriteAllTextAsync(path, jsonString);
|
||||||
|
|
||||||
LoadProfiles();
|
LoadProfiles();
|
||||||
|
|
||||||
|
ProfileChoose = ProfileName; // Show new profile
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogProfileInvalidProfileNameErrorMessage]);
|
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogProfileInvalidProfileNameErrorMessage]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void RemoveProfile()
|
public async void RemoveProfile()
|
||||||
|
@ -825,13 +940,32 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadProfiles();
|
LoadProfiles();
|
||||||
|
|
||||||
|
ProfileChoose = ProfilesList[0].ToString(); // Show default profile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RevertChanges()
|
||||||
|
{
|
||||||
|
Device = Devices.ToList().FindIndex(d => d.Id == RevertDeviceId);
|
||||||
|
LoadDevice();
|
||||||
|
LoadConfiguration();
|
||||||
|
OnPropertyChanged();
|
||||||
|
IsModified = false;
|
||||||
|
}
|
||||||
|
|
||||||
public void Save()
|
public void Save()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (!IsModified)
|
||||||
|
{
|
||||||
|
return; //If the input settings were not touched, then do nothing
|
||||||
|
}
|
||||||
|
|
||||||
IsModified = false;
|
IsModified = false;
|
||||||
|
|
||||||
|
RevertDeviceId = Devices[Device].Id; // Remember selected device after saving
|
||||||
|
|
||||||
List <InputConfig> newConfig = [];
|
List <InputConfig> newConfig = [];
|
||||||
|
|
||||||
newConfig.AddRange(ConfigurationState.Instance.Hid.InputConfig.Value);
|
newConfig.AddRange(ConfigurationState.Instance.Hid.InputConfig.Value);
|
||||||
|
@ -862,6 +996,7 @@ namespace Ryujinx.Ava.UI.ViewModels.Input
|
||||||
: (ConfigViewModel as ControllerInputViewModel).Config.GetConfig();
|
: (ConfigViewModel as ControllerInputViewModel).Config.GetConfig();
|
||||||
config.ControllerType = Controllers[_controller].Type;
|
config.ControllerType = Controllers[_controller].Type;
|
||||||
config.PlayerIndex = _playerId;
|
config.PlayerIndex = _playerId;
|
||||||
|
config.Name = device.Name;
|
||||||
|
|
||||||
int i = newConfig.FindIndex(x => x.PlayerIndex == PlayerId);
|
int i = newConfig.FindIndex(x => x.PlayerIndex == PlayerId);
|
||||||
if (i == -1)
|
if (i == -1)
|
||||||
|
|
|
@ -65,7 +65,8 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||||
|
|
||||||
if (!float.IsNaN(_changeSlider) && _changeSlider != (float)check.Value)
|
if (!float.IsNaN(_changeSlider) && _changeSlider != (float)check.Value)
|
||||||
{
|
{
|
||||||
(DataContext as ControllerInputViewModel)!.ParentModel.IsModified = true;
|
FlagInputConfigChanged();
|
||||||
|
|
||||||
_changeSlider = (float)check.Value;
|
_changeSlider = (float)check.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,7 +76,8 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||||
{
|
{
|
||||||
if (sender is CheckBox { IsPointerOver: true })
|
if (sender is CheckBox { IsPointerOver: true })
|
||||||
{
|
{
|
||||||
(DataContext as ControllerInputViewModel)!.ParentModel.IsModified = true;
|
FlagInputConfigChanged();
|
||||||
|
|
||||||
_currentAssigner?.Cancel();
|
_currentAssigner?.Cancel();
|
||||||
_currentAssigner = null;
|
_currentAssigner = null;
|
||||||
}
|
}
|
||||||
|
@ -115,7 +117,7 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||||
if (e.ButtonValue.HasValue)
|
if (e.ButtonValue.HasValue)
|
||||||
{
|
{
|
||||||
Button buttonValue = e.ButtonValue.Value;
|
Button buttonValue = e.ButtonValue.Value;
|
||||||
viewModel.ParentModel.IsModified = true;
|
FlagInputConfigChanged();
|
||||||
|
|
||||||
switch (button.Name)
|
switch (button.Name)
|
||||||
{
|
{
|
||||||
|
@ -209,6 +211,11 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void FlagInputConfigChanged()
|
||||||
|
{
|
||||||
|
(DataContext as ControllerInputViewModel)!.ParentModel.IsModified = true;
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
@ -232,7 +239,6 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||||
{
|
{
|
||||||
gamepad?.ClearLed();
|
gamepad?.ClearLed();
|
||||||
}
|
}
|
||||||
|
|
||||||
_currentAssigner?.Cancel();
|
_currentAssigner?.Cancel();
|
||||||
_currentAssigner = null;
|
_currentAssigner = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,13 +41,20 @@
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
Margin="2"
|
Margin="2"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
VerticalAlignment="Center" ColumnDefinitions="Auto,*">
|
VerticalAlignment="Center" ColumnDefinitions="Auto,*,Auto">
|
||||||
<TextBlock
|
<StackPanel
|
||||||
|
Orientation="Vertical"
|
||||||
Margin="5,0,10,0"
|
Margin="5,0,10,0"
|
||||||
Width="90"
|
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
|
Width="90">
|
||||||
|
<TextBlock
|
||||||
Text="{ext:Locale ControllerSettingsPlayer}" />
|
Text="{ext:Locale ControllerSettingsPlayer}" />
|
||||||
|
<TextBlock
|
||||||
|
Classes="pending"
|
||||||
|
Text ="{ext:Locale ControllerSettingsModifiedNotification}"
|
||||||
|
IsVisible="{Binding IsModified}"/>
|
||||||
|
</StackPanel>
|
||||||
<ComboBox
|
<ComboBox
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Name="PlayerIndexBox"
|
Name="PlayerIndexBox"
|
||||||
|
@ -62,6 +69,18 @@
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ComboBox.ItemTemplate>
|
</ComboBox.ItemTemplate>
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
|
<Button
|
||||||
|
Grid.Column="2"
|
||||||
|
MinWidth="0"
|
||||||
|
Margin="5,0,0,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
ToolTip.Tip="{ext:Locale ControllerSettingsCancelCurrentChangesToolTip}"
|
||||||
|
Command="{Binding RevertChanges}">
|
||||||
|
<ui:SymbolIcon
|
||||||
|
Symbol="Undo"
|
||||||
|
FontSize="15"
|
||||||
|
Height="20" />
|
||||||
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
<!-- Profile Selection -->
|
<!-- Profile Selection -->
|
||||||
<Grid
|
<Grid
|
||||||
|
@ -81,7 +100,8 @@
|
||||||
Name="ProfileBox"
|
Name="ProfileBox"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
SelectedIndex="0"
|
SelectedItem="{Binding ProfileChoose, Mode=TwoWay}"
|
||||||
|
SelectionChanged="ComboBox_SelectionChanged"
|
||||||
ItemsSource="{Binding ProfilesList}"
|
ItemsSource="{Binding ProfilesList}"
|
||||||
Text="{Binding ProfileName, Mode=TwoWay}" />
|
Text="{Binding ProfileName, Mode=TwoWay}" />
|
||||||
<Button
|
<Button
|
||||||
|
@ -90,7 +110,7 @@
|
||||||
Margin="5,0,0,0"
|
Margin="5,0,0,0"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
ToolTip.Tip="{ext:Locale ControllerSettingsLoadProfileToolTip}"
|
ToolTip.Tip="{ext:Locale ControllerSettingsLoadProfileToolTip}"
|
||||||
Command="{Binding LoadProfile}">
|
Command="{Binding LoadProfileButton}">
|
||||||
<ui:SymbolIcon
|
<ui:SymbolIcon
|
||||||
Symbol="View"
|
Symbol="View"
|
||||||
FontSize="15"
|
FontSize="15"
|
||||||
|
@ -148,7 +168,7 @@
|
||||||
MinWidth="0"
|
MinWidth="0"
|
||||||
Margin="5,0,0,0"
|
Margin="5,0,0,0"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Command="{Binding LoadDevices}">
|
Command="{Binding LoadDevice}">
|
||||||
<ui:SymbolIcon
|
<ui:SymbolIcon
|
||||||
Symbol="Refresh"
|
Symbol="Refresh"
|
||||||
FontSize="15"
|
FontSize="15"
|
||||||
|
@ -181,6 +201,28 @@
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
<ContentControl IsVisible="{Binding NotificationIsVisible}">
|
||||||
|
<ContentControl.Content>
|
||||||
|
|
||||||
|
<StackPanel>
|
||||||
|
<TextBlock
|
||||||
|
Margin="5,20,0,0"
|
||||||
|
Text="{Binding NotificationText}" />
|
||||||
|
<Button
|
||||||
|
MinWidth="0"
|
||||||
|
Width="90"
|
||||||
|
Height="27"
|
||||||
|
Margin="0,10,0,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Command="{Binding UnlinkDevice}">
|
||||||
|
<TextBlock
|
||||||
|
Text="{ext:Locale ControllerSettingsUnlink}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
HorizontalAlignment="Center" />
|
||||||
|
</Button>
|
||||||
|
</StackPanel>
|
||||||
|
</ContentControl.Content>
|
||||||
|
</ContentControl>
|
||||||
<ContentControl Content="{Binding ConfigViewModel}" IsVisible="{Binding ShowSettings}">
|
<ContentControl Content="{Binding ConfigViewModel}" IsVisible="{Binding ShowSettings}">
|
||||||
<ContentControl.DataTemplates>
|
<ContentControl.DataTemplates>
|
||||||
<DataTemplate DataType="viewModels:ControllerInputViewModel">
|
<DataTemplate DataType="viewModels:ControllerInputViewModel">
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Avalonia.Controls;
|
using Avalonia.Controls;
|
||||||
|
using FluentAvalonia.UI.Controls;
|
||||||
using Ryujinx.Ava.Common.Locale;
|
using Ryujinx.Ava.Common.Locale;
|
||||||
using Ryujinx.Ava.UI.Controls;
|
using Ryujinx.Ava.UI.Controls;
|
||||||
using Ryujinx.Ava.UI.Helpers;
|
using Ryujinx.Ava.UI.Helpers;
|
||||||
|
@ -63,13 +64,22 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ViewModel.IsModified = false;
|
||||||
ViewModel.PlayerId = ViewModel.PlayerIdChoose;
|
ViewModel.PlayerId = ViewModel.PlayerIdChoose;
|
||||||
|
|
||||||
ViewModel.IsModified = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is FAComboBox faComboBox)
|
||||||
|
{
|
||||||
|
faComboBox.IsDropDownOpen = false;
|
||||||
|
ViewModel.IsModified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
ViewModel.Dispose();
|
ViewModel.Dispose();
|
||||||
|
|
|
@ -9,6 +9,8 @@ using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.ViewModels.Input;
|
using Ryujinx.Ava.UI.ViewModels.Input;
|
||||||
using Ryujinx.Input;
|
using Ryujinx.Input;
|
||||||
using Ryujinx.Input.Assigner;
|
using Ryujinx.Input.Assigner;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System;
|
||||||
using Button = Ryujinx.Input.Button;
|
using Button = Ryujinx.Input.Button;
|
||||||
using Key = Ryujinx.Common.Configuration.Hid.Key;
|
using Key = Ryujinx.Common.Configuration.Hid.Key;
|
||||||
|
|
||||||
|
@ -186,11 +188,63 @@ namespace Ryujinx.Ava.UI.Views.Input
|
||||||
{
|
{
|
||||||
bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed;
|
bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed;
|
||||||
|
|
||||||
|
bool shouldRemoveBinding = e.GetCurrentPoint(this).Properties.IsRightButtonPressed;
|
||||||
|
|
||||||
|
if (shouldRemoveBinding)
|
||||||
|
{
|
||||||
|
DeleteBind();
|
||||||
|
}
|
||||||
|
|
||||||
_currentAssigner?.Cancel(shouldUnbind);
|
_currentAssigner?.Cancel(shouldUnbind);
|
||||||
|
|
||||||
PointerPressed -= MouseClick;
|
PointerPressed -= MouseClick;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DeleteBind()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (_currentAssigner != null)
|
||||||
|
{
|
||||||
|
Dictionary<string, Action> buttonActions = new Dictionary<string, Action>
|
||||||
|
{
|
||||||
|
{ "ButtonZl", () => ViewModel.Config.ButtonZl = Key.Unbound },
|
||||||
|
{ "ButtonL", () => ViewModel.Config.ButtonL = Key.Unbound },
|
||||||
|
{ "ButtonMinus", () => ViewModel.Config.ButtonMinus = Key.Unbound },
|
||||||
|
{ "LeftStickButton", () => ViewModel.Config.LeftStickButton = Key.Unbound },
|
||||||
|
{ "LeftStickUp", () => ViewModel.Config.LeftStickUp = Key.Unbound },
|
||||||
|
{ "LeftStickDown", () => ViewModel.Config.LeftStickDown = Key.Unbound },
|
||||||
|
{ "LeftStickRight", () => ViewModel.Config.LeftStickRight = Key.Unbound },
|
||||||
|
{ "LeftStickLeft", () => ViewModel.Config.LeftStickLeft = Key.Unbound },
|
||||||
|
{ "DpadUp", () => ViewModel.Config.DpadUp = Key.Unbound },
|
||||||
|
{ "DpadDown", () => ViewModel.Config.DpadDown = Key.Unbound },
|
||||||
|
{ "DpadLeft", () => ViewModel.Config.DpadLeft = Key.Unbound },
|
||||||
|
{ "DpadRight", () => ViewModel.Config.DpadRight = Key.Unbound },
|
||||||
|
{ "LeftButtonSr", () => ViewModel.Config.LeftButtonSr = Key.Unbound },
|
||||||
|
{ "LeftButtonSl", () => ViewModel.Config.LeftButtonSl = Key.Unbound },
|
||||||
|
{ "RightButtonSr", () => ViewModel.Config.RightButtonSr = Key.Unbound },
|
||||||
|
{ "RightButtonSl", () => ViewModel.Config.RightButtonSl = Key.Unbound },
|
||||||
|
{ "ButtonZr", () => ViewModel.Config.ButtonZr = Key.Unbound },
|
||||||
|
{ "ButtonR", () => ViewModel.Config.ButtonR = Key.Unbound },
|
||||||
|
{ "ButtonPlus", () => ViewModel.Config.ButtonPlus = Key.Unbound },
|
||||||
|
{ "ButtonA", () => ViewModel.Config.ButtonA = Key.Unbound },
|
||||||
|
{ "ButtonB", () => ViewModel.Config.ButtonB = Key.Unbound },
|
||||||
|
{ "ButtonX", () => ViewModel.Config.ButtonX = Key.Unbound },
|
||||||
|
{ "ButtonY", () => ViewModel.Config.ButtonY = Key.Unbound },
|
||||||
|
{ "RightStickButton", () => ViewModel.Config.RightStickButton = Key.Unbound },
|
||||||
|
{ "RightStickUp", () => ViewModel.Config.RightStickUp = Key.Unbound },
|
||||||
|
{ "RightStickDown", () => ViewModel.Config.RightStickDown = Key.Unbound },
|
||||||
|
{ "RightStickRight", () => ViewModel.Config.RightStickRight = Key.Unbound },
|
||||||
|
{ "RightStickLeft", () => ViewModel.Config.RightStickLeft = Key.Unbound }
|
||||||
|
};
|
||||||
|
|
||||||
|
if (buttonActions.TryGetValue(_currentAssigner.ToggledButton.Name, out Action action))
|
||||||
|
{
|
||||||
|
action();
|
||||||
|
ViewModel.ParentModel.IsModified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
|
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnDetachedFromVisualTree(e);
|
base.OnDetachedFromVisualTree(e);
|
||||||
|
|
|
@ -10,6 +10,8 @@ using Ryujinx.Ava.UI.Helpers;
|
||||||
using Ryujinx.Ava.UI.ViewModels;
|
using Ryujinx.Ava.UI.ViewModels;
|
||||||
using Ryujinx.Input;
|
using Ryujinx.Input;
|
||||||
using Ryujinx.Input.Assigner;
|
using Ryujinx.Input.Assigner;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System;
|
||||||
using Button = Ryujinx.Input.Button;
|
using Button = Ryujinx.Input.Button;
|
||||||
using Key = Ryujinx.Common.Configuration.Hid.Key;
|
using Key = Ryujinx.Common.Configuration.Hid.Key;
|
||||||
|
|
||||||
|
@ -45,6 +47,51 @@ namespace Ryujinx.Ava.UI.Views.Settings
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void MouseClick(object sender, PointerPressedEventArgs e)
|
||||||
|
{
|
||||||
|
bool shouldUnbind = e.GetCurrentPoint(this).Properties.IsMiddleButtonPressed;
|
||||||
|
bool shouldRemoveBinding = e.GetCurrentPoint(this).Properties.IsRightButtonPressed;
|
||||||
|
|
||||||
|
if (shouldRemoveBinding)
|
||||||
|
{
|
||||||
|
DeleteBind();
|
||||||
|
}
|
||||||
|
|
||||||
|
_currentAssigner?.Cancel(shouldUnbind);
|
||||||
|
|
||||||
|
PointerPressed -= MouseClick;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeleteBind()
|
||||||
|
{
|
||||||
|
if (DataContext is not SettingsViewModel viewModel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_currentAssigner != null)
|
||||||
|
{
|
||||||
|
Dictionary<string, Action> buttonActions = new Dictionary<string, Action>
|
||||||
|
{
|
||||||
|
{ "ToggleVSyncMode", () => viewModel.KeyboardHotkey.ToggleVSyncMode = Key.Unbound },
|
||||||
|
{ "Screenshot", () => viewModel.KeyboardHotkey.Screenshot = Key.Unbound },
|
||||||
|
{ "ShowUI", () => viewModel.KeyboardHotkey.ShowUI = Key.Unbound },
|
||||||
|
{ "Pause", () => viewModel.KeyboardHotkey.Pause = Key.Unbound },
|
||||||
|
{ "ToggleMute", () => viewModel.KeyboardHotkey.ToggleMute = Key.Unbound },
|
||||||
|
{ "ResScaleUp", () => viewModel.KeyboardHotkey.ResScaleUp = Key.Unbound },
|
||||||
|
{ "ResScaleDown", () => viewModel.KeyboardHotkey.ResScaleDown = Key.Unbound },
|
||||||
|
{ "VolumeUp", () => viewModel.KeyboardHotkey.VolumeUp = Key.Unbound },
|
||||||
|
{ "VolumeDown", () => viewModel.KeyboardHotkey.VolumeDown = Key.Unbound },
|
||||||
|
{ "CustomVSyncIntervalIncrement", () => viewModel.KeyboardHotkey.CustomVSyncIntervalIncrement = Key.Unbound },
|
||||||
|
{ "CustomVSyncIntervalDecrement", () => viewModel.KeyboardHotkey.CustomVSyncIntervalDecrement = Key.Unbound },
|
||||||
|
{ "TurboMode", () => viewModel.KeyboardHotkey.TurboMode = Key.Unbound }
|
||||||
|
};
|
||||||
|
|
||||||
|
if (buttonActions.TryGetValue(_currentAssigner.ToggledButton.Name, out Action action))
|
||||||
|
{
|
||||||
|
action();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void Button_IsCheckedChanged(object sender, RoutedEventArgs e)
|
private void Button_IsCheckedChanged(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (sender is ToggleButton button)
|
if (sender is ToggleButton button)
|
||||||
|
@ -62,6 +109,8 @@ namespace Ryujinx.Ava.UI.Views.Settings
|
||||||
|
|
||||||
this.Focus(NavigationMethod.Pointer);
|
this.Focus(NavigationMethod.Pointer);
|
||||||
|
|
||||||
|
PointerPressed += MouseClick;
|
||||||
|
|
||||||
IKeyboard keyboard = (IKeyboard)_avaloniaKeyboardDriver.GetGamepad("0");
|
IKeyboard keyboard = (IKeyboard)_avaloniaKeyboardDriver.GetGamepad("0");
|
||||||
IButtonAssigner assigner = new KeyboardKeyAssigner(keyboard);
|
IButtonAssigner assigner = new KeyboardKeyAssigner(keyboard);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue