diff --git a/CSharpManager/InputManager.cs b/CSharpManager/InputManager.cs index 70e97d6..533e082 100644 --- a/CSharpManager/InputManager.cs +++ b/CSharpManager/InputManager.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Runtime.InteropServices; using System.Text; using System.Threading; @@ -44,30 +43,68 @@ private void FindMainWindow() private void HandleKeys(List items) { var now = DateTime.Now.Ticks / 10000; - var modifiers = KeyUtils.Modifiers; + var currentModifiers = KeyUtils.Modifiers; + + var matchedItems = new List(); + + // 统计可能按下的按键 foreach (var item in items) { - if (item.Modifiers == modifiers && KeyUtils.IsKeyDown(item.Key) || - CurrentGamePadButton != GamePadButton.None && item.GamePadButton != GamePadButton.None && CurrentGamePadButton.HasFlag(item.GamePadButton)) + // 情况:组合键单独按下,多个组合键按下,多个组合键+普通键按下 + bool keyboardMatch = item.Modifiers == currentModifiers && ((item.Key == Key.None && currentModifiers != ModifierKeys.None) || KeyUtils.IsKeyDown(item.Key)); + // 任意多个手柄按键按下 + bool gamepadMatch = CurrentGamePadButton != GamePadButton.None && item.GamePadButton != GamePadButton.None && (CurrentGamePadButton & item.GamePadButton) == item.GamePadButton; + + if (keyboardMatch || gamepadMatch) + { + matchedItems.Add(item); + } + else if (item.IsPressed) + { + item.IsPressed = false; + } + } + + if (matchedItems.Count > 0) + { + // 获取最高复杂度 + int maxComplexity = KeyUtils.CountModifiers(matchedItems[0].Modifiers) + + KeyUtils.CountGamePadButtons(matchedItems[0].GamePadButton); + + foreach (var item in matchedItems) { - if (item.IsPressed && (item.RepeatMs == 0 || item.LastTriggerMs > 0 && now - item.LastTriggerMs < item.RepeatMs)) + // 获取当前复杂度 + int currentComplexity = KeyUtils.CountModifiers(item.Modifiers) + + KeyUtils.CountGamePadButtons(item.GamePadButton); + + // 比最高复杂度低的,忽略掉 + if (currentComplexity < maxComplexity) { - continue; + break; } - item.IsPressed = true; - if (item.RunOnGameThread) + + bool shouldTrigger = false; + if (!item.IsPressed || + (item.RepeatMs > 0 && item.LastTriggerMs > 0 && + now - item.LastTriggerMs >= item.RepeatMs)) { - Utils.TryRunOnGameThread(item.Action); + shouldTrigger = true; + item.IsPressed = true; + item.LastTriggerMs = now; } - else + + if (shouldTrigger) { - Utils.TryRun(item.Action); + if (item.RunOnGameThread) + { + Utils.TryRunOnGameThread(item.Action); + } + else + { + Utils.TryRun(item.Action); + } } } - else if (item.IsPressed) - { - item.IsPressed = false; - } } } @@ -77,10 +114,6 @@ public void Update() if (EnableGamePad) { GamePadUtils.GetGamePadButtons(out var buttons); - // if (buttons != GamePadButton.None) - // { - // GamePadButtonDown?.Invoke(new GamePadButtonEvent { Button = buttons }); - // } CurrentGamePadButton = buttons; } HandleKeys(BuiltinHotKeyItems); @@ -132,6 +165,7 @@ public HotKeyItem RegisterBuiltinKeyBind(Key key, Action action) { var item = new HotKeyItem(ModifierKeys.None, key, action); BuiltinHotKeyItems.Add(item); + SortHotKeys(BuiltinHotKeyItems); return item; } @@ -139,14 +173,26 @@ public HotKeyItem RegisterBuiltinKeyBind(ModifierKeys modifiers, Key key, Action { var item = new HotKeyItem(modifiers, key, action); BuiltinHotKeyItems.Add(item); + SortHotKeys(BuiltinHotKeyItems); return item; } + private void SortHotKeys(List items) + { + items.Sort((a, b) => + { + int aComplexity = KeyUtils.CountModifiers(a.Modifiers) + KeyUtils.CountGamePadButtons(a.GamePadButton); + int bComplexity = KeyUtils.CountModifiers(b.Modifiers) + KeyUtils.CountGamePadButtons(b.GamePadButton); + return bComplexity.CompareTo(aComplexity); + }); + } + public void RegisterKeyBind(HotKeyItem item) { lock (HotKeyItems) { HotKeyItems.Add(item); + SortHotKeys(HotKeyItems); } } diff --git a/CSharpModBase/Input/KeyUtils.cs b/CSharpModBase/Input/KeyUtils.cs index 1f2618b..aff495d 100644 --- a/CSharpModBase/Input/KeyUtils.cs +++ b/CSharpModBase/Input/KeyUtils.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Runtime.InteropServices; @@ -65,6 +66,27 @@ public static bool IsKeyDown(Key key) return GetKeyState((uint)key) < 0; } + public static int CountModifiers(ModifierKeys modifiers) + { + int count = 0; + if ((modifiers & ModifierKeys.Control) != 0) count++; + if ((modifiers & ModifierKeys.Alt) != 0) count++; + if ((modifiers & ModifierKeys.Shift) != 0) count++; + return count; + } + public static int CountGamePadButtons(GamePadButton keys) + { + int count = 0; + foreach (GamePadButton button in Enum.GetValues(typeof(GamePadButton))) + { + if (button != GamePadButton.None && (keys & button) == button) + { + count++; + } + } + return count; + } + public static ModifierKeys Modifiers { get