annotate modules/ReAction_Action/ReAction_Action.lua @ 59:7430a8dd4e90

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