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 }
|