From ceb64cedb05039433563ef5048c2ace31780c274 Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Wed, 4 May 2022 00:28:26 +1000 Subject: [PATCH] Finish `MergeLAndRModifierKeys` UX (resolves #3184) --- .../config/ConfigExtensions.cs | 16 ++++++++++++++++ src/BizHawk.Client.EmuHawk/Input/Input.cs | 13 ++++++++++--- .../config/EmuHawkOptions.Designer.cs | 15 ++++++++++++++- .../config/EmuHawkOptions.cs | 15 +++++++++++++++ .../Extensions/StringExtensions.cs | 8 ++++++++ 5 files changed, 63 insertions(+), 4 deletions(-) mode change 100644 => 100755 src/BizHawk.Client.EmuHawk/config/EmuHawkOptions.Designer.cs diff --git a/src/BizHawk.Client.Common/config/ConfigExtensions.cs b/src/BizHawk.Client.Common/config/ConfigExtensions.cs index 5041dc497e..65da878185 100644 --- a/src/BizHawk.Client.Common/config/ConfigExtensions.cs +++ b/src/BizHawk.Client.Common/config/ConfigExtensions.cs @@ -1,5 +1,10 @@ using System; +using System.Collections.Generic; +using System.Linq; + +using BizHawk.Common.StringExtensions; using BizHawk.Emulation.Common; + using Newtonsoft.Json.Linq; namespace BizHawk.Client.Common @@ -136,6 +141,17 @@ namespace BizHawk.Client.Common config.PutCoreSyncSettings(o, typeof(TCore)); } + public static void ReplaceKeysInBindings(this Config config, IReadOnlyDictionary replMap) + { + string ReplMulti(string multiBind) + => multiBind.TransformFields(',', bind => bind.TransformFields('+', button => replMap.TryGetValue(button, out var repl) ? repl : button)); + foreach (var hotkeyBinding in config.HotkeyBindings.Bindings) hotkeyBinding.Bindings = ReplMulti(hotkeyBinding.Bindings); + foreach (var bindCollection in new[] { config.AllTrollers, config.AllTrollersAutoFire }) // analog and feedback binds can only be bound to (host) gamepads, not keyboard + { + foreach (var k in bindCollection.Keys.ToArray()) bindCollection[k] = bindCollection[k].ToDictionary(static kvp => kvp.Key, kvp => ReplMulti(kvp.Value)); + } + } + /// file extension, including the leading period and in lowercase /// will be if returned value is public static bool TryGetChosenSystemForFileExt(this Config config, string fileExt, out string systemID) diff --git a/src/BizHawk.Client.EmuHawk/Input/Input.cs b/src/BizHawk.Client.EmuHawk/Input/Input.cs index 584901d2c9..f59a62e47a 100644 --- a/src/BizHawk.Client.EmuHawk/Input/Input.cs +++ b/src/BizHawk.Client.EmuHawk/Input/Input.cs @@ -42,7 +42,6 @@ namespace BizHawk.Client.EmuHawk { _getConfigCallback = getConfigCallback; _currentConfig = _getConfigCallback(); - _currentConfig.MergeLAndRModifierKeys = true; // for debugging UpdateModifierKeysEffective(); MainFormInputAllowedCallback = mainFormInputAllowedCallback; @@ -81,7 +80,7 @@ namespace BizHawk.Client.EmuHawk .Concat(_currentConfig.ModifierKeys) .Take(32).ToArray(); - private readonly IReadOnlyDictionary _modifierKeyPreMap = new Dictionary + internal static readonly IReadOnlyDictionary ModifierKeyPreMap = new Dictionary { ["LeftSuper"] = "Win", ["RightSuper"] = "Win", @@ -93,9 +92,17 @@ namespace BizHawk.Client.EmuHawk ["RightShift"] = "Shift", }; + internal static readonly IReadOnlyDictionary ModifierKeyInvPreMap = new Dictionary + { + ["Super"] = "LeftWin", + ["Ctrl"] = "LeftCtrl", + ["Alt"] = "LeftAlt", + ["Shift"] = "LeftShift", + }; + private void HandleButton(string button, bool newState, ClientInputFocus source) { - if (!(_currentConfig.MergeLAndRModifierKeys &&_modifierKeyPreMap.TryGetValue(button, out var button1))) button1 = button; + if (!(_currentConfig.MergeLAndRModifierKeys && ModifierKeyPreMap.TryGetValue(button, out var button1))) button1 = button; var modIndex = _currentConfig.ModifierKeysEffective.IndexOf(button1); var currentModifier = modIndex is -1 ? 0U : 1U << modIndex; if (EnableIgnoreModifiers && currentModifier is not 0U) return; diff --git a/src/BizHawk.Client.EmuHawk/config/EmuHawkOptions.Designer.cs b/src/BizHawk.Client.EmuHawk/config/EmuHawkOptions.Designer.cs old mode 100644 new mode 100755 index ce2c8a85f7..4da1a22080 --- a/src/BizHawk.Client.EmuHawk/config/EmuHawkOptions.Designer.cs +++ b/src/BizHawk.Client.EmuHawk/config/EmuHawkOptions.Designer.cs @@ -78,6 +78,7 @@ this.BackupSRamCheckbox = new System.Windows.Forms.CheckBox(); this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); this.locLabelEx1 = new BizHawk.WinForms.Controls.LocLabelEx(); + this.cbMergeLAndRModifierKeys = new System.Windows.Forms.CheckBox(); this.tabControl1.SuspendLayout(); this.tabPage1.SuspendLayout(); this.groupBox3.SuspendLayout(); @@ -126,6 +127,7 @@ // // tabPage1 // + this.tabPage1.Controls.Add(this.cbMergeLAndRModifierKeys); this.tabPage1.Controls.Add(this.HandleAlternateKeyboardLayoutsCheckBox); this.tabPage1.Controls.Add(this.NeverAskSaveCheckbox); this.tabPage1.Controls.Add(this.label2); @@ -281,7 +283,7 @@ this.groupBox1.Controls.Add(this.StartFullScreenCheckbox); this.groupBox1.Controls.Add(this.label3); this.groupBox1.Controls.Add(this.SingleInstanceModeCheckbox); - this.groupBox1.Location = new System.Drawing.Point(6, 205); + this.groupBox1.Location = new System.Drawing.Point(6, 221); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(369, 133); this.groupBox1.TabIndex = 15; @@ -573,6 +575,16 @@ this.locLabelEx1.Name = "locLabelEx1"; this.locLabelEx1.Text = "Note: Only a tiny subset of commandline args work (incl. rom path)"; // + // cbMergeLAndRModifierKeys + // + this.cbMergeLAndRModifierKeys.AutoSize = true; + this.cbMergeLAndRModifierKeys.Location = new System.Drawing.Point(7, 202); + this.cbMergeLAndRModifierKeys.Name = "cbMergeLAndRModifierKeys"; + this.cbMergeLAndRModifierKeys.Size = new System.Drawing.Size(320, 17); + this.cbMergeLAndRModifierKeys.TabIndex = 29; + this.cbMergeLAndRModifierKeys.Text = "Merge L+R modifier keys e.g. Shift instead of LShift and RShift"; + this.cbMergeLAndRModifierKeys.UseVisualStyleBackColor = true; + // // EmuHawkOptions // this.AcceptButton = this.OkBtn; @@ -657,5 +669,6 @@ private System.Windows.Forms.CheckBox SingleInstanceModeCheckbox; private System.Windows.Forms.CheckBox NoMixedKeyPriorityCheckBox; private WinForms.Controls.LocLabelEx locLabelEx1; + private System.Windows.Forms.CheckBox cbMergeLAndRModifierKeys; } } diff --git a/src/BizHawk.Client.EmuHawk/config/EmuHawkOptions.cs b/src/BizHawk.Client.EmuHawk/config/EmuHawkOptions.cs index 72abe2197e..ef1251ce80 100644 --- a/src/BizHawk.Client.EmuHawk/config/EmuHawkOptions.cs +++ b/src/BizHawk.Client.EmuHawk/config/EmuHawkOptions.cs @@ -70,6 +70,7 @@ namespace BizHawk.Client.EmuHawk AcceptBackgroundInputControllerOnlyCheckBox.Checked = _config.AcceptBackgroundInputControllerOnly; HandleAlternateKeyboardLayoutsCheckBox.Checked = _config.HandleAlternateKeyboardLayouts; NeverAskSaveCheckbox.Checked = _config.SuppressAskSave; + cbMergeLAndRModifierKeys.Checked = _config.MergeLAndRModifierKeys; SingleInstanceModeCheckbox.Checked = _config.SingleInstanceMode; SingleInstanceModeCheckbox.Enabled = !OSTailoredCode.IsUnixHost; @@ -110,6 +111,19 @@ namespace BizHawk.Client.EmuHawk private void OkBtn_Click(object sender, EventArgs e) { + if (cbMergeLAndRModifierKeys.Checked != _config.MergeLAndRModifierKeys) + { + var merging = cbMergeLAndRModifierKeys.Checked; + var result = MessageBox.Show( + this, + text: $"Would you like to replace {(merging ? "LShift and RShift with Shift" : "Shift with LShift")},\nand the same for the other modifier keys,\nin existing keybinds for hotkeys and all systems' gamepads?", + caption: "Rewrite keybinds now?", + MessageBoxButtons.YesNoCancel, + MessageBoxIcon.Question); + if (result is DialogResult.Cancel) return; + if (result is DialogResult.Yes) _config.ReplaceKeysInBindings(merging ? Input.ModifierKeyPreMap : Input.ModifierKeyInvPreMap); + } + _config.StartFullscreen = StartFullScreenCheckbox.Checked; _config.StartPaused = StartPausedCheckbox.Checked; _config.PauseWhenMenuActivated = PauseWhenMenuActivatedCheckbox.Checked; @@ -120,6 +134,7 @@ namespace BizHawk.Client.EmuHawk _config.AcceptBackgroundInputControllerOnly = AcceptBackgroundInputControllerOnlyCheckBox.Checked; _config.HandleAlternateKeyboardLayouts = HandleAlternateKeyboardLayoutsCheckBox.Checked; _config.SuppressAskSave = NeverAskSaveCheckbox.Checked; + _config.MergeLAndRModifierKeys = cbMergeLAndRModifierKeys.Checked; _config.SingleInstanceMode = SingleInstanceModeCheckbox.Checked; if(rbInputMethodDirectInput.Checked) _config.HostInputMethod = EHostInputMethod.DirectInput; if(rbInputMethodOpenTK.Checked) _config.HostInputMethod = EHostInputMethod.OpenTK; diff --git a/src/BizHawk.Common/Extensions/StringExtensions.cs b/src/BizHawk.Common/Extensions/StringExtensions.cs index 3859caf2fa..cde93e7122 100644 --- a/src/BizHawk.Common/Extensions/StringExtensions.cs +++ b/src/BizHawk.Common/Extensions/StringExtensions.cs @@ -116,5 +116,13 @@ namespace BizHawk.Common.StringExtensions var index = str.IndexOf(delimiter); return index < 0 ? null : str.Substring(0, index); } + + /// + /// splits a given by , + /// applies to each part, then rejoins them + /// + /// "abc,def,ghi".TransformFields(',', s => s.Reverse()) == "cba,fed,ihg" + public static string TransformFields(this string str, char delimiter, Func transform) + => string.Join(delimiter.ToString(), str.Split(delimiter).Select(transform)); } }