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.

444 lines
12 KiB

local _, addon = ...
local SetOverrideBindingClick = SetOverrideBindingClick;
local ClearOverrideBindings = ClearOverrideBindings;
local IsKeyDown = IsKeyDown;
local GamePadButtonPool = addon.GamePadButtonPool;
local ACTION_GOUPS = addon.actionGroups;
local ActiveGroup = {};
local KeyListener, Repeater;
local Loader = CreateFrame("Frame");
local ModuleManager = Narci.ModuleManager;
local function SignalGamePadActive()
end
if ModuleManager then
function SignalGamePadActive()
ModuleManager:OnGamePadActiveChanged(true);
end
ModuleManager:AddGamePadCallbackWidget(Loader);
end
local function SelectActionGroup(name, mode)
if ACTION_GOUPS[name] then
if ActiveGroup.currentObj and ActiveGroup.currentObj.OnLeave then
ActiveGroup.currentObj:OnLeave();
end
GamePadButtonPool:HideAllButtons();
ActiveGroup = ACTION_GOUPS[name];
ActiveGroup:Activate(mode);
Repeater:SetInterval(ActiveGroup.repeatInterval);
--print("Action Group: "..name);
else
print("Failed to find: "..name);
end
end
addon.SelectActionGroup = SelectActionGroup;
--courtesy of Munk (dev of ConsolePort and Immersion)
local Proxy = CreateFrame("Button", "NarciPadClickProxy", nil, "InsecureActionButtonTemplate");
addon.ClickProxy = Proxy;
Proxy:SetAttribute("type", "click");
function Proxy:SetClickTarget(object)
SetOverrideBindingClick(Proxy, true, "PAD3", "NarciPadClickProxy");
self:SetAttribute("type", "click");
self:SetAttribute("clickbutton", object);
end
function Proxy:SetUseItem(slotID)
SetOverrideBindingClick(Proxy, true, "PAD3", "NarciPadClickProxy");
self:SetAttribute("type", "item");
self:SetAttribute("item", slotID);
end
function Proxy:SetRunMacro(macroText)
if macroText then
SetOverrideBindingClick(Proxy, true, "PAD3", "NarciPadClickProxy");
self:SetAttribute("type", "macro");
self:SetAttribute("macrotext", macroText);
else
self:Remove();
end
end
function Proxy:SetCancelCast()
ClearOverrideBindings(self)
SetOverrideBindingClick(Proxy, true, "PAD2", "NarciPadClickProxy");
self:SetAttribute("type", "macro");
self:SetAttribute("macrotext", "/stopcasting");
end
function Proxy:Remove()
ClearOverrideBindings(self)
end
local IsNavigationKeys = {
["PADRSHOULDER"] = true,
["PADLSHOULDER"] = true,
["PADDLEFT"] = true,
["PADDRIGHT"] = true,
["PADDUP"] = true,
["PADDDOWN"] = true,
};
local SIGNAL_PRESS = {
["PAD1"] = true,
["PAD2"] = true,
["PAD3"] = true,
["PAD4"] = true,
}
--Process hardware input
KeyListener = CreateFrame("Frame");
KeyListener.isButtonDown = {};
KeyListener:Hide();
KeyListener:SetPropagateKeyboardInput(false);
Repeater = CreateFrame("Frame", nil, KeyListener);
Repeater:Hide();
KeyListener:RegisterEvent("PLAYER_REGEN_DISABLED");
KeyListener:RegisterEvent("MODIFIER_STATE_CHANGED");
KeyListener:SetScript("OnEvent", function(self, event, ...)
if event == "PLAYER_REGEN_DISABLED" then
self:Deactivate();
else
self:SetModifierState(...)
end
end);
function KeyListener:SetModifierState(key, down)
self.isButtonDown[key] = down == 1;
end
function KeyListener:IsButtonDown(key)
return self.isButtonDown[key]
end
function KeyListener:ResetButtonStates()
self.isButtonDown = {};
end
KeyListener:SetScript("OnKeyDown", function(self, key, down)
--print("|cFF8cd964"..key);
self:SetPropagateKeyboardInput(true);
end);
KeyListener:SetScript("OnKeyUp", function(self, key, down)
--print("|cFFff8000"..key);
self:SetPropagateKeyboardInput(true);
end);
KeyListener:SetScript("OnGamePadStick", function(self, ...)
if self:IsButtonDown("PADRTRIGGER") or self:IsButtonDown("RCTRL") then
local stick, x, y, a = ...
if stick == "Right" then
y = 0.1 * y;
if y > 0 then
CameraZoomIn(y);
elseif y < 0 then
CameraZoomOut(-y);
else
end
self:SetPropagateKeyboardInput(false);
end
else
local stick, x, y, a = ...
if stick == "Right" then
addon.CameraRotater:Yaw(x);
self:SetPropagateKeyboardInput(false);
end
end
end)
KeyListener:SetScript("OnGamePadButtonDown", function(self, key)
--print("|cFF8cd964"..key);
if key == "PADBACK" or key == "PADSYSTEM" then
Narci:CloseCharacterUI();
return
end
self.isButtonDown[key] = true;
SignalGamePadActive();
local hold, propagate = self:ProcessKeyDown(key);
if hold and IsNavigationKeys[key] then
self:HoldKey(key);
else
Repeater:Stop();
end
self:SetPropagateKeyboardInput(propagate);
if SIGNAL_PRESS[key] then
GamePadButtonPool:SignalPress(key);
end
end)
KeyListener:SetScript("OnGamePadButtonUp", function(self, key)
--print("|cFFff8000"..key);
self.isButtonDown[key] = false;
Repeater:Stop();
self:ProcessKeyUp(key);
end)
function KeyListener:ProcessKeyDown(key, isRepeated)
local hold, propagate;
if IsNavigationKeys[key] then
if key == "PADDLEFT" then
hold, propagate = ActiveGroup:Navigate(-1, 0);
elseif key == "PADDRIGHT" then
hold, propagate = ActiveGroup:Navigate(1, 0);
elseif key == "PADDUP" then
hold, propagate = ActiveGroup:Navigate(0, 1);
elseif key == "PADDDOWN" then
hold, propagate = ActiveGroup:Navigate(0, -1);
elseif key == "PADLSHOULDER" then
hold, propagate = ActiveGroup:Switch(-1);
elseif key == "PADRSHOULDER" then
hold, propagate = ActiveGroup:Switch(1);
else
end
else
hold, propagate = ActiveGroup:KeyDown(key);
end
if propagate == nil then
propagate = false;
end
return hold, propagate
end
function KeyListener:ProcessKeyUp(key)
ActiveGroup:KeyUp(key);
end
function KeyListener:HoldKey(key)
Repeater:SetKeyAndStart(key);
end
function KeyListener:Activate()
self:Show();
self:EnableGamePadButton(true);
self:EnableKeyboard(true);
self:SetFrameStrata("FULLSCREEN_DIALOG");
self:SetFrameLevel(1208);
end
function KeyListener:Deactivate()
self:Hide();
self:SetPropagateKeyboardInput(true);
Proxy:Remove();
end
--Hold to Repeat Aey Actions
Repeater.t = 0;
Repeater.interval = 0.25;
Repeater:SetScript("OnUpdate", function(self, elapsed)
self.t = self.t + elapsed;
if self.t > self.interval then
self.t = 0;
if self.key and KeyListener:IsButtonDown(self.key) then
local isValid = KeyListener:ProcessKeyDown(self.key, true);
if not isValid then
self:Hide();
end
else
self:Hide();
end
end
end);
Repeater:SetScript("OnHide", function(self)
self.callBack = nil;
self.t = 0;
end);
function Repeater:SetInterval(interval)
self.interval = interval or 0.25;
end
function Repeater:SetKeyAndStart(key)
if key then
self:Hide();
self.key = key;
self:Start();
else
self:Stop();
end
end
function Repeater:Start()
self.t = -0.25; --initial delay
self:Show();
end
function Repeater:Stop()
self:Hide();
end
------------------------------------------------------
Loader:RegisterEvent("ADDON_LOADED");
--[[
Loader:RegisterEvent("GAME_PAD_ACTIVE_CHANGED");
Loader:RegisterEvent("GAME_PAD_CONFIGS_CHANGED");
Loader:RegisterEvent("GAME_PAD_CONNECTED");
Loader:RegisterEvent("GAME_PAD_DISCONNECTED");
function Loader:OnActiveChanged(isActive)
if isActive then
print("Game pad is active");
else
print("Game pad is inactive");
end
end
function Loader:OnConfigChanged()
print("Game pad config changed");
end
function Loader:OnConnected()
print("Game pad connected");
end
function Loader:OnDisconnected()
print("Game pad disconnected");
end
--]]
function Loader:Init()
print("Narcissus GamePad enabled");
hooksecurefunc("Narci_Open", function()
if Narci.isActive then
KeyListener:Activate();
SelectActionGroup("CharacterFrame");
else
self:ExitGamePadMode();
end
end)
local EquipmentOption = Narci_EquipmentOption;
hooksecurefunc(EquipmentOption, "SetFromSlotButton", function(f, slotButton, returnHome)
SelectActionGroup("EquipmentOption", true);
end);
hooksecurefunc(EquipmentOption, "CloseUI", function()
SelectActionGroup("EquipmentSlot");
end);
local EquipmentFlyout = Narci_EquipmentFlyoutFrame;
hooksecurefunc(EquipmentFlyout, "DisplayItemsBySlotID", function(f, slotButton, slotChanged)
SelectActionGroup("SwapItem", slotChanged);
end);
EquipmentFlyout:HookScript("OnHide", function(frame)
SelectActionGroup("EquipmentSlot");
end);
hooksecurefunc(Narci_NavBar, "SelectTab", function(f, tabID)
if tabID == 1 then
SelectActionGroup("CharacterFrame", 1);
elseif tabID == 2 then
SelectActionGroup("SetManager");
elseif tabID == 3 then
SelectActionGroup("Soulbind");
elseif tabID == 4 then
SelectActionGroup("MythicPlus");
end
end);
EquipmentOption.ItemList:HookScript("OnShow", function(frame)
SelectActionGroup("EnhancementList");
end);
EquipmentOption.ItemList:HookScript("OnHide", function(frame)
SelectActionGroup("EquipmentOption");
end);
Narci_TitleFrame:HookScript("OnShow", function(frame)
SelectActionGroup("TitleManager");
end);
Narci_TitleFrame:HookScript("OnHide", function(frame)
SelectActionGroup("CharacterFrame");
end);
end
function Loader:ExitGamePadMode()
KeyListener:Deactivate();
self:ResetNavigation();
end
function Loader:ResetNavigation()
addon.CameraRotater:Stop();
for name, actionGroup in pairs(ACTION_GOUPS) do
actionGroup:ResetNavigation();
end
end
function Loader:OnGamePadActiveChanged(isActive)
if isActive then
addon.GamePadNavBar:Show();
else
addon.GamePadNavBar:Hide();
if ActiveGroup.currentObj and ActiveGroup.currentObj.OnLeave and not ActiveGroup.currentObj:IsMouseOver() then
ActiveGroup.currentObj:OnLeave();
end
self:ResetNavigation();
end
GamePadButtonPool:OnGamePadActiveChanged(isActive);
end
Loader:SetScript("OnEvent", function(self, event, ...)
if event == "ADDON_LOADED" then
local name = ...
if name == "Narcissus_GamePad" then
self:UnregisterEvent(event);
self:Init();
end
elseif event == "GAME_PAD_ACTIVE_CHANGED" then
self:OnActiveChanged(...);
elseif event == "GAME_PAD_CONFIGS_CHANGED" then
self:OnConfigChanged(...);
elseif event == "GAME_PAD_CONNECTED" then
self:OnConnected(...);
elseif event == "GAME_PAD_DISCONNECTED" then
self:OnDisconnected(...);
end
end)
SlashCmdList['NARCISSUSGAMEPAD'] = function(msg)
msg = string.lower(msg);
Narci_Open();
end
SLASH_NARCISSUSGAMEPAD1 = '/narcissusgamepad';