annotate modules/ReAction_Action/ReAction_Action.lua @ 60:44649a10378d

Fixed options handling to create a separate table for each bar instead of a shared table with proxy handler. Also simplified options registration and moved some options around.
author Flick <flickerstreak@gmail.com>
date Sat, 10 May 2008 00:08:01 +0000
parents 7430a8dd4e90
children 768be7eb22a0
rev   line source
flickerstreak@24 1 --[[
flickerstreak@53 2 ReAction Action button module.
flickerstreak@24 3
flickerstreak@24 4 The button module implements standard action button functionality by wrapping Blizzard's
flickerstreak@24 5 ActionButton frame and associated functions. It also provides some button layout
flickerstreak@24 6 modification tools.
flickerstreak@24 7
flickerstreak@24 8 --]]
flickerstreak@24 9
flickerstreak@24 10 -- local imports
flickerstreak@24 11 local ReAction = ReAction
flickerstreak@24 12 local L = ReAction.L
flickerstreak@24 13 local _G = _G
flickerstreak@24 14 local CreateFrame = CreateFrame
flickerstreak@24 15
flickerstreak@24 16 -- module declaration
flickerstreak@24 17 local moduleID = "Action"
flickerstreak@28 18 local module = ReAction:NewModule( moduleID )
flickerstreak@24 19
flickerstreak@24 20 -- module methods
flickerstreak@24 21 function module:OnInitialize()
flickerstreak@28 22 self.db = ReAction.db:RegisterNamespace( moduleID,
flickerstreak@24 23 {
flickerstreak@28 24 profile = {
flickerstreak@28 25 buttons = { }
flickerstreak@28 26 }
flickerstreak@24 27 }
flickerstreak@24 28 )
flickerstreak@24 29 self.buttons = { }
flickerstreak@60 30 self.options = setmetatable({},{__mode="k"})
flickerstreak@49 31
flickerstreak@60 32 ReAction:RegisterOptions(self, {
flickerstreak@60 33 [moduleID] = {
flickerstreak@60 34 type = "group",
flickerstreak@60 35 name = L["Action Bars"],
flickerstreak@60 36 args = {
flickerstreak@60 37 hideEmpty = {
flickerstreak@60 38 type = "toggle",
flickerstreak@60 39 name = L["Hide Empty Buttons"],
flickerstreak@60 40 get = function() return self.db.profile.hideEmptyButtons end,
flickerstreak@60 41 set = function(info, val) module:SetHideEmptyButtons(val) end,
flickerstreak@60 42 }
flickerstreak@60 43 }
flickerstreak@60 44 }
flickerstreak@60 45 })
flickerstreak@24 46 end
flickerstreak@24 47
flickerstreak@24 48 function module:OnEnable()
flickerstreak@53 49 ReAction:RegisterBarType(L["Action Bar"],
flickerstreak@53 50 {
flickerstreak@53 51 type = moduleID,
flickerstreak@53 52 defaultButtonSize = 36,
flickerstreak@53 53 defaultBarRows = 1,
flickerstreak@53 54 defaultBarCols = 12,
flickerstreak@53 55 defaultBarSpacing = 3
flickerstreak@53 56 }, true)
flickerstreak@24 57 end
flickerstreak@24 58
flickerstreak@24 59 function module:OnDisable()
flickerstreak@53 60 ReAction:UnregisterBarType(L["Action Bar"])
flickerstreak@24 61 end
flickerstreak@24 62
flickerstreak@24 63 function module:ApplyToBar(bar)
flickerstreak@52 64 self:RefreshBar(bar)
flickerstreak@24 65 end
flickerstreak@24 66
flickerstreak@24 67 function module:RefreshBar(bar)
flickerstreak@53 68 if bar.config.type == moduleID then
flickerstreak@48 69 if self.buttons[bar] == nil then
flickerstreak@48 70 self.buttons[bar] = { }
flickerstreak@48 71 end
flickerstreak@48 72 local btns = self.buttons[bar]
flickerstreak@48 73 local profile = self.db.profile
flickerstreak@48 74 local barName = bar:GetName()
flickerstreak@48 75 if profile.buttons[barName] == nil then
flickerstreak@48 76 profile.buttons[barName] = {}
flickerstreak@48 77 end
flickerstreak@48 78 local btnCfg = profile.buttons[barName]
flickerstreak@24 79
flickerstreak@48 80 local r, c = bar:GetButtonGrid()
flickerstreak@48 81 local n = r*c
flickerstreak@48 82 for i = 1, n do
flickerstreak@48 83 if btnCfg[i] == nil then
flickerstreak@48 84 btnCfg[i] = {}
flickerstreak@48 85 end
flickerstreak@48 86 if btns[i] == nil then
flickerstreak@52 87 local ok, b = pcall(self.BtnClass.new, self.BtnClass, bar, i, btnCfg[i])
flickerstreak@52 88 if ok and b then
flickerstreak@52 89 btns[i] = b
flickerstreak@52 90 end
flickerstreak@48 91 else
flickerstreak@48 92 btns[i]:Refresh(bar,i)
flickerstreak@48 93 end
flickerstreak@24 94 end
flickerstreak@48 95 for i = n+1, #btns do
flickerstreak@52 96 if btns[i] then
flickerstreak@52 97 btns[i] = btns[i]:Destroy()
flickerstreak@52 98 if btnCfg[i] then
flickerstreak@52 99 btnCfg[i] = nil
flickerstreak@52 100 end
flickerstreak@48 101 end
flickerstreak@24 102 end
flickerstreak@24 103 end
flickerstreak@24 104 end
flickerstreak@24 105
flickerstreak@24 106 function module:RemoveFromBar(bar)
flickerstreak@24 107 if self.buttons[bar] then
flickerstreak@24 108 local btns = self.buttons[bar]
flickerstreak@24 109 for _,b in pairs(btns) do
flickerstreak@24 110 if b then
flickerstreak@24 111 b:Destroy()
flickerstreak@24 112 end
flickerstreak@24 113 end
flickerstreak@24 114 self.buttons[bar] = nil
flickerstreak@24 115 end
flickerstreak@24 116 end
flickerstreak@24 117
flickerstreak@24 118 function module:EraseBarConfig(barName)
flickerstreak@24 119 self.db.profile.buttons[barName] = nil
flickerstreak@24 120 end
flickerstreak@24 121
flickerstreak@48 122 function module:RenameBarConfig(oldname, newname)
flickerstreak@48 123 local b = self.db.profile.buttons
flickerstreak@48 124 b[newname], b[oldname] = b[oldname], nil
flickerstreak@48 125 end
flickerstreak@48 126
flickerstreak@49 127 function module:SetHideEmptyButtons(hide)
flickerstreak@49 128 if hide ~= self.db.profile.hideEmptyButtons then
flickerstreak@49 129 for _, bar in pairs(self.buttons) do
flickerstreak@49 130 for _, b in pairs(bar) do
flickerstreak@49 131 if hide then
flickerstreak@49 132 ActionButton_HideGrid(b.frame)
flickerstreak@49 133 else
flickerstreak@49 134 ActionButton_ShowGrid(b.frame)
flickerstreak@49 135 end
flickerstreak@49 136 end
flickerstreak@49 137 end
flickerstreak@49 138 self.db.profile.hideEmptyButtons = hide
flickerstreak@49 139 end
flickerstreak@49 140 end
flickerstreak@49 141
flickerstreak@24 142 function module:ApplyConfigMode(mode,bars)
flickerstreak@49 143 for _, bar in pairs(bars) do
flickerstreak@49 144 if bar and self.buttons[bar] then
flickerstreak@49 145 for _, b in pairs(self.buttons[bar]) do
flickerstreak@24 146 if b then
flickerstreak@24 147 if mode then
flickerstreak@49 148 ActionButton_ShowGrid(b.frame)
flickerstreak@50 149 self:showActionIDLabel(b)
flickerstreak@49 150 else
flickerstreak@49 151 ActionButton_HideGrid(b.frame)
flickerstreak@50 152 self:hideActionIDLabel(b)
flickerstreak@24 153 end
flickerstreak@24 154 end
flickerstreak@24 155 end
flickerstreak@24 156 end
flickerstreak@24 157 end
flickerstreak@24 158 end
flickerstreak@24 159
flickerstreak@50 160 function module:showActionIDLabel(button)
flickerstreak@52 161 if not button.actionIDLabel and button:GetActionID() then
flickerstreak@50 162 local label = button:GetFrame():CreateFontString(nil,"OVERLAY","GameFontNormalLarge")
flickerstreak@50 163 label:SetAllPoints()
flickerstreak@50 164 label:SetJustifyH("CENTER")
flickerstreak@50 165 label:SetShadowColor(0,0,0,1)
flickerstreak@50 166 label:SetShadowOffset(2,-2)
flickerstreak@50 167 label:SetText(tostring(button:GetActionID()))
flickerstreak@50 168 button.actionIDLabel = label
flickerstreak@50 169 end
flickerstreak@50 170 button.actionIDLabel:Show()
flickerstreak@50 171 end
flickerstreak@50 172
flickerstreak@50 173 function module:hideActionIDLabel(button)
flickerstreak@50 174 if button.actionIDLabel then
flickerstreak@50 175 button.actionIDLabel:Hide()
flickerstreak@50 176 end
flickerstreak@50 177 end
flickerstreak@50 178
flickerstreak@50 179
flickerstreak@60 180 ---- Options ----
flickerstreak@60 181 function module:GetBarOptions(bar)
flickerstreak@60 182 if not self.options[bar] then
flickerstreak@60 183 self.options[bar] = {
flickerstreak@60 184 type = "group",
flickerstreak@60 185 name = L["Action Buttons"],
flickerstreak@60 186 hidden = function() return bar.config.type ~= moduleID end,
flickerstreak@60 187 args = {
flickerstreak@60 188 }
flickerstreak@60 189 }
flickerstreak@60 190 end
flickerstreak@60 191 return self.options[bar]
flickerstreak@59 192 end
flickerstreak@59 193
flickerstreak@50 194
flickerstreak@24 195 -- use-count of action IDs
flickerstreak@53 196 local nActionIDs = 120
flickerstreak@24 197 local ActionIDList = setmetatable( {}, {
flickerstreak@24 198 __index = function(self, idx)
flickerstreak@24 199 if idx == nil then
flickerstreak@53 200 for i = 1, nActionIDs do
flickerstreak@24 201 if rawget(self,i) == nil then
flickerstreak@24 202 rawset(self,i,1)
flickerstreak@24 203 return i
flickerstreak@24 204 end
flickerstreak@24 205 end
flickerstreak@52 206 error("ran out of action IDs")
flickerstreak@24 207 else
flickerstreak@24 208 local c = rawget(self,idx) or 0
flickerstreak@24 209 rawset(self,idx,c+1)
flickerstreak@24 210 return idx
flickerstreak@24 211 end
flickerstreak@24 212 end,
flickerstreak@24 213 __newindex = function(self,idx,value)
flickerstreak@24 214 if value == nil then
flickerstreak@24 215 value = rawget(self,idx)
flickerstreak@24 216 if value == 1 then
flickerstreak@24 217 value = nil
flickerstreak@24 218 elseif value then
flickerstreak@24 219 value = value - 1
flickerstreak@24 220 end
flickerstreak@24 221 end
flickerstreak@24 222 rawset(self,idx,value)
flickerstreak@24 223 end
flickerstreak@24 224 })
flickerstreak@24 225
flickerstreak@24 226
flickerstreak@24 227
flickerstreak@28 228
flickerstreak@28 229 ------ Button class ------
flickerstreak@28 230 local Button = { }
flickerstreak@28 231
flickerstreak@28 232 local function Constructor( self, bar, idx, config )
flickerstreak@24 233 self.bar, self.idx, self.config = bar, idx, config
flickerstreak@24 234
flickerstreak@24 235 local barFrame = bar:GetFrame()
flickerstreak@24 236
flickerstreak@56 237 config.name = config.name or ("ReAction_%s_%d"):format(bar:GetName(),idx)
flickerstreak@49 238 self.name = config.name
flickerstreak@24 239 config.actionID = ActionIDList[config.actionID] -- gets a free one if none configured
flickerstreak@24 240
flickerstreak@24 241 local f = CreateFrame("CheckButton", self.name, barFrame, "ActionBarButtonTemplate")
flickerstreak@49 242
flickerstreak@24 243 -- TODO: re-implement ActionButton event handlers that don't do secure stuff
flickerstreak@24 244
flickerstreak@24 245 -- this will probably cause taint, using right now for display/debugging purposes
flickerstreak@30 246 f:SetScript("OnAttributeChanged", ActionButton_UpdateAction)
flickerstreak@24 247 f:SetAttribute("action", config.actionID)
flickerstreak@49 248
flickerstreak@24 249 barFrame:SetAttribute("addchild",f)
flickerstreak@49 250
flickerstreak@24 251 self.frame = f
flickerstreak@24 252 self:Refresh(bar,idx)
flickerstreak@49 253
flickerstreak@49 254 if not module.db.profile.hideEmptyButtons then
flickerstreak@49 255 ActionButton_ShowGrid(self.frame)
flickerstreak@49 256 end
flickerstreak@50 257
flickerstreak@50 258 if ReAction.configMode then
flickerstreak@50 259 ActionButton_ShowGrid(self.frame)
flickerstreak@50 260 module:showActionIDLabel(self)
flickerstreak@50 261 end
flickerstreak@24 262 end
flickerstreak@24 263
flickerstreak@24 264 function Button:Destroy()
flickerstreak@24 265 local f = self.frame
flickerstreak@24 266 f:UnregisterAllEvents()
flickerstreak@24 267 f:Hide()
flickerstreak@24 268 f:SetParent(UIParent)
flickerstreak@24 269 f:ClearAllPoints()
flickerstreak@28 270 if self.name then
flickerstreak@28 271 _G[self.name] = nil
flickerstreak@24 272 end
flickerstreak@52 273 if self.config.actionID then
flickerstreak@52 274 ActionIDList[self.config.actionID] = nil
flickerstreak@52 275 end
flickerstreak@24 276 self.frame = nil
flickerstreak@24 277 self.config = nil
flickerstreak@24 278 self.bar = nil
flickerstreak@24 279 end
flickerstreak@24 280
flickerstreak@24 281 function Button:Refresh(bar,idx)
flickerstreak@24 282 bar:PlaceButton(self.frame, idx, 36, 36)
flickerstreak@24 283 end
flickerstreak@24 284
flickerstreak@24 285 function Button:GetFrame()
flickerstreak@24 286 return self.frame
flickerstreak@24 287 end
flickerstreak@24 288
flickerstreak@24 289 function Button:GetName()
flickerstreak@24 290 return self.name
flickerstreak@24 291 end
flickerstreak@24 292
flickerstreak@24 293 function Button:GetActionID()
flickerstreak@24 294 return self.config.actionID
flickerstreak@24 295 end
flickerstreak@28 296
flickerstreak@28 297
flickerstreak@28 298 -- export as a class-factory to module
flickerstreak@28 299 module.BtnClass = {
flickerstreak@28 300 new = function(self, ...)
flickerstreak@28 301 local x = { }
flickerstreak@28 302 for k,v in pairs(Button) do
flickerstreak@28 303 x[k] = v
flickerstreak@28 304 end
flickerstreak@28 305 Constructor(x, ...)
flickerstreak@28 306 return x
flickerstreak@28 307 end
flickerstreak@28 308 }