annotate classes/Button.lua @ 128:729232aeeb5e

Action Button rewrite. (note: pet actions are probably slightly broken right now, they haven't been updated yet)
author Flick <flickerstreak@gmail.com>
date Thu, 05 Mar 2009 01:28:48 +0000
parents 6a4b4d3c5fad
children 28b430de5875
rev   line source
flickerstreak@122 1 --[[
flickerstreak@122 2 ReAction Button base class
flickerstreak@122 3 --]]
flickerstreak@122 4
flickerstreak@122 5 -- local imports
flickerstreak@122 6 local ReAction = ReAction
flickerstreak@122 7 local L = ReAction.L
flickerstreak@122 8 local _G = _G
flickerstreak@122 9 local CreateFrame = CreateFrame
flickerstreak@122 10 local GetBindingKey = GetBindingKey
flickerstreak@122 11 local format = string.format
flickerstreak@122 12
flickerstreak@122 13 ReAction:UpdateRevision("$Revision: 154 $")
flickerstreak@122 14
flickerstreak@122 15 -- libraries
flickerstreak@122 16 local KB = LibStub("LibKeyBound-1.0")
flickerstreak@122 17 local LBF = LibStub("LibButtonFacade",true) -- optional
flickerstreak@122 18
flickerstreak@122 19 -- private
flickerstreak@122 20 local trash = CreateFrame("Frame")
flickerstreak@122 21 local frameList = { }
flickerstreak@122 22 local idPools = { }
flickerstreak@122 23
flickerstreak@122 24 local function kb_onEnter( frame )
flickerstreak@122 25 KB:Set(frame)
flickerstreak@122 26 end
flickerstreak@122 27
flickerstreak@122 28 -- Button class
flickerstreak@122 29 local Button = { }
flickerstreak@122 30
flickerstreak@122 31 ReAction.Button = Button -- export to ReAction
flickerstreak@122 32
flickerstreak@128 33 function Button:New( name, barConfig, bar, idx, inherits, buttonType )
flickerstreak@122 34 buttonType = buttonType or "CheckButton"
flickerstreak@122 35
flickerstreak@122 36 -- create new self
flickerstreak@122 37 self = setmetatable(
flickerstreak@122 38 {
flickerstreak@122 39 bar = bar,
flickerstreak@122 40 idx = idx,
flickerstreak@128 41 barConfig = barConfig,
flickerstreak@128 42 config = barConfig.buttons[idx],
flickerstreak@122 43 name = name,
flickerstreak@122 44 },
flickerstreak@122 45 { __index = self } )
flickerstreak@122 46
flickerstreak@122 47 -- have to recycle frames with the same name: CreateFrame() doesn't overwrite
flickerstreak@122 48 -- existing globals. Can't set to nil in the global because it's then tainted.
flickerstreak@122 49 -- Caller is responsible for ensuring global uniqueness of names.
flickerstreak@122 50 local f = name and frameList[name]
flickerstreak@122 51 if f then
flickerstreak@122 52 f:SetParent(bar:GetFrame())
flickerstreak@122 53 else
flickerstreak@122 54 f = CreateFrame(buttonType, name, bar:GetFrame(), inherits)
flickerstreak@122 55 if name then
flickerstreak@122 56 frameList[name] = f
flickerstreak@122 57 end
flickerstreak@122 58 end
flickerstreak@122 59
flickerstreak@122 60 self.frame = f
flickerstreak@122 61
flickerstreak@122 62 if config then
flickerstreak@122 63 config.name = name
flickerstreak@122 64 end
flickerstreak@122 65
flickerstreak@122 66 -- install LibKeyBound handlers onto frame
flickerstreak@122 67 function f:GetActionName()
flickerstreak@122 68 return format("%s:%s", bar:GetName(), idx)
flickerstreak@122 69 end
flickerstreak@122 70
flickerstreak@122 71 local clickBinding = format("CLICK %s:LeftButton", name)
flickerstreak@122 72 function f:GetHotkey()
flickerstreak@122 73 return KB:ToShortKey(GetBindingKey(clickBinding))
flickerstreak@122 74 end
flickerstreak@122 75
flickerstreak@122 76 return self
flickerstreak@122 77 end
flickerstreak@122 78
flickerstreak@122 79 function Button:Destroy()
flickerstreak@126 80 local f = self:GetFrame()
flickerstreak@126 81 if f then
flickerstreak@126 82 f:Hide()
flickerstreak@126 83 f:SetParent(trash)
flickerstreak@126 84 f:ClearAllPoints()
flickerstreak@126 85 end
flickerstreak@122 86 end
flickerstreak@122 87
flickerstreak@128 88 function Button:GetBar()
flickerstreak@128 89 return self.bar
flickerstreak@128 90 end
flickerstreak@128 91
flickerstreak@122 92 function Button:GetFrame()
flickerstreak@122 93 return self.frame
flickerstreak@122 94 end
flickerstreak@122 95
flickerstreak@122 96 function Button:GetName()
flickerstreak@122 97 return self.name
flickerstreak@122 98 end
flickerstreak@122 99
flickerstreak@122 100 function Button:GetConfig()
flickerstreak@122 101 return self.config
flickerstreak@122 102 end
flickerstreak@122 103
flickerstreak@128 104 function Button:GetBarConfig()
flickerstreak@128 105 -- this is the per-bar Button config structure,
flickerstreak@128 106 -- not the config structure of the bar itself
flickerstreak@128 107 return self.barConfig
flickerstreak@128 108 end
flickerstreak@128 109
flickerstreak@122 110 function Button:GetActionID()
flickerstreak@122 111 -- derived classes should override this
flickerstreak@122 112 return nil
flickerstreak@122 113 end
flickerstreak@122 114
flickerstreak@122 115 function Button:SetActionIDPool( poolID, maxID )
flickerstreak@122 116 self.actionPoolID = poolID
flickerstreak@122 117 self.actionMaxID = maxID
flickerstreak@122 118 end
flickerstreak@122 119
flickerstreak@122 120 function Button:AcquireActionID( id, hint, unique )
flickerstreak@122 121 local poolID = self.actionPoolID
flickerstreak@122 122 local maxID = self.actionMaxID
flickerstreak@122 123 if not poolID or not maxID then
flickerstreak@122 124 error("AcquireActionID: must setup pool first with SetActionIDPool")
flickerstreak@122 125 end
flickerstreak@123 126 local pool = idPools[poolID]
flickerstreak@122 127 if not pool then
flickerstreak@122 128 pool = { nWraps = 0, useCount = { } }
flickerstreak@122 129 for i = 1, maxID do
flickerstreak@122 130 pool.useCount[i] = 0
flickerstreak@122 131 end
flickerstreak@123 132 idPools[poolID] = pool
flickerstreak@122 133 end
flickerstreak@122 134 local useCount = pool.useCount
flickerstreak@122 135 if id == nil then
flickerstreak@122 136 repeat
flickerstreak@126 137 local nWraps = pool.nWraps or 0
flickerstreak@126 138 if hint and (useCount[hint] == nil or useCount[hint] == nWraps) then
flickerstreak@122 139 id = hint
flickerstreak@122 140 else
flickerstreak@122 141 local start = hint or 1
flickerstreak@122 142 for i = start, maxID do
flickerstreak@122 143 if useCount[i] == nil or useCount[i] == nWraps then
flickerstreak@122 144 id = i
flickerstreak@122 145 break
flickerstreak@122 146 end
flickerstreak@122 147 end
flickerstreak@122 148 if not id then
flickerstreak@122 149 for i = 1, start do
flickerstreak@122 150 if useCount[i] == nil or useCount[i] == nWraps then
flickerstreak@122 151 id = i
flickerstreak@122 152 break
flickerstreak@122 153 end
flickerstreak@122 154 end
flickerstreak@122 155 end
flickerstreak@122 156 end
flickerstreak@122 157 if id == nil then
flickerstreak@122 158 if unique then
flickerstreak@122 159 return nil
flickerstreak@122 160 end
flickerstreak@122 161 pool.nWraps = nWraps + 1
flickerstreak@122 162 end
flickerstreak@126 163 until id ~= nil
flickerstreak@122 164 end
flickerstreak@122 165 useCount[id] = (useCount[id] or 0) + 1
flickerstreak@122 166 return id
flickerstreak@122 167 end
flickerstreak@122 168
flickerstreak@122 169 function Button:ReleaseActionID( id )
flickerstreak@122 170 local poolID = self.actionPoolID
flickerstreak@122 171 if not poolID then
flickerstreak@122 172 error("ReleaseActionID: must setup pool first with SetActionIDPool")
flickerstreak@122 173 end
flickerstreak@123 174 local pool = idPools[poolID]
flickerstreak@122 175 if pool and id and pool.useCount[id] then
flickerstreak@122 176 pool.useCount[id] = pool.useCount[id] - 1
flickerstreak@122 177 pool.nWraps = min(pool.useCount[id], pool.nWraps)
flickerstreak@122 178 end
flickerstreak@122 179 end
flickerstreak@122 180
flickerstreak@122 181 function Button:Refresh()
flickerstreak@122 182 self.bar:PlaceButton( self, self.frame:GetWidth(), self.frame:GetHeight() )
flickerstreak@122 183 end
flickerstreak@122 184
flickerstreak@122 185 function Button:SetKeybindMode( mode )
flickerstreak@122 186 local f = self.frame
flickerstreak@122 187 if mode then
flickerstreak@122 188 self.oldOnEnter = f:GetScript("OnEnter")
flickerstreak@122 189 f:SetScript("OnEnter", kb_onEnter)
flickerstreak@124 190 elseif self.oldOnEnter then
flickerstreak@122 191 f:SetScript("OnEnter", self.oldOnEnter)
flickerstreak@122 192 self.oldOnEnter = nil
flickerstreak@122 193 end
flickerstreak@128 194 self:ShowGridTemp(mode)
flickerstreak@122 195 self:UpdateKeybindModeDisplay( mode )
flickerstreak@122 196 end
flickerstreak@122 197
flickerstreak@122 198 function Button:UpdateKeybindModeDisplay( mode )
flickerstreak@122 199 self.border = self.border or _G[format("%sBorder",tostring(self:GetName()))]
flickerstreak@122 200 if self.border then
flickerstreak@122 201 if mode then
flickerstreak@122 202 self.border:SetVertexColor(KB:GetColorKeyBoundMode())
flickerstreak@122 203 self.border:Show()
flickerstreak@122 204 else
flickerstreak@122 205 self.border:Hide()
flickerstreak@122 206 end
flickerstreak@122 207 end
flickerstreak@122 208 end
flickerstreak@122 209
flickerstreak@122 210 function Button:UpdateHotkey( hotkey )
flickerstreak@122 211 hotkey = hotkey or self.hotkey
flickerstreak@122 212 if not hotkey then
flickerstreak@122 213 hotkey = _G[format("%sHotKey", tostring(self:GetName()))]
flickerstreak@122 214 self.hotkey = hotkey
flickerstreak@122 215 end
flickerstreak@122 216 if hotkey then
flickerstreak@122 217 local txt = self.frame:GetHotkey()
flickerstreak@122 218 hotkey:SetText( txt )
flickerstreak@122 219 if txt == nil or txt == "" then
flickerstreak@122 220 hotkey:Hide()
flickerstreak@122 221 else
flickerstreak@122 222 hotkey:Show()
flickerstreak@122 223 end
flickerstreak@122 224 end
flickerstreak@122 225 end
flickerstreak@122 226
flickerstreak@122 227 function Button:GetActionIDLabel( create )
flickerstreak@122 228 local f = self.frame
flickerstreak@122 229 if not f.actionIDLabel and create then
flickerstreak@122 230 local label = f:CreateFontString(nil,"OVERLAY","GameFontNormalLarge")
flickerstreak@122 231 label:SetAllPoints()
flickerstreak@122 232 label:SetJustifyH("CENTER")
flickerstreak@122 233 label:SetShadowColor(0,0,0,1)
flickerstreak@122 234 label:SetShadowOffset(2,-2)
flickerstreak@122 235 f.actionIDLabel = label -- store the label with the frame for recycling
flickerstreak@122 236 end
flickerstreak@122 237 return f.actionIDLabel
flickerstreak@122 238 end
flickerstreak@122 239
flickerstreak@122 240 function Button:UpdateActionIDLabel( show )
flickerstreak@122 241 local label = self:GetActionIDLabel( show )
flickerstreak@122 242 if label then
flickerstreak@122 243 if show then
flickerstreak@122 244 local id = self:GetActionID()
flickerstreak@122 245 if id then
flickerstreak@122 246 label:SetText(tostring(id))
flickerstreak@122 247 label:Show()
flickerstreak@122 248 return
flickerstreak@122 249 end
flickerstreak@122 250 end
flickerstreak@122 251 label:Hide()
flickerstreak@122 252 end
flickerstreak@122 253 end
flickerstreak@122 254
flickerstreak@122 255 function Button:SetNormalVertexColor( r, g, b, a )
flickerstreak@122 256 if LBF then
flickerstreak@122 257 LBF:SetNormalVertexColor(self.frame, r, g, b, a)
flickerstreak@122 258 else
flickerstreak@122 259 self.frame:GetNormalTexture():SetVertexColor(r,g,b,a)
flickerstreak@122 260 end
flickerstreak@122 261 end
flickerstreak@122 262
flickerstreak@122 263 function Button:GetNormalVertexColor()
flickerstreak@122 264 if LBF then
flickerstreak@122 265 return LBF:GetNormalVertexColor(self.frame)
flickerstreak@122 266 else
flickerstreak@122 267 return self.frame:GetNormalTexture():GetVertexColor()
flickerstreak@122 268 end
flickerstreak@122 269 end
flickerstreak@122 270
flickerstreak@122 271 function Button:UpdateShowGrid()
flickerstreak@122 272 -- does nothing by default
flickerstreak@122 273 end
flickerstreak@128 274
flickerstreak@128 275 function Button:ShowGridTemp(show)
flickerstreak@128 276 -- does nothing by default
flickerstreak@128 277 end
flickerstreak@128 278
flickerstreak@128 279 function Button:ShowGrid(show)
flickerstreak@128 280 -- does nothing by default
flickerstreak@128 281 end