Mercurial > wow > reaction
changeset 116:fb48811a8736
Convert to standard keybindings
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Fri, 23 Jan 2009 23:44:55 +0000 |
parents | af0172ed7037 |
children | e2257bf1d717 |
files | ReAction.lua locale/enUS.lua modules/Action.lua modules/PetAction.lua |
diffstat | 4 files changed, 421 insertions(+), 546 deletions(-) [+] |
line wrap: on
line diff
--- a/ReAction.lua Fri Jan 23 23:40:13 2009 +0000 +++ b/ReAction.lua Fri Jan 23 23:44:55 2009 +0000 @@ -57,10 +57,7 @@ ------ PRIVATE ------ local weak = {__mode="k"} -local private = { - allKB = setmetatable({}, weak), - kbHooked = setmetatable({}, weak), -} +local private = { } local bars = {} local defaultBarConfig = {} local barOptionGenerators = { } @@ -86,9 +83,19 @@ handler = ReAction, get = "GetConfigMode", set = function(info, value) ReAction:SetConfigMode(value) end, + width = "double", disabled = InCombatLockdown, order = 1 }, + skipProfileWarning = { + type = "toggle", + name = L["Skip profile keybind warning"], + desc = L["Don't show a warning about updating keybinds when switching profiles"], + get = function() return ReAction.db.global.skipKeybindWarning end, + set = function(info, value) ReAction.db.global.skipKeybindWarning = value end, + width = "double", + order = 2, + }, }, plugins = { }, order = 2, @@ -107,19 +114,24 @@ } ReAction.options = options -local SelectBar, DestroyBar, InitializeBars, TearDownBars, DeepCopy, CallModuleMethod, SlashHandler, KBAttach + -- insert an entry into the WoW static popup dialogs list +StaticPopupDialogs["REACTION_KB_WARN"] = { + text = L["ReAction profile changed: check your keybinds, they may need to be updated."], + button1 = L["OK"], + hideOnEscape = true, + enterClicksFirstButton = true, + timeout = 0, + showAlert = true, + whileDead = true, +} + +local SelectBar, DestroyBar, InitializeBars, TearDownBars, DeepCopy, CallModuleMethod, SlashHandler do local pcall = pcall local geterrorhandler = geterrorhandler local self = ReAction local inited = false - local function kb_onEnter( self ) - if ReAction:GetKeybindMode() then - KB:Set(self) - end - end - function SelectBar(x) local bar, name if type(x) == "string" then @@ -215,15 +227,6 @@ end end - function KBAttach( frame ) - if not private.kbHooked[frame] then - -- avoid taint, particularly with SecureAnchorEnterTemplate - -- don't hook scripts multiple times, there isn't any unhook! - frame:HookScript("OnEnter",kb_onEnter) - private.kbHooked[frame] = true - end - end - end @@ -263,6 +266,7 @@ function ReAction:OnProfileChanged() TearDownBars() InitializeBars() + self:PopKeybindWarning() end function ReAction:PLAYER_REGEN_DISABLED() @@ -501,9 +505,6 @@ function ReAction:SetKeybindMode( mode ) if mode ~= private.kbMode then if mode then - for f in pairs(private.allKB) do - KBAttach(f) - end KB:Activate() else KB:Deactivate() @@ -516,27 +517,8 @@ return private.kbMode end -function ReAction:RegisterKeybindFrame( f ) - private.allKB[f] = true - if private.kbMode then - KBAttach(f) +function ReAction:PopKeybindWarning() + if not self.db.global.skipKeybindWarning then + StaticPopup_Show("REACTION_KB_WARN") end end - -function ReAction:FreeOverrideHotkey( key ) - for f in pairs(private.allKB) do - if f.GetBindings then - for i = 1, select('#', f:GetBindings()) do - if select(i, f:GetBindings()) == key then - if f.FreeKey then - return f:FreeKey(key) - else - local action = f.GetActionName and f:GetActionName() or f:GetName() - SetOverrideBinding(f, false, key, nil) - return action - end - end - end - end - end -end
--- a/locale/enUS.lua Fri Jan 23 23:40:13 2009 +0000 +++ b/locale/enUS.lua Fri Jan 23 23:44:55 2009 +0000 @@ -16,9 +16,13 @@ "Global configuration settings", "Unlock Bars", "Unlock bars for dragging and resizing with the mouse", +"Skip profile keybind warning", +"Don't show a warning about updating keybinds when switching profiles", "Module Settings", "Configuration settings for each module", "Default", +"ReAction profile changed: check your keybinds, they may need to be updated.", +"OK", -- Overlay.lua "Hold Shift", @@ -127,11 +131,11 @@ "for keybind mode", --- modules/ReAction_HideBlizzard +-- HideBlizzard "Hide Blizzard Action Bars", "Hide the default main bar and extra action bars", --- modules/ReAction_Action +-- Action "Action Bar", "Action Bars", "Hide Empty Buttons", @@ -161,16 +165,11 @@ "Show Page #", "Action Buttons", --- modules/ReAction_PetAction +-- PetAction "Pet Action Bar", "Pet Buttons", --- modules/ReAction_PossessBar -"Possess Bar", -"Hide Empty Possess Bar Buttons", -"Possess Buttons", - --- modules/ReAction_ConfigUI +-- ConfigUI "Center", "Left", "Right",
--- a/modules/Action.lua Fri Jan 23 23:40:13 2009 +0000 +++ b/modules/Action.lua Fri Jan 23 23:44:55 2009 +0000 @@ -18,6 +18,8 @@ ReAction:UpdateRevision("$Revision$") +local weak = { __mode="k" } + -- libraries local KB = LibStub("LibKeyBound-1.0") local LBF -- initialized later @@ -267,7 +269,6 @@ }, } - local weak = { __mode="k" } local meta = { __index = Handle } function Handle:New( bar, config ) @@ -365,15 +366,7 @@ function Handle:SetKeybindMode(mode) for _, b in pairs(self.btns) do - if mode then - -- set the border for all buttons to the keybind-enable color - b.border:SetVertexColor(KB:GetColorKeyBoundMode()) - b.border:Show() - elseif IsEquippedAction(b:GetActionID()) then - b.border:SetVertexColor(0, 1.0, 0, 0.35) -- from ActionButton.lua - else - b.border:Hide() - end + b:SetKeybindMode(mode) end end @@ -763,398 +756,368 @@ end ------ Button class ------ +local frameRecycler = { } +local trash = CreateFrame("Frame") +local OnUpdate, KBAttach, GetHotkey +do + local ATTACK_BUTTON_FLASH_TIME = ATTACK_BUTTON_FLASH_TIME + local IsActionInRange = IsActionInRange -do - local frameRecycler = { } - local trash = CreateFrame("Frame") - local OnUpdate, KBAttach, GetActionName, GetHotkey, SetKey, FreeKey, ClearBindings, GetBindings - do - local ATTACK_BUTTON_FLASH_TIME = ATTACK_BUTTON_FLASH_TIME - local IsActionInRange = IsActionInRange + function OnUpdate(frame, elapsed) + -- note: This function taints frame.flashtime and frame.rangeTimer. Both of these + -- are only read by ActionButton_OnUpdate (which this function replaces). In + -- all other places they're just written, so it doesn't taint any secure code. + if frame.flashing == 1 then + frame.flashtime = frame.flashtime - elapsed + if frame.flashtime <= 0 then + local overtime = -frame.flashtime + if overtime >= ATTACK_BUTTON_FLASH_TIME then + overtime = 0 + end + frame.flashtime = ATTACK_BUTTON_FLASH_TIME - overtime - local buttonLookup = setmetatable({},{__mode="kv"}) - - function OnUpdate(frame, elapsed) - -- note: This function taints frame.flashtime and frame.rangeTimer. Both of these - -- are only read by ActionButton_OnUpdate (which this function replaces). In - -- all other places they're just written, so it doesn't taint any secure code. - if frame.flashing == 1 then - frame.flashtime = frame.flashtime - elapsed - if frame.flashtime <= 0 then - local overtime = -frame.flashtime - if overtime >= ATTACK_BUTTON_FLASH_TIME then - overtime = 0 - end - frame.flashtime = ATTACK_BUTTON_FLASH_TIME - overtime - - local flashTexture = frame.flash - if flashTexture:IsShown() then - flashTexture:Hide() - else - flashTexture:Show() - end - end - end - - if frame.rangeTimer then - frame.rangeTimer = frame.rangeTimer - elapsed; - - if frame.rangeTimer <= 0 then - if IsActionInRange(frame.action) == 0 then - frame.icon:SetVertexColor(1.0,0.1,0.1) - else - ActionButton_UpdateUsable(frame) - end - frame.rangeTimer = 0.1 + local flashTexture = frame.flash + if flashTexture:IsShown() then + flashTexture:Hide() + else + flashTexture:Show() end end end + + if frame.rangeTimer then + frame.rangeTimer = frame.rangeTimer - elapsed; - -- Use KeyBound-1.0 for binding, but use Override bindings instead of - -- regular bindings to support multiple profile use. This is a little - -- weird with the KeyBound dialog box (which has per-char selector as well - -- as an OK/Cancel box) but it's the least amount of effort to implement. - function GetActionName(f) - local b = buttonLookup[f] - if b then - return format("%s:%s", b.bar:GetName(), b.idx) - end - end - - function GetHotkey(f) - local b = buttonLookup[f] - if b then - return KB:ToShortKey(b:GetConfig().hotkey) - end - end - - function SetKey(f, key) - local b = buttonLookup[f] - if b then - local c = b:GetConfig() - if c.hotkey then - SetOverrideBinding(f, false, c.hotkey, nil) + if frame.rangeTimer <= 0 then + if IsActionInRange(frame.action) == 0 then + frame.icon:SetVertexColor(1.0,0.1,0.1) + else + ActionButton_UpdateUsable(frame) end - if key then - SetOverrideBindingClick(f, false, key, f:GetName(), nil) - end - c.hotkey = key - b:DisplayHotkey(GetHotkey(f)) - end - end - - function FreeKey(f, key) - local b = buttonLookup[f] - if b then - local c = b:GetConfig() - if c.hotkey == key then - local action = f:GetActionName() - SetOverrideBinding(f, false, c.hotkey, nil) - c.hotkey = nil - b:DisplayHotkey(nil) - return action - end - end - return ReAction:FreeOverrideHotkey(key) - end - - function ClearBindings(f) - SetKey(f, nil) - end - - function GetBindings(f) - local b = buttonLookup[f] - if b then - return b:GetConfig().hotkey - end - end - - function KBAttach( button ) - local f = button:GetFrame() - f.GetActionName = GetActionName - f.GetHotkey = GetHotkey - f.SetKey = SetKey - f.FreeKey = FreeKey - f.ClearBindings = ClearBindings - f.GetBindings = GetBindings - buttonLookup[f] = button - f:SetKey(button:GetConfig().hotkey) - ReAction:RegisterKeybindFrame(f) - if ReAction:GetKeybindMode() then - button.border:SetVertexColor(KB:GetColorKeyBoundMode()) - button.border:Show() + frame.rangeTimer = 0.1 end end end - local meta = {__index = Button} - - function Button:New( handle, idx, config, barConfig ) - local bar = handle.bar - - -- create new self - self = setmetatable( - { - bar = bar, - idx = idx, - config = config, - barConfig = barConfig, - }, meta ) - - local name = config.name or ("ReAction_%s_%s_%d"):format(bar:GetName(),moduleID,idx) - self.name = name - config.name = name - local lastButton = handle:GetLastButton() - config.actionID = IDAlloc:Acquire(config.actionID, lastButton and lastButton.config.actionID) -- gets a free one if none configured - self.nPages = 1 - - -- have to recycle frames with the same name: CreateFrame() doesn't overwrite - -- existing globals. Can't set to nil in the global because it's then tainted. - local parent = bar:GetFrame() - local f = frameRecycler[name] - if f then - f:SetParent(parent) - else - f = CreateFrame("CheckButton", name, parent, "ActionBarButtonTemplate") - -- ditch the old hotkey text because it's tied in ActionButton_Update() to the - -- standard binding. We use override bindings. - local hotkey = _G[name.."HotKey"] - hotkey:SetParent(trash) - hotkey = f:CreateFontString(nil, "ARTWORK", "NumberFontNormalSmallGray") - hotkey:SetWidth(36) - hotkey:SetHeight(18) - hotkey:SetJustifyH("RIGHT") - hotkey:SetJustifyV("TOP") - hotkey:SetPoint("TOPLEFT",f,"TOPLEFT",-2,-2) - f.hotkey = hotkey - f.icon = _G[name.."Icon"] - f.flash = _G[name.."Flash"] - f:SetScript("OnUpdate",OnUpdate) - end - - self.hotkey = f.hotkey - self.border = _G[name.."Border"] - - f:SetAttribute("action", config.actionID) - f:SetAttribute("default-action", config.actionID) - -- install mind control actions for all buttons just for simplicity - if self.idx <= 12 then - f:SetAttribute("mindcontrol-action", 120 + self.idx) - end - - -- set a _childupdate handler, called within the header's context - f:SetAttribute("_childupdate", - -- function _childupdate(self, snippetid, message) - [[ - local action = "default-action" - if doMindControl and GetBonusBarOffset() == 5 then - action = "mindcontrol-action" - elseif page and state and page[state] then - action = "action-"..page[state] - end - local value = self:GetAttribute(action) - if value then - self:SetAttribute("action",value) - end - ]]) - - -- install drag wrappers to lock buttons - bar:GetFrame():WrapScript(f, "OnDragStart", - -- OnDragStart(self, button, kind, value, ...) - [[ - if lockButtons and (PlayerInCombat() or not lockButtonsCombat) and not IsModifiedClick("PICKUPACTION") then - return "clear" - end - ]]) - - self.frame = f - - - -- initialize the hide state - f:SetAttribute("showgrid",0) - self:ShowGrid(not barConfig.hideEmpty) - if ReAction:GetConfigMode() then - self:ShowGrid(true) - end - - -- show the ID label if applicable - self:ShowActionIDLabel(ReAction:GetConfigMode()) - - -- attach the keybinder - KBAttach(self) - - -- attach to skinner - bar:SkinButton(self, - { - HotKey = self.hotkey, - } - ) - - self:Refresh() - return self - end - - function Button:Destroy() - local f = self.frame - f:UnregisterAllEvents() - f:Hide() - f:SetParent(UIParent) - f:ClearAllPoints() - if self.name then - frameRecycler[self.name] = f - end - if self.config.actionID then - IDAlloc:Release(self.config.actionID) - end - if self.config.pageactions then - for _, id in ipairs(self.config.pageactions) do - IDAlloc:Release(id) - end - end - self.frame = nil - self.config = nil - self.bar = nil - end - - function Button:Refresh() - local f = self.frame - self.bar:PlaceButton(self, 36, 36) - self:RefreshPages() - end - - function Button:GetFrame() - return self.frame - end - - function Button:GetName() - return self.name - end - - function Button:GetConfig() - return self.config - end - - function Button:GetActionID(page) - if page == nil then - -- get the effective ID - return self.frame.action -- kept up-to-date by Blizzard's ActionButton_CalculateAction() - else - if page == 1 then - return self.config.actionID - else - return self.config.pageactions and self.config.pageactions[page] or self.config.actionID - end + local function GetActionName(f) + local b = f and f._reactionButton + if b then + return format("%s:%s", b.bar:GetName(), b.idx) end end - function Button:SetActionID( id, page ) - id = tonumber(id) - page = tonumber(page) - if id == nil or id < 1 or id > 120 then - error("Button:SetActionID - invalid action ID") - end - if page and page ~= 1 then - if not self.config.pageactions then - self.config.pageactions = { } - end - if self.config.pageactions[page] then - IDAlloc:Release(self.config.pageactions[page]) - end - self.config.pageactions[page] = id - IDAlloc:Acquire(self.config.pageactions[page]) - self.frame:SetAttribute(("action-page%d"):format(page),id) - else - IDAlloc:Release(self.config.actionID) - self.config.actionID = id - IDAlloc:Acquire(self.config.actionID) - self.frame:SetAttribute("action",id) - if self.config.pageactions then - self.config.pageactions[1] = id - self.frame:SetAttribute("action-page1",id) - end + function GetHotkey(f) + return KB:ToShortKey(GetBindingKey(format("CLICK %s:LeftButton",f:GetName()))) + end + + local function kb_onEnter( self ) + if ReAction:GetKeybindMode() then + KB:Set(self) end end - function Button:RefreshPages( force ) - local nPages = self.barConfig.nPages - if nPages and (nPages ~= self.nPages or force) then - local f = self:GetFrame() - local c = self.config.pageactions - if nPages > 1 and not c then - c = { } - self.config.pageactions = c - end - for i = 1, nPages do - if i > 1 then - c[i] = IDAlloc:Acquire(c[i], self.config.actionID + (i-1)*self.bar:GetNumButtons()) - else - c[i] = self.config.actionID -- page 1 is the same as the base actionID - end - f:SetAttribute(("action-page%d"):format(i),c[i]) - end - for i = nPages+1, #c do - IDAlloc:Release(c[i]) - c[i] = nil - f:SetAttribute(("action-page%d"):format(i),nil) - end - self.nPages = nPages + function KBAttach( button ) + if not button.kbHooked then + button.kbHooked = true + local f = button:GetFrame() + f:HookScript("OnEnter", kb_onEnter) + f.GetActionName = GetActionName + f.GetHotkey = GetHotkey end end - function Button:ShowGrid( show ) - if not InCombatLockdown() then - local f = self.frame - local count = f:GetAttribute("showgrid") - if show then - count = count + 1 - else - count = count - 1 - end - if count < 0 then - count = 0 - end - f:SetAttribute("showgrid",count) - - if count >= 1 and not f:GetAttribute("statehidden") then - if LBF then - LBF:SetNormalVertexColor(self.frame, 1.0, 1.0, 1.0, 0.5) - else - self.frame:GetNormalTexture():SetVertexColor(1.0, 1.0, 1.0, 0.5); - end - f:Show() - elseif count < 1 and not HasAction(self:GetActionID()) then - f:Hide() - end + -- This is a bit hokey : install a bare hook on ActionButton_UpdateHotkey because + -- even though it's secure it's never called in a way that can cause taint. This is + -- for performance reasons to avoid having to hook frame:OnEvent securely. + local UpdateHotkey_old = ActionButton_UpdateHotkeys + ActionButton_UpdateHotkeys = function( frame, ... ) + local b = frame._reactionButton + if b then + b.hotkey:SetText( GetHotkey(frame) ) + else + return UpdateHotkey_old(frame, ...) end end +end - function Button:ShowActionIDLabel( show ) - local f = self:GetFrame() - if show then - local id = self:GetActionID() - if not f.actionIDLabel then - local label = f:CreateFontString(nil,"OVERLAY","GameFontNormalLarge") - label:SetAllPoints() - label:SetJustifyH("CENTER") - label:SetShadowColor(0,0,0,1) - label:SetShadowOffset(2,-2) - f.actionIDLabel = label -- store the label with the frame for recycling +local meta = {__index = Button} - f:HookScript("OnAttributeChanged", - function(frame, attr, value) - if label:IsVisible() and attr:match("action") then - label:SetText(tostring(frame.action)) - end - end) +function Button:New( handle, idx, config, barConfig ) + local bar = handle.bar + + -- create new self + self = setmetatable( + { + bar = bar, + idx = idx, + config = config, + barConfig = barConfig, + }, meta ) + + local name = config.name or ("ReAction_%s_%s_%d"):format(bar:GetName(),moduleID,idx) + self.name = name + config.name = name + local lastButton = handle:GetLastButton() + config.actionID = IDAlloc:Acquire(config.actionID, lastButton and lastButton.config.actionID) -- gets a free one if none configured + self.nPages = 1 + + -- have to recycle frames with the same name: CreateFrame() doesn't overwrite + -- existing globals. Can't set to nil in the global because it's then tainted. + local parent = bar:GetFrame() + local f = frameRecycler[name] + if f then + f:SetParent(parent) + else + f = CreateFrame("CheckButton", name, parent, "ActionBarButtonTemplate") + -- ditch the old hotkey text because it's tied in ActionButton_Update() to the + -- standard binding. + local hotkey = _G[name.."HotKey"] + hotkey:SetParent(trash) + hotkey = f:CreateFontString(nil, "ARTWORK", "NumberFontNormalSmallGray") + hotkey:SetWidth(36) + hotkey:SetHeight(18) + hotkey:SetJustifyH("RIGHT") + hotkey:SetJustifyV("TOP") + hotkey:SetPoint("TOPLEFT",f,"TOPLEFT",-2,-2) + f.hotkey = hotkey + f.icon = _G[name.."Icon"] + f.flash = _G[name.."Flash"] + f:SetScript("OnUpdate",OnUpdate) + end + + f._reactionButton = self + + self.hotkey = f.hotkey + self.border = _G[name.."Border"] + + f:SetAttribute("action", config.actionID) + f:SetAttribute("default-action", config.actionID) + -- install mind control actions for all buttons just for simplicity + if self.idx <= 12 then + f:SetAttribute("mindcontrol-action", 120 + self.idx) + end + + -- set a _childupdate handler, called within the header's context + f:SetAttribute("_childupdate", + -- function _childupdate(self, snippetid, message) + [[ + local action = "default-action" + if doMindControl and GetBonusBarOffset() == 5 then + action = "mindcontrol-action" + elseif page and state and page[state] then + action = "action-"..page[state] end - f.actionIDLabel:SetText(tostring(id)) - f.actionIDLabel:Show() - elseif f.actionIDLabel then - f.actionIDLabel:Hide() + local value = self:GetAttribute(action) + if value then + self:SetAttribute("action",value) + end + ]]) + + -- install drag wrappers to lock buttons + bar:GetFrame():WrapScript(f, "OnDragStart", + -- OnDragStart(self, button, kind, value, ...) + [[ + if lockButtons and (PlayerInCombat() or not lockButtonsCombat) and not IsModifiedClick("PICKUPACTION") then + return "clear" + end + ]]) + + self.frame = f + + -- initialize the hide state + f:SetAttribute("showgrid",0) + self:ShowGrid(not barConfig.hideEmpty) + if ReAction:GetConfigMode() then + self:ShowGrid(true) + end + + -- set the hotkey text + self.hotkey:SetText( GetHotkey(self.frame) ) + + -- show the ID label if applicable + self:ShowActionIDLabel(ReAction:GetConfigMode()) + + -- attach to skinner + bar:SkinButton(self, + { + HotKey = self.hotkey, + } + ) + + self:Refresh() + return self +end + +function Button:Destroy() + local f = self.frame + f:UnregisterAllEvents() + f:Hide() + f:SetParent(UIParent) + f:ClearAllPoints() + if self.name then + frameRecycler[self.name] = f + end + if self.config.actionID then + IDAlloc:Release(self.config.actionID) + end + if self.config.pageactions then + for _, id in ipairs(self.config.pageactions) do + IDAlloc:Release(id) end end + f._reactionButton = nil + self.frame = nil + self.config = nil + self.bar = nil +end - function Button:DisplayHotkey( key ) - self.hotkey:SetText(key or "") +function Button:Refresh() + local f = self.frame + self.bar:PlaceButton(self, 36, 36) + self:RefreshPages() +end + +function Button:GetFrame() + return self.frame +end + +function Button:GetName() + return self.name +end + +function Button:GetConfig() + return self.config +end + +function Button:GetActionID(page) + if page == nil then + -- get the effective ID + return self.frame.action -- kept up-to-date by Blizzard's ActionButton_CalculateAction() + else + if page == 1 then + return self.config.actionID + else + return self.config.pageactions and self.config.pageactions[page] or self.config.actionID + end end end + +function Button:SetActionID( id, page ) + id = tonumber(id) + page = tonumber(page) + if id == nil or id < 1 or id > 120 then + error("Button:SetActionID - invalid action ID") + end + if page and page ~= 1 then + if not self.config.pageactions then + self.config.pageactions = { } + end + if self.config.pageactions[page] then + IDAlloc:Release(self.config.pageactions[page]) + end + self.config.pageactions[page] = id + IDAlloc:Acquire(self.config.pageactions[page]) + self.frame:SetAttribute(("action-page%d"):format(page),id) + else + IDAlloc:Release(self.config.actionID) + self.config.actionID = id + IDAlloc:Acquire(self.config.actionID) + self.frame:SetAttribute("action",id) + if self.config.pageactions then + self.config.pageactions[1] = id + self.frame:SetAttribute("action-page1",id) + end + end +end + +function Button:RefreshPages( force ) + local nPages = self.barConfig.nPages + if nPages and (nPages ~= self.nPages or force) then + local f = self:GetFrame() + local c = self.config.pageactions + if nPages > 1 and not c then + c = { } + self.config.pageactions = c + end + for i = 1, nPages do + if i > 1 then + c[i] = IDAlloc:Acquire(c[i], self.config.actionID + (i-1)*self.bar:GetNumButtons()) + else + c[i] = self.config.actionID -- page 1 is the same as the base actionID + end + f:SetAttribute(("action-page%d"):format(i),c[i]) + end + for i = nPages+1, #c do + IDAlloc:Release(c[i]) + c[i] = nil + f:SetAttribute(("action-page%d"):format(i),nil) + end + self.nPages = nPages + end +end + +function Button:ShowGrid( show ) + if not InCombatLockdown() then + local f = self.frame + local count = f:GetAttribute("showgrid") + if show then + count = count + 1 + else + count = count - 1 + end + if count < 0 then + count = 0 + end + f:SetAttribute("showgrid",count) + + if count >= 1 and not f:GetAttribute("statehidden") then + if LBF then + LBF:SetNormalVertexColor(self.frame, 1.0, 1.0, 1.0, 0.5) + else + self.frame:GetNormalTexture():SetVertexColor(1.0, 1.0, 1.0, 0.5); + end + f:Show() + elseif count < 1 and not HasAction(self:GetActionID()) then + f:Hide() + end + end +end + +function Button:ShowActionIDLabel( show ) + local f = self:GetFrame() + if show then + local id = self:GetActionID() + if not f.actionIDLabel then + local label = f:CreateFontString(nil,"OVERLAY","GameFontNormalLarge") + label:SetAllPoints() + label:SetJustifyH("CENTER") + label:SetShadowColor(0,0,0,1) + label:SetShadowOffset(2,-2) + f.actionIDLabel = label -- store the label with the frame for recycling + + f:HookScript("OnAttributeChanged", + function(frame, attr, value) + if label:IsVisible() and attr:match("action") then + label:SetText(tostring(frame.action)) + end + end) + end + f.actionIDLabel:SetText(tostring(id)) + f.actionIDLabel:Show() + elseif f.actionIDLabel then + f.actionIDLabel:Hide() + end +end + +function Button:SetKeybindMode( mode ) + if mode then + KBAttach( self ) + -- set the border for all buttons to the keybind-enable color + self.border:SetVertexColor(KB:GetColorKeyBoundMode()) + self.border:Show() + elseif IsEquippedAction(self:GetActionID()) then + self.border:SetVertexColor(0, 1.0, 0, 0.35) -- from ActionButton.lua + else + self.border:Hide() + end +end \ No newline at end of file
--- a/modules/PetAction.lua Fri Jan 23 23:40:13 2009 +0000 +++ b/modules/PetAction.lua Fri Jan 23 23:44:55 2009 +0000 @@ -296,90 +296,22 @@ local frameRecycler = {} local trash = CreateFrame("Frame") -local KBAttach, GetActionName, GetHotkey, SetKey, FreeKey, ClearBindings, GetBindings, OnEnter, OnLeave -do - local buttonLookup = setmetatable({},{__mode="kv"}) - -- Use KeyBound-1.0 for binding, but use Override bindings instead of - -- regular bindings to support multiple profile use. This is a little - -- weird with the KeyBound dialog box (which has per-char selector as well - -- as an OK/Cancel box) but it's the least amount of effort to implement. - function GetActionName(f) - local b = buttonLookup[f] - if b then - return format("%s:%s", b.bar:GetName(), b.idx) - end +local function GetActionName(f) + local b = f and f._reactionButton + if b then + return format("%s:%s", b.bar:GetName(), b.idx) end +end - function GetHotkey(f) - local b = buttonLookup[f] - if b then - return KB:ToShortKey(b:GetConfig().hotkey) - end - end +local function GetHotkey(f) + return KB:ToShortKey(GetBindingKey(format("CLICK %s:LeftButton",f:GetName()))) +end - function SetKey(f, key) - local b = buttonLookup[f] - if b then - local c = b:GetConfig() - if c.hotkey then - SetOverrideBinding(f, false, c.hotkey, nil) - end - if key then - SetOverrideBindingClick(f, false, key, f:GetName(), nil) - end - c.hotkey = key - b:DisplayHotkey(GetHotkey(f)) - end - end - - function FreeKey(f, key) - local b = buttonLookup[f] - if b then - local c = b:GetConfig() - if c.hotkey == key then - local action = f:GetActionName() - SetOverrideBinding(f, false, c.hotkey, nil) - c.hotkey = nil - b:DisplayHotkey(nil) - return action - end - end - return ReAction:FreeOverrideHotkey(key) - end - - function ClearBindings(f) - SetKey(f, nil) - end - - function GetBindings(f) - local b = buttonLookup[f] - if b then - return b:GetConfig().hotkey - end - end - - function KBAttach( button ) - local f = button:GetFrame() - f.GetActionName = GetActionName - f.GetHotkey = GetHotkey - f.SetKey = SetKey - f.FreeKey = FreeKey - f.ClearBindings = ClearBindings - f.GetBindings = GetBindings - buttonLookup[f] = button - f:SetKey(button:GetConfig().hotkey) - ReAction:RegisterKeybindFrame(f) - if ReAction:GetKeybindMode() then - button.border:SetVertexColor(KB:GetColorKeyBoundMode()) - button.border:Show() - end - end - - function OnEnter( self ) - if not self.tooltipName then - return; - end +local function OnEnter( self ) + if ReAction:GetKeybindMode() then + KB:Set(self) + elseif self.tooltipName then local uber = GetCVar("UberTooltips") if self.isToken or (uber == "0") then if uber == "0" then @@ -387,12 +319,7 @@ else GameTooltip_SetDefaultAnchor(GameTooltip, self) end - local tooltip = self.tooltipName - local k = GetBindings(self) - if k then - tooltip = tooltip .. format(" %s(%s)%s", NORMAL_FONT_COLOR_CODE, k, FONT_COLOR_CODE_CLOSE) - end - GameTooltip:SetText(tooltip) + GameTooltip:SetText(self.tooltipName) if self.tooltipSubtext then GameTooltip:AddLine(self.tooltipSubtext, "", 0.5, 0.5, 0.5) end @@ -402,11 +329,10 @@ GameTooltip:SetPetAction(self:GetID()) end end +end - function OnLeave() - GameTooltip:Hide() - end - +local function OnLeave() + GameTooltip:Hide() end local meta = { __index = Button } @@ -424,7 +350,7 @@ config.name = name self.name = name config.actionID = ActionIDList[config.actionID] -- gets a free one if none configured - + -- have to recycle frames with the same name: -- otherwise you either get references to old textures because named CreateFrame() -- doesn't overwrite existing globals. Can't set them to nil in the global table, @@ -463,15 +389,16 @@ self.hotkey = f.hotkey self.border = _G[("%sBorder"):format(name)] + f._reactionButton = self - f:RegisterEvent("PLAYER_CONTROL_LOST"); - f:RegisterEvent("PLAYER_CONTROL_GAINED"); - f:RegisterEvent("PLAYER_FARSIGHT_FOCUS_CHANGED"); - f:RegisterEvent("UNIT_PET"); - f:RegisterEvent("UNIT_FLAGS"); - f:RegisterEvent("UNIT_AURA"); - f:RegisterEvent("PET_BAR_UPDATE"); - f:RegisterEvent("PET_BAR_UPDATE_COOLDOWN"); + f:RegisterEvent("PLAYER_CONTROL_LOST") + f:RegisterEvent("PLAYER_CONTROL_GAINED") + f:RegisterEvent("PLAYER_FARSIGHT_FOCUS_CHANGED") + f:RegisterEvent("UNIT_PET") + f:RegisterEvent("UNIT_FLAGS") + f:RegisterEvent("UNIT_AURA") + f:RegisterEvent("PET_BAR_UPDATE") + f:RegisterEvent("PET_BAR_UPDATE_COOLDOWN") f:SetScript("OnEvent", function(event,arg1) @@ -493,8 +420,6 @@ end ]]) - KBAttach(self) - -- attach to skinner bar:SkinButton(self, { @@ -503,6 +428,7 @@ ) self:Refresh() + self:UpdateHotkey() self:SetKeybindMode(ReAction:GetKeybindMode()) return self @@ -521,6 +447,7 @@ if self.config.actionID then ActionIDList[self.config.actionID] = nil end + f._reactionButton = nil self.frame = nil self.config = nil self.bar = nil @@ -551,26 +478,25 @@ function Button:Update() local id = self.frame:GetID() - local name, subtext, texture, isToken, isActive, autoCastAllowed, autoCastEnabled = GetPetActionInfo(id); + local name, subtext, texture, isToken, isActive, autoCastAllowed, autoCastEnabled = GetPetActionInfo(id) local f = self.frame - --ReAction:Print(("id %d: '%s', '%s', '%s', '%s', '%s', '%s', '%s'"):format(tostring(id), tostring(name),tostring(subtext),tostring(texture),tostring(isToken),tostring(isActive),tostring(autoCastAllowed),tostring(autoCastEnabled))) if isToken then - self.icon:SetTexture(_G[texture]); - f.tooltipName = _G[name]; + self.icon:SetTexture(_G[texture]) + f.tooltipName = _G[name] else - self.icon:SetTexture(texture); - f.tooltipName = name; + self.icon:SetTexture(texture) + f.tooltipName = name end - f.isToken = isToken; - f.tooltipSubtext = subtext; - f:SetChecked( isActive and 1 or 0); + f.isToken = isToken + f.tooltipSubtext = subtext + f:SetChecked( isActive and 1 or 0) if autoCastAllowed then - self.acTex:Show(); + self.acTex:Show() else - self.acTex:Hide(); + self.acTex:Hide() end if autoCastEnabled then @@ -585,23 +511,23 @@ else SetDesaturation(self.icon,1) end - self.icon:Show(); - f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2"); + self.icon:Show() + f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot2") else - self.icon:Hide(); - f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot"); + self.icon:Hide() + f:SetNormalTexture("Interface\\Buttons\\UI-Quickslot") end self:UpdateCooldown() end function Button:UpdateCooldown() - local start, duration, enable = GetPetActionCooldown(self.frame:GetID()); - CooldownFrame_SetTimer(self.cooldown, start, duration, enable); + local start, duration, enable = GetPetActionCooldown(self.frame:GetID()) + CooldownFrame_SetTimer(self.cooldown, start, duration, enable) end function Button:UpdateHotkey() - self:DisplayHotkey(GetHotkey(self.frame)) + self.hotkey:SetText(GetHotkey(self.frame) or "") end function Button:ShowActionIDLabel(show) @@ -625,6 +551,9 @@ function Button:SetKeybindMode(mode) if mode then + local f = self.frame + f.GetActionName = GetActionName + f.GetHotkey = GetHotkey self.border:SetVertexColor(KB:GetColorKeyBoundMode()) self.border:Show() else @@ -632,6 +561,3 @@ end end -function Button:DisplayHotkey( key ) - self.hotkey:SetText(key or "") -end