annotate modules/ReAction_Action/ReAction_Action.lua @ 52:c9df7866ff31

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