using System; using System.Collections.Generic; using Dalamud.Game.ClientState.GamePad; using Dalamud.Game.ClientState.Keys; using Dalamud.Plugin.Services; using HSUI.Config; using HSUI.Interface.GeneralElements; namespace HSUI.Helpers { /// Polls controller bar keybinds and executes slots when keys/buttons are pressed. Supports combinations (e.g. L2+South). public static class ControllerBarKeybindExecutor { private static readonly Dictionary _triggerWasDown = new Dictionary(); public static void Process(IFramework framework) { try { if (!ControllerHotbarsConfig.GetEffectiveControllerHotbarsEnabled()) return; var keybindsConfig = ConfigurationManager.Instance?.GetConfigObject(); if (keybindsConfig == null) return; if (ActionBarsManager.Instance == null) return; for (int bar = 1; bar <= ControllerBarKeybindsConfig.Bars; bar++) { for (int slot = 0; slot < ControllerBarKeybindsConfig.SlotsPerBar; slot++) { string binding = keybindsConfig.GetKeybind(bar, slot); if (string.IsNullOrEmpty(binding)) continue; bool triggered = IsKeybindTriggered(binding); if (triggered) ActionBarsManager.Instance.ExecuteControllerSlot(bar, slot); } } } catch (Exception ex) { Plugin.Logger?.Warning($"[HSUI ControllerBarKeybinds] Process: {ex.Message}"); } } /// True when all modifiers are held and the trigger key/button was just pressed (edge). private static bool IsKeybindTriggered(string binding) { if (string.IsNullOrEmpty(binding)) return false; string[] parts = binding.Split('+'); for (int i = 0; i < parts.Length; i++) parts[i] = parts[i].Trim(); if (parts.Length == 0) return false; if (parts.Length == 1) { bool down = IsSingleKeybindDown(parts[0]); if (!_triggerWasDown.TryGetValue(binding, out bool wasDown)) wasDown = false; _triggerWasDown[binding] = down; return down && !wasDown; } string triggerPart = parts[parts.Length - 1]; for (int i = 0; i < parts.Length - 1; i++) { if (!IsSingleKeybindDown(parts[i])) return false; } bool triggerDown = IsSingleKeybindDown(triggerPart); if (!_triggerWasDown.TryGetValue(binding, out bool triggerWasDown)) triggerWasDown = false; _triggerWasDown[binding] = triggerDown; return triggerDown && !triggerWasDown; } private static bool IsSingleKeybindDown(string part) { if (string.IsNullOrEmpty(part)) return false; if (part.StartsWith("Key:", StringComparison.OrdinalIgnoreCase)) { string vkStr = part.Substring(4).Trim(); if (Plugin.KeyState == null) return false; if (Enum.TryParse(vkStr, true, out var vk) && Plugin.KeyState.IsVirtualKeyValid((int)vk)) return Plugin.KeyState[vk]; return false; } if (part.StartsWith("Pad:", StringComparison.OrdinalIgnoreCase)) { string padStr = part.Substring(4).Trim(); if (Plugin.GamepadState == null) return false; if (Enum.TryParse(padStr, true, out var btn)) return Plugin.GamepadState.Raw(btn) > 0.5f; return false; } return false; } } }