You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
416 lines
12 KiB
416 lines
12 KiB
-- Press Key to select option
|
|
|
|
|
|
local _, addon = ...
|
|
local API = addon.API;
|
|
local Clipboard = addon.Clipboard;
|
|
|
|
|
|
local DEFAULT_CONTROL_KEY = "SPACE";
|
|
local GAMEPAD_CONFIRM = "PAD1";
|
|
local GAMEPAD_CANCEL = "PAD2";
|
|
local GAMEPAD_ALT = "PAD4";
|
|
|
|
|
|
-- Custom Settings
|
|
local ENABLE_KEYCONTROL_IN_COMBAT = true;
|
|
local PRIMARY_CONTROL_KEY = DEFAULT_CONTROL_KEY;
|
|
local USE_INTERACT_KEY = false;
|
|
local DISABLE_CONTROL_KEY = false; --If true, pressing the key (Space) will not continue quest
|
|
local TTS_HOTKEY_ENABLED = false;
|
|
local DEBUG_SHOW_GAMEPAD_BUTTON = false; --[TEMP] Console user
|
|
------------------
|
|
|
|
local InCombatLockdown = InCombatLockdown;
|
|
local IsModifierKeyDown = IsModifierKeyDown;
|
|
local tostring = tostring;
|
|
local type = type;
|
|
|
|
local KeyboardControl = CreateFrame("Frame");
|
|
KeyboardControl:Hide();
|
|
KeyboardControl:SetFrameStrata("TOOLTIP");
|
|
KeyboardControl:SetFixedFrameStrata(true);
|
|
addon.KeyboardControl = KeyboardControl;
|
|
|
|
KeyboardControl.noPropagateFrame = CreateFrame("Frame", nil, KeyboardControl);
|
|
KeyboardControl.noPropagateFrame:SetPropagateKeyboardInput(false);
|
|
|
|
function KeyboardControl:ResetKeyActions()
|
|
self.keyActions = {};
|
|
end
|
|
KeyboardControl:ResetKeyActions()
|
|
|
|
function KeyboardControl:CanSetKey(key)
|
|
if key then
|
|
if type(key) == "number" then
|
|
return key <= 9
|
|
else
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
function KeyboardControl:SetKeyFunction(key, func)
|
|
if not self:CanSetKey(key) then return end;
|
|
|
|
key = tostring(key);
|
|
|
|
if not self.keyActions[key] then
|
|
self.keyActions[key] = {
|
|
obj = func,
|
|
type = "function",
|
|
};
|
|
return key
|
|
end
|
|
end
|
|
|
|
function KeyboardControl:SetKeyButton(key, buttonToClick)
|
|
if key == "PRIMARY" then
|
|
key = PRIMARY_CONTROL_KEY;
|
|
end
|
|
|
|
if not self:CanSetKey(key) then return end;
|
|
|
|
key = tostring(key)
|
|
|
|
if not self.keyActions[key] then
|
|
self.keyActions[key] = {
|
|
obj = buttonToClick,
|
|
type = "button",
|
|
};
|
|
return key
|
|
end
|
|
end
|
|
|
|
function KeyboardControl:OnEvent(event, ...)
|
|
if event == "PLAYER_REGEN_DISABLED" then
|
|
self:RegisterEvent("PLAYER_REGEN_ENABLED");
|
|
elseif event == "PLAYER_REGEN_ENABLED" then
|
|
if self:IsVisible() then
|
|
|
|
end
|
|
elseif event == "UPDATE_BINDINGS" then
|
|
self.bindingDirty = true;
|
|
end
|
|
end
|
|
KeyboardControl:SetScript("OnEvent", KeyboardControl.OnEvent);
|
|
|
|
function KeyboardControl:OnHide()
|
|
self:StopListeningKeys();
|
|
self:UnregisterEvent("PLAYER_REGEN_DISABLED");
|
|
self:UnregisterEvent("PLAYER_REGEN_ENABLED");
|
|
self:ResetKeyActions();
|
|
self:StopRepeatingAction();
|
|
end
|
|
KeyboardControl:SetScript("OnHide", KeyboardControl.OnHide);
|
|
|
|
function KeyboardControl:OnShow()
|
|
self:RegisterEvent("PLAYER_REGEN_DISABLED");
|
|
|
|
if self.bindingDirty then
|
|
self.bindingDirty = nil;
|
|
if USE_INTERACT_KEY then
|
|
local newKey = API.GetBestInteractKey();
|
|
if newKey and newKey ~= PRIMARY_CONTROL_KEY then
|
|
PRIMARY_CONTROL_KEY = newKey;
|
|
addon.DialogueUI:OnSettingsChanged();
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
KeyboardControl:SetScript("OnShow", KeyboardControl.OnShow);
|
|
|
|
function KeyboardControl:OnKeyDown(key, fromGamePad)
|
|
local valid = false;
|
|
local processed = false;
|
|
|
|
if key == GAMEPAD_CONFIRM then
|
|
valid = KeyboardControl.parent:ClickFocusedObject();
|
|
if valid then
|
|
processed = true;
|
|
else
|
|
key = PRIMARY_CONTROL_KEY;
|
|
end
|
|
else
|
|
if DISABLE_CONTROL_KEY and key == PRIMARY_CONTROL_KEY then
|
|
key = "DISABLED";
|
|
processed = true;
|
|
valid = false;
|
|
end
|
|
end
|
|
|
|
|
|
if (not processed) and (key == PRIMARY_CONTROL_KEY) and (not KeyboardControl.keyActions[key]) then
|
|
key = "1";
|
|
end
|
|
|
|
if key == "ESCAPE" then
|
|
valid = true;
|
|
|
|
if Clipboard:IsShown() then
|
|
Clipboard:Hide();
|
|
processed = true;
|
|
elseif addon.SettingsUI:IsShown() then
|
|
addon.SettingsUI:Hide();
|
|
processed = true;
|
|
else
|
|
if fromGamePad then
|
|
|
|
else
|
|
if KeyboardControl.parent.HideUI then
|
|
local cancelPopupFirst = true;
|
|
KeyboardControl.parent:HideUI(cancelPopupFirst);
|
|
processed = true;
|
|
else
|
|
KeyboardControl.parent:Hide();
|
|
processed = true;
|
|
end
|
|
end
|
|
end
|
|
elseif key == "GAMEPAD_UP" then
|
|
valid = true;
|
|
processed = true;
|
|
KeyboardControl.parent:FocusPreviousObject();
|
|
elseif key == "GAMEPAD_DOWN" then
|
|
valid = true;
|
|
processed = true;
|
|
KeyboardControl.parent:FocusNextObject();
|
|
elseif key == "F1" then
|
|
valid = true;
|
|
processed = true;
|
|
addon.SettingsUI:ToggleUI();
|
|
elseif (key == "R" and not IsModifierKeyDown()) then
|
|
if TTS_HOTKEY_ENABLED then
|
|
valid = true;
|
|
processed = true;
|
|
addon.TTSUtil:ToggleSpeaking();
|
|
end
|
|
end
|
|
|
|
if (not processed) and KeyboardControl.keyActions[key] then
|
|
valid = true;
|
|
|
|
local actionType = KeyboardControl.keyActions[key].type;
|
|
local object = KeyboardControl.keyActions[key].obj;
|
|
|
|
if actionType == "function" then
|
|
object();
|
|
elseif actionType == "button" then
|
|
if object:IsEnabled() and object:IsVisible() then
|
|
local noFeedback = object:OnClick("GamePad");
|
|
if (not noFeedback) and object.PlayKeyFeedback then
|
|
object:PlayKeyFeedback();
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if not InCombatLockdown() then
|
|
KeyboardControl:SetPropagateKeyboardInput(not valid);
|
|
end
|
|
end
|
|
|
|
function KeyboardControl:SetParentFrame(frame)
|
|
self.parent = frame;
|
|
self:SetParent(frame);
|
|
self:Show();
|
|
|
|
self:StopListeningKeys();
|
|
|
|
local listener;
|
|
|
|
if InCombatLockdown() then
|
|
if ENABLE_KEYCONTROL_IN_COMBAT then
|
|
listener = self.noPropagateFrame;
|
|
end
|
|
else
|
|
listener = self;
|
|
end
|
|
|
|
if listener then
|
|
listener:SetScript("OnKeyDown", self.OnKeyDown);
|
|
listener:SetScript("OnGamePadButtonDown", self.OnGamePadButtonDown);
|
|
listener:SetScript("OnGamePadButtonUp", self.OnGamePadButtonUp)
|
|
listener:EnableGamePadButton(true);
|
|
listener:EnableKeyboard(true);
|
|
end
|
|
end
|
|
|
|
function KeyboardControl:StopListeningKeys()
|
|
self:SetScript("OnKeyDown", nil);
|
|
self.noPropagateFrame:SetScript("OnKeyDown", nil);
|
|
|
|
self:SetScript("OnGamePadButtonDown", nil);
|
|
self.noPropagateFrame:SetScript("OnGamePadButtonDown", nil);
|
|
self:SetScript("OnGamePadButtonUp", nil);
|
|
self.noPropagateFrame:SetScript("OnGamePadButtonUp", nil);
|
|
|
|
self:EnableGamePadButton(false);
|
|
self.noPropagateFrame:EnableGamePadButton(false);
|
|
|
|
self:EnableKeyboard(false);
|
|
self.noPropagateFrame:EnableKeyboard(false);
|
|
end
|
|
|
|
function KeyboardControl.GetPrimaryControlKey()
|
|
return PRIMARY_CONTROL_KEY
|
|
end
|
|
|
|
|
|
do --GamePad/Controller
|
|
local KeyRemap = {
|
|
PAD2 = "ESCAPE",
|
|
PADDUP = "GAMEPAD_UP",
|
|
PADDDOWN = "GAMEPAD_DOWN",
|
|
PADFORWARD = "F1", --Toggle Settings
|
|
PADMENU = "F1",
|
|
PADBACK = "ESCAPE",
|
|
PADDLEFT = "GAMEPAD_UP",
|
|
PADDRIGHT = "GAMEPAD_DOWN",
|
|
};
|
|
|
|
local RepeatableButton = {
|
|
PADDUP = true,
|
|
PADDDOWN = true,
|
|
PADDLEFT = true,
|
|
PADDRIGHT = true,
|
|
};
|
|
|
|
local REPEAT_INTERVAL = 0.125;
|
|
|
|
function KeyboardControl:OnGamePadButtonDown(button)
|
|
self:StopRepeatingAction();
|
|
|
|
|
|
if button == "PADRTRIGGER" then --Debug Console
|
|
DEBUG_SHOW_GAMEPAD_BUTTON = not DEBUG_SHOW_GAMEPAD_BUTTON;
|
|
if DEBUG_SHOW_GAMEPAD_BUTTON then
|
|
addon.DevTool:PrintText("|cffffd100Display Pressed Buttons|r");
|
|
else
|
|
addon.DevTool:PrintText("|cffffd100No Longer Display Pressed Buttons|r");
|
|
end
|
|
if not InCombatLockdown() then
|
|
KeyboardControl:SetPropagateKeyboardInput(false);
|
|
end
|
|
return
|
|
end
|
|
|
|
if button == "PADLTRIGGER" then
|
|
if TTS_HOTKEY_ENABLED then
|
|
addon.TTSUtil:ToggleSpeaking();
|
|
if not InCombatLockdown() then
|
|
KeyboardControl:SetPropagateKeyboardInput(false);
|
|
end
|
|
return
|
|
end
|
|
end
|
|
|
|
if DEBUG_SHOW_GAMEPAD_BUTTON then
|
|
addon.DevTool:PrintText(button);
|
|
end
|
|
|
|
if button == GAMEPAD_CONFIRM then
|
|
|
|
elseif button == GAMEPAD_ALT then
|
|
local TooltipFrame = addon.SharedTooltip;
|
|
if TooltipFrame and TooltipFrame:IsShown() then
|
|
TooltipFrame:ToggleAlternateInfo()
|
|
end
|
|
else
|
|
if RepeatableButton[button] then
|
|
self:RepeatAction(KeyRemap[button]);
|
|
end
|
|
button = KeyRemap[button];
|
|
end
|
|
|
|
if button then
|
|
KeyboardControl:OnKeyDown(button, true);
|
|
end
|
|
end
|
|
|
|
function KeyboardControl:OnGamePadButtonUp(button)
|
|
self:StopRepeatingAction();
|
|
end
|
|
|
|
local function RepeatGamePadButton_OnUpdate(self, elapsed)
|
|
self.repeatElapsed = self.repeatElapsed + elapsed;
|
|
if self.repeatElapsed >= REPEAT_INTERVAL then
|
|
self.repeatElapsed = 0;
|
|
if self.repeatButton then
|
|
KeyboardControl:OnKeyDown(self.repeatButton, true);
|
|
else
|
|
self:StopRepeatingAction();
|
|
end
|
|
end
|
|
end
|
|
|
|
function KeyboardControl:RepeatAction(button)
|
|
self.repeatElapsed = -0.375;
|
|
self.repeatButton = button;
|
|
self:SetScript("OnUpdate", RepeatGamePadButton_OnUpdate);
|
|
end
|
|
|
|
function KeyboardControl:StopRepeatingAction()
|
|
self:SetScript("OnUpdate", nil);
|
|
self.repeatElapsed = nil;
|
|
end
|
|
|
|
|
|
local function PostInputDeviceChanged(dbValue)
|
|
--Switch ABXY is reversed
|
|
local isSwitch = dbValue == 4;
|
|
|
|
if isSwitch then
|
|
GAMEPAD_CONFIRM = "PAD2";
|
|
GAMEPAD_CANCEL = "PAD1";
|
|
GAMEPAD_ALT = "PAD4";
|
|
KeyRemap.PAD1 = "ESCAPE";
|
|
KeyRemap.PAD2 = nil;
|
|
else
|
|
GAMEPAD_CONFIRM = "PAD1";
|
|
GAMEPAD_CANCEL = "PAD2";
|
|
GAMEPAD_ALT = "PAD3";
|
|
KeyRemap.PAD1 = nil;
|
|
KeyRemap.PAD2 = "ESCAPE";
|
|
end
|
|
end
|
|
addon.CallbackRegistry:Register("PostInputDeviceChanged", PostInputDeviceChanged);
|
|
end
|
|
|
|
|
|
do --Settings
|
|
local function Settings_PrimaryControlKey(dbValue)
|
|
local newKey;
|
|
|
|
DISABLE_CONTROL_KEY = false;
|
|
|
|
if dbValue == 1 then
|
|
newKey = DEFAULT_CONTROL_KEY;
|
|
KeyboardControl:UnregisterEvent("UPDATE_BINDINGS");
|
|
USE_INTERACT_KEY = false;
|
|
elseif dbValue == 2 then
|
|
newKey = API.GetBestInteractKey();
|
|
KeyboardControl:RegisterEvent("UPDATE_BINDINGS");
|
|
USE_INTERACT_KEY = true;
|
|
elseif dbValue == 0 then
|
|
newKey = "DISABLED";
|
|
KeyboardControl:UnregisterEvent("UPDATE_BINDINGS");
|
|
USE_INTERACT_KEY = false;
|
|
DISABLE_CONTROL_KEY = true;
|
|
end
|
|
|
|
if newKey and newKey ~= PRIMARY_CONTROL_KEY then
|
|
PRIMARY_CONTROL_KEY = newKey;
|
|
addon.DialogueUI:OnSettingsChanged();
|
|
end
|
|
end
|
|
addon.CallbackRegistry:Register("SettingChanged.PrimaryControlKey", Settings_PrimaryControlKey);
|
|
|
|
|
|
local function Settings_TTSUseHotkey(dbValue)
|
|
TTS_HOTKEY_ENABLED = dbValue == true
|
|
end
|
|
addon.CallbackRegistry:Register("SettingChanged.TTSUseHotkey", Settings_TTSUseHotkey);
|
|
end
|