annotate modules/ReAction_Action/ReAction_Action.lua @ 69:a785d6708388

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