Files

400 lines
13 KiB
Lua

local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
local AB = E:GetModule("ActionBars")
local Skins = E:GetModule("Skins")
--Lua functions
local _G = _G
local select, tonumber, pairs = select, tonumber, pairs
local floor = math.floor
local find, format, upper = string.find, string.format, string.upper
--WoW API / Variables
local hooksecurefunc = hooksecurefunc
local CreateFrame = CreateFrame
local IsAddOnLoaded = IsAddOnLoaded
local LoadBindings, SaveBindings = LoadBindings, SaveBindings
local GetCurrentBindingSet = GetCurrentBindingSet
local SetBinding = SetBinding
local GetBindingKey = GetBindingKey
local IsAltKeyDown, IsControlKeyDown = IsAltKeyDown, IsControlKeyDown
local IsShiftKeyDown, IsModifiedClick = IsShiftKeyDown, IsModifiedClick
local InCombatLockdown = InCombatLockdown
local GameTooltip_ShowCompareItem = GameTooltip_ShowCompareItem
local GetMacroInfo = GetMacroInfo
local SecureActionButton_OnClick = SecureActionButton_OnClick
local GameTooltip_Hide = GameTooltip_Hide
local CHARACTER_SPECIFIC_KEYBINDING_TOOLTIP = CHARACTER_SPECIFIC_KEYBINDING_TOOLTIP
local CHARACTER_SPECIFIC_KEYBINDINGS = CHARACTER_SPECIFIC_KEYBINDINGS
local bind = CreateFrame("Frame", "ElvUI_KeyBinder", E.UIParent)
function AB:ActivateBindMode()
if InCombatLockdown() then
return
end
bind.active = true
E:StaticPopupSpecial_Show(ElvUIBindPopupWindow)
AB:RegisterEvent("PLAYER_REGEN_DISABLED", "DeactivateBindMode", false)
end
function AB:DeactivateBindMode(save)
if save then
SaveBindings(GetCurrentBindingSet())
E:Print(L["Binds Saved"])
else
LoadBindings(GetCurrentBindingSet())
E:Print(L["Binds Discarded"])
end
bind.active = false
self:BindHide()
self:UnregisterEvent("PLAYER_REGEN_DISABLED")
E:StaticPopupSpecial_Hide(ElvUIBindPopupWindow)
AB.bindingsChanged = false
end
function AB:BindHide()
bind:ClearAllPoints()
bind:Hide()
GameTooltip:Hide()
end
function AB:BindListener(key)
AB.bindingsChanged = true
if key == "ESCAPE" or key == "RightButton" then
if bind.button.bindings then
for i = 1, #bind.button.bindings do
SetBinding(bind.button.bindings[i])
end
end
E:Print(format(L["All keybindings cleared for |cff00ff00%s|r."], bind.button.name))
self:BindUpdate(bind.button, bind.spellmacro)
if bind.spellmacro ~= "MACRO" then
GameTooltip:Hide()
end
return
end
if key == "LSHIFT"
or key == "RSHIFT"
or key == "LCTRL"
or key == "RCTRL"
or key == "LALT"
or key == "RALT"
or key == "UNKNOWN"
or key == "LeftButton"
then return end
if key == "MiddleButton" then key = "BUTTON3" end
if find(key, "Button%d") then
key = upper(key)
end
local alt = IsAltKeyDown() and "ALT-" or ""
local ctrl = IsControlKeyDown() and "CTRL-" or ""
local shift = IsShiftKeyDown() and "SHIFT-" or ""
local keybind = format("%s%s%s%s", alt, ctrl, shift, key)
if not bind.spellmacro or bind.spellmacro == "PET" or bind.spellmacro == "SHAPESHIFT" then
SetBinding(keybind, bind.button.bindstring)
else
SetBinding(keybind, bind.spellmacro.." "..bind.button.name)
end
E:Print(format("%s%s%s.", keybind, L[" |cff00ff00bound to |r"], bind.button.name))
self:BindUpdate(bind.button, bind.spellmacro)
if bind.spellmacro ~= "MACRO" then
GameTooltip:Hide()
end
end
function AB:BindUpdate(button, spellmacro)
if not bind.active or InCombatLockdown() then return end
bind.button = button
bind.spellmacro = spellmacro
bind:ClearAllPoints()
bind:SetAllPoints(button)
bind:Show()
ShoppingTooltip1:Hide()
if not bind:IsMouseEnabled() then
bind:EnableMouse(true)
end
if spellmacro == "MACRO" then
bind.button.id = bind.button:GetID()
if floor(.5 + select(2, MacroFrameTab1Text:GetTextColor()) * 10) / 10 == .8 then bind.button.id = bind.button.id + MAX_ACCOUNT_MACROS end
bind.button.name = GetMacroInfo(bind.button.id)
GameTooltip:SetOwner(bind, "ANCHOR_TOP")
GameTooltip:SetPoint("BOTTOM", bind, "TOP", 0, 1)
GameTooltip:AddLine(bind.button.name, 1, 1, 1)
bind.button.bindings = {GetBindingKey(spellmacro.." "..bind.button.name)}
if #bind.button.bindings == 0 then
GameTooltip:AddLine(L["No bindings set."], .6, .6, .6)
else
GameTooltip:AddDoubleLine(L["Binding"], L["Key"], .6, .6, .6, .6, .6, .6)
for i = 1, #bind.button.bindings do
GameTooltip:AddDoubleLine(L["Binding"]..i, bind.button.bindings[i], 1, 1, 1)
end
end
GameTooltip:Show()
elseif spellmacro == "SHAPESHIFT" or spellmacro == "PET" then
bind.button.id = tonumber(button:GetID())
bind.button.name = button:GetName()
if not bind.button.name then return end
if not bind.button.id or bind.button.id < 1 or bind.button.id > (spellmacro=="SHAPESHIFT" and 10 or 12) then
bind.button.bindstring = "CLICK "..bind.button.name..":LeftButton"
else
bind.button.bindstring = (spellmacro=="SHAPESHIFT" and "SHAPESHIFTBUTTON" or "BONUSACTIONBUTTON")..bind.button.id
end
GameTooltip:AddLine(L["Trigger"])
GameTooltip:Show()
GameTooltip:SetScript("OnHide", function(tt)
tt:SetOwner(bind, "ANCHOR_NONE")
tt:SetPoint("BOTTOM", bind, "TOP", 0, 1)
tt:AddLine(bind.button.name, 1, 1, 1)
bind.button.bindings = {GetBindingKey(bind.button.bindstring)}
if #bind.button.bindings == 0 then
tt:AddLine(L["No bindings set."], .6, .6, .6)
else
tt:AddDoubleLine(L["Binding"], L["Key"], .6, .6, .6, .6, .6, .6)
for i = 1, #bind.button.bindings do
tt:AddDoubleLine(i, bind.button.bindings[i])
end
end
tt:Show()
tt:SetScript("OnHide", nil)
end)
else
bind.button.action = tonumber(button.action)
bind.button.name = button:GetName()
if not bind.button.name then return end
if (not bind.button.action or bind.button.action < 1 or bind.button.action > 132) and not (bind.button.keyBoundTarget) then
bind.button.bindstring = "CLICK "..bind.button.name..":LeftButton"
elseif bind.button.keyBoundTarget then
bind.button.bindstring = bind.button.keyBoundTarget
else
local modact = 1 + (bind.button.action-1) % 12
if bind.button.action < 25 or bind.button.action > 72 then
bind.button.bindstring = "ACTIONBUTTON"..modact
elseif bind.button.action < 73 and bind.button.action > 60 then
bind.button.bindstring = "MULTIACTIONBAR1BUTTON"..modact
elseif bind.button.action < 61 and bind.button.action > 48 then
bind.button.bindstring = "MULTIACTIONBAR2BUTTON"..modact
elseif bind.button.action < 49 and bind.button.action > 36 then
bind.button.bindstring = "MULTIACTIONBAR4BUTTON"..modact
elseif bind.button.action < 37 and bind.button.action > 24 then
bind.button.bindstring = "MULTIACTIONBAR3BUTTON"..modact
end
end
GameTooltip:AddLine(L["Trigger"])
GameTooltip:Show()
GameTooltip:SetScript("OnHide", function(tt)
tt:SetOwner(bind, "ANCHOR_TOP")
tt:SetPoint("BOTTOM", bind, "TOP", 0, 4)
tt:AddLine(bind.button.name, 1, 1, 1)
bind.button.bindings = {GetBindingKey(bind.button.bindstring)}
if #bind.button.bindings == 0 then
tt:AddLine(L["No bindings set."], .6, .6, .6)
else
tt:AddDoubleLine(L["Binding"], L["Key"], .6, .6, .6, .6, .6, .6)
for i = 1, #bind.button.bindings do
tt:AddDoubleLine(i, bind.button.bindings[i])
end
end
tt:Show()
tt:SetScript("OnHide", nil)
end)
end
end
function AB:RegisterButton(button, override)
local shapeshift = ShapeshiftButton1:GetScript("OnClick")
local pet = PetActionButton1:GetScript("OnClick")
local secureOnClick = SecureActionButton_OnClick
if button.IsProtected and button.GetObjectType and button.GetScript and button:GetObjectType() == "CheckButton" and button:IsProtected() then
local script = button:GetScript("OnClick")
if script == secureOnClick or override then
button:HookScript("OnEnter", function(b) self:BindUpdate(b) end)
if script == shapeshift then
button:HookScript("OnEnter", function(b) self:BindUpdate(b, "SHAPESHIFT") end)
elseif script == pet then
button:HookScript("OnEnter", function(b) self:BindUpdate(b, "PET") end)
end
end
end
end
local elapsed = 0
function AB:Tooltip_OnUpdate(tooltip, e)
elapsed = elapsed + e
if elapsed < .2 then return else elapsed = 0 end
local compareItems = IsModifiedClick("COMPAREITEMS")
if not tooltip.comparing and compareItems and tooltip:GetItem() then
GameTooltip_ShowCompareItem(tooltip)
tooltip.comparing = true
elseif tooltip.comparing and not compareItems then
for _, frame in pairs(tooltip.shoppingTooltips) do frame:Hide() end
tooltip.comparing = false
end
end
function AB:RegisterMacro(addon)
if addon == "Blizzard_MacroUI" then
for i = 1, MAX_ACCOUNT_MACROS do
local button = _G["MacroButton"..i]
button:HookScript("OnEnter", function(b) AB:BindUpdate(b, "MACRO") end)
end
end
end
function AB:ChangeBindingProfile()
if ElvUIBindPopupWindowCheckButton:GetChecked() then
LoadBindings(2)
SaveBindings(2)
else
LoadBindings(1)
SaveBindings(1)
end
end
function AB:LoadKeyBinder()
bind:SetFrameStrata("DIALOG")
bind:SetFrameLevel(99)
bind:EnableMouse(true)
bind:EnableKeyboard(true)
bind:EnableMouseWheel(true)
bind.texture = bind:CreateTexture()
bind.texture:SetAllPoints(bind)
bind.texture:SetTexture(0, 0, 0, .25)
bind:Hide()
self:HookScript(GameTooltip, "OnUpdate", "Tooltip_OnUpdate")
hooksecurefunc(GameTooltip, "Hide", function(tooltip) for _, tt in pairs(tooltip.shoppingTooltips) do tt:Hide() end end)
bind:SetScript("OnEnter", function(self) local db = self.button:GetParent().db if db and db.mouseover then AB:Button_OnEnter(self.button) end end)
bind:SetScript("OnLeave", function(self) AB:BindHide() local db = self.button:GetParent().db if db and db.mouseover then AB:Button_OnLeave(self.button) end end)
bind:SetScript("OnKeyUp", function(_, key) self:BindListener(key) end)
bind:SetScript("OnMouseUp", function(_, key) self:BindListener(key) end)
bind:SetScript("OnMouseWheel", function(_, delta) if delta > 0 then self:BindListener("MOUSEWHEELUP") else self:BindListener("MOUSEWHEELDOWN") end end)
for b, _ in pairs(self.handledbuttons) do
self:RegisterButton(b, true)
end
if not IsAddOnLoaded("Blizzard_MacroUI") then
self:SecureHook("LoadAddOn", "RegisterMacro")
else
self:RegisterMacro("Blizzard_MacroUI")
end
--Special Popup
local f = CreateFrame("Frame", "ElvUIBindPopupWindow", UIParent)
f:SetFrameStrata("DIALOG")
f:SetToplevel(true)
f:EnableMouse(true)
f:SetMovable(true)
f:SetFrameLevel(99)
f:SetClampedToScreen(true)
f:SetWidth(360)
f:SetHeight(130)
f:SetTemplate("Transparent")
f:Hide()
local header = CreateFrame("Button", nil, f)
header:SetTemplate(nil, true)
header:Width(100)
header:Height(25)
header:Point("CENTER", f, "TOP")
header:SetFrameLevel(header:GetFrameLevel() + 2)
header:EnableMouse(true)
header:RegisterForClicks("AnyUp", "AnyDown")
header:SetScript("OnMouseDown", function() f:StartMoving() end)
header:SetScript("OnMouseUp", function() f:StopMovingOrSizing() end)
local title = header:CreateFontString("OVERLAY")
title:FontTemplate()
title:Point("CENTER", header, "CENTER")
title:SetText("Key Binds")
local desc = f:CreateFontString("ARTWORK")
desc:SetFontObject("GameFontHighlight")
desc:SetJustifyV("TOP")
desc:SetJustifyH("LEFT")
desc:Point("TOPLEFT", 18, -32)
desc:Point("BOTTOMRIGHT", -18, 48)
desc:SetText(L["Hover your mouse over any actionbutton or spellbook button to bind it. Press the ESC key to clear the current actionbutton's keybinding."])
local perCharCheck = CreateFrame("CheckButton", f:GetName().."CheckButton", f, "OptionsCheckButtonTemplate")
_G[perCharCheck:GetName().."Text"]:SetText(CHARACTER_SPECIFIC_KEYBINDINGS)
perCharCheck:SetScript("OnShow", function(self)
self:SetChecked(GetCurrentBindingSet() == 2)
end)
perCharCheck:SetScript("OnClick", function()
if ( AB.bindingsChanged ) then
E:StaticPopup_Show("CONFIRM_LOSE_BINDING_CHANGES")
else
AB:ChangeBindingProfile()
end
end)
perCharCheck:SetScript("OnEnter", function(self)
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
GameTooltip:SetText(CHARACTER_SPECIFIC_KEYBINDING_TOOLTIP, nil, nil, nil, nil, 1)
end)
perCharCheck:SetScript("OnLeave", GameTooltip_Hide)
local save = CreateFrame("Button", f:GetName().."SaveButton", f, "OptionsButtonTemplate")
_G[save:GetName().."Text"]:SetText(L["Save"])
save:Width(150)
save:SetScript("OnClick", function()
AB:DeactivateBindMode(true)
end)
local discard = CreateFrame("Button", f:GetName().."DiscardButton", f, "OptionsButtonTemplate")
discard:Width(150)
_G[discard:GetName().."Text"]:SetText(L["Discard"])
discard:SetScript("OnClick", function()
AB:DeactivateBindMode(false)
end)
--position buttons
perCharCheck:Point("BOTTOMLEFT", discard, "TOPLEFT", 0, 2)
save:Point("BOTTOMRIGHT", -14, 10)
discard:Point("BOTTOMLEFT", 14, 10)
Skins:HandleCheckBox(perCharCheck)
Skins:HandleButton(save)
Skins:HandleButton(discard)
end
function ToggleQuickKeybindMode(characterSpecific)
if ElvUIBindPopupWindow and ElvUIBindPopupWindow:IsVisible() then
AB:DeactivateBindMode(false)
else
AB:ActivateBindMode()
end
end