Mercurial > wow > reaction
view classes/Button.lua @ 126:6a4b4d3c5fad
More fixes for button base class
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Tue, 03 Mar 2009 23:18:35 +0000 |
parents | 0c5017f6062d |
children | 729232aeeb5e |
line wrap: on
line source
--[[ ReAction Button base class --]] -- local imports local ReAction = ReAction local L = ReAction.L local _G = _G local CreateFrame = CreateFrame local GetBindingKey = GetBindingKey local format = string.format ReAction:UpdateRevision("$Revision: 154 $") -- libraries local KB = LibStub("LibKeyBound-1.0") local LBF = LibStub("LibButtonFacade",true) -- optional -- private local trash = CreateFrame("Frame") local frameList = { } local idPools = { } local function kb_onEnter( frame ) KB:Set(frame) end -- Button class local Button = { } ReAction.Button = Button -- export to ReAction function Button:New( name, config, bar, idx, inherits, buttonType ) buttonType = buttonType or "CheckButton" -- create new self self = setmetatable( { bar = bar, idx = idx, config = config, name = name, }, { __index = self } ) -- 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. -- Caller is responsible for ensuring global uniqueness of names. local f = name and frameList[name] if f then f:SetParent(bar:GetFrame()) else f = CreateFrame(buttonType, name, bar:GetFrame(), inherits) if name then frameList[name] = f end end self.frame = f if config then config.name = name end -- install LibKeyBound handlers onto frame function f:GetActionName() return format("%s:%s", bar:GetName(), idx) end local clickBinding = format("CLICK %s:LeftButton", name) function f:GetHotkey() return KB:ToShortKey(GetBindingKey(clickBinding)) end return self end function Button:Destroy() local f = self:GetFrame() if f then f:Hide() f:SetParent(trash) f:ClearAllPoints() end 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() -- derived classes should override this return nil end function Button:SetActionIDPool( poolID, maxID ) self.actionPoolID = poolID self.actionMaxID = maxID end function Button:AcquireActionID( id, hint, unique ) local poolID = self.actionPoolID local maxID = self.actionMaxID if not poolID or not maxID then error("AcquireActionID: must setup pool first with SetActionIDPool") end local pool = idPools[poolID] if not pool then pool = { nWraps = 0, useCount = { } } for i = 1, maxID do pool.useCount[i] = 0 end idPools[poolID] = pool end local useCount = pool.useCount if id == nil then repeat local nWraps = pool.nWraps or 0 if hint and (useCount[hint] == nil or useCount[hint] == nWraps) then id = hint else local start = hint or 1 for i = start, maxID do if useCount[i] == nil or useCount[i] == nWraps then id = i break end end if not id then for i = 1, start do if useCount[i] == nil or useCount[i] == nWraps then id = i break end end end end if id == nil then if unique then return nil end pool.nWraps = nWraps + 1 end until id ~= nil end useCount[id] = (useCount[id] or 0) + 1 return id end function Button:ReleaseActionID( id ) local poolID = self.actionPoolID if not poolID then error("ReleaseActionID: must setup pool first with SetActionIDPool") end local pool = idPools[poolID] if pool and id and pool.useCount[id] then pool.useCount[id] = pool.useCount[id] - 1 pool.nWraps = min(pool.useCount[id], pool.nWraps) end end function Button:Refresh() self.bar:PlaceButton( self, self.frame:GetWidth(), self.frame:GetHeight() ) end function Button:SetKeybindMode( mode ) local f = self.frame if mode then self.oldOnEnter = f:GetScript("OnEnter") f:SetScript("OnEnter", kb_onEnter) elseif self.oldOnEnter then f:SetScript("OnEnter", self.oldOnEnter) self.oldOnEnter = nil end self:UpdateKeybindModeDisplay( mode ) end function Button:UpdateKeybindModeDisplay( mode ) self.border = self.border or _G[format("%sBorder",tostring(self:GetName()))] if self.border then if mode then self.border:SetVertexColor(KB:GetColorKeyBoundMode()) self.border:Show() else self.border:Hide() end end end function Button:UpdateHotkey( hotkey ) hotkey = hotkey or self.hotkey if not hotkey then hotkey = _G[format("%sHotKey", tostring(self:GetName()))] self.hotkey = hotkey end if hotkey then local txt = self.frame:GetHotkey() hotkey:SetText( txt ) if txt == nil or txt == "" then hotkey:Hide() else hotkey:Show() end end end function Button:GetActionIDLabel( create ) local f = self.frame if not f.actionIDLabel and create 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 end return f.actionIDLabel end function Button:UpdateActionIDLabel( show ) local label = self:GetActionIDLabel( show ) if label then if show then local id = self:GetActionID() if id then label:SetText(tostring(id)) label:Show() return end end label:Hide() end end function Button:SetNormalVertexColor( r, g, b, a ) if LBF then LBF:SetNormalVertexColor(self.frame, r, g, b, a) else self.frame:GetNormalTexture():SetVertexColor(r,g,b,a) end end function Button:GetNormalVertexColor() if LBF then return LBF:GetNormalVertexColor(self.frame) else return self.frame:GetNormalTexture():GetVertexColor() 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) self:UpdateShowGrid() end end function Button:UpdateShowGrid() -- does nothing by default end