Mercurial > wow > reaction
diff classes/Button.lua @ 122:a2d2f23137c8
- Rearranged and consolidated some files in modules directory
- Added 'classes' directory, moved Bar and Overlay there
- Added Button, ActionButton, and GridProxy classes, not in use yet
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Mon, 23 Feb 2009 18:56:57 +0000 |
parents | |
children | 943eed2c7def |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/classes/Button.lua Mon Feb 23 18:56:57 2009 +0000 @@ -0,0 +1,277 @@ +--[[ + 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.frame + gridProxy:RemoveGridFrame(f) + f:Hide() + f:SetParent(trash) + f:ClearAllPoints() +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 = pools[poolID] + if not pool then + pool = { nWraps = 0, useCount = { } } + for i = 1, maxID do + pool.useCount[i] = 0 + end + pools[poolID] = pool + end + local useCount = pool.useCount + if id == nil then + repeat + local nWraps = pool.nWraps + if 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 + 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 = pools[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) + else + 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