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@48
|
51 if bar.config.type == "actionbar" then
|
flickerstreak@48
|
52 self:RefreshBar(bar)
|
flickerstreak@48
|
53 end
|
flickerstreak@24
|
54 end
|
flickerstreak@24
|
55
|
flickerstreak@24
|
56 function module:RefreshBar(bar)
|
flickerstreak@48
|
57 if bar.config.type == "actionbar" then
|
flickerstreak@48
|
58 if self.buttons[bar] == nil then
|
flickerstreak@48
|
59 self.buttons[bar] = { }
|
flickerstreak@48
|
60 end
|
flickerstreak@48
|
61 local btns = self.buttons[bar]
|
flickerstreak@48
|
62 local profile = self.db.profile
|
flickerstreak@48
|
63 local barName = bar:GetName()
|
flickerstreak@48
|
64 if profile.buttons[barName] == nil then
|
flickerstreak@48
|
65 profile.buttons[barName] = {}
|
flickerstreak@48
|
66 end
|
flickerstreak@48
|
67 local btnCfg = profile.buttons[barName]
|
flickerstreak@24
|
68
|
flickerstreak@48
|
69 local r, c = bar:GetButtonGrid()
|
flickerstreak@48
|
70 local n = r*c
|
flickerstreak@48
|
71 for i = 1, n do
|
flickerstreak@48
|
72 if btnCfg[i] == nil then
|
flickerstreak@48
|
73 btnCfg[i] = {}
|
flickerstreak@48
|
74 end
|
flickerstreak@48
|
75 if btns[i] == nil then
|
flickerstreak@48
|
76 btns[i] = self.BtnClass:new(bar,i,btnCfg[i])
|
flickerstreak@48
|
77 else
|
flickerstreak@48
|
78 btns[i]:Refresh(bar,i)
|
flickerstreak@48
|
79 end
|
flickerstreak@24
|
80 end
|
flickerstreak@48
|
81 for i = n+1, #btns do
|
flickerstreak@48
|
82 btns[i] = btns[i]:Destroy()
|
flickerstreak@48
|
83 if btnCfg[i] then
|
flickerstreak@48
|
84 btnCfg[i] = nil
|
flickerstreak@48
|
85 end
|
flickerstreak@24
|
86 end
|
flickerstreak@24
|
87 end
|
flickerstreak@24
|
88 end
|
flickerstreak@24
|
89
|
flickerstreak@24
|
90 function module:RemoveFromBar(bar)
|
flickerstreak@24
|
91 if self.buttons[bar] then
|
flickerstreak@24
|
92 local btns = self.buttons[bar]
|
flickerstreak@24
|
93 for _,b in pairs(btns) do
|
flickerstreak@24
|
94 if b then
|
flickerstreak@24
|
95 b:Destroy()
|
flickerstreak@24
|
96 end
|
flickerstreak@24
|
97 end
|
flickerstreak@24
|
98 self.buttons[bar] = nil
|
flickerstreak@24
|
99 end
|
flickerstreak@24
|
100 end
|
flickerstreak@24
|
101
|
flickerstreak@24
|
102 function module:EraseBarConfig(barName)
|
flickerstreak@24
|
103 self.db.profile.buttons[barName] = nil
|
flickerstreak@24
|
104 end
|
flickerstreak@24
|
105
|
flickerstreak@48
|
106 function module:RenameBarConfig(oldname, newname)
|
flickerstreak@48
|
107 local b = self.db.profile.buttons
|
flickerstreak@48
|
108 b[newname], b[oldname] = b[oldname], nil
|
flickerstreak@48
|
109 end
|
flickerstreak@48
|
110
|
flickerstreak@49
|
111 function module:SetHideEmptyButtons(hide)
|
flickerstreak@49
|
112 if hide ~= self.db.profile.hideEmptyButtons then
|
flickerstreak@49
|
113 for _, bar in pairs(self.buttons) do
|
flickerstreak@49
|
114 for _, b in pairs(bar) do
|
flickerstreak@49
|
115 if hide then
|
flickerstreak@49
|
116 ActionButton_HideGrid(b.frame)
|
flickerstreak@49
|
117 else
|
flickerstreak@49
|
118 ActionButton_ShowGrid(b.frame)
|
flickerstreak@49
|
119 end
|
flickerstreak@49
|
120 end
|
flickerstreak@49
|
121 end
|
flickerstreak@49
|
122 self.db.profile.hideEmptyButtons = hide
|
flickerstreak@49
|
123 end
|
flickerstreak@49
|
124 end
|
flickerstreak@49
|
125
|
flickerstreak@24
|
126 function module:ApplyConfigMode(mode,bars)
|
flickerstreak@49
|
127 for _, bar in pairs(bars) do
|
flickerstreak@49
|
128 if bar and self.buttons[bar] then
|
flickerstreak@49
|
129 for _, b in pairs(self.buttons[bar]) do
|
flickerstreak@24
|
130 if b then
|
flickerstreak@24
|
131 if mode then
|
flickerstreak@49
|
132 ActionButton_ShowGrid(b.frame)
|
flickerstreak@24
|
133 if not b.actionIDLabel then
|
flickerstreak@24
|
134 local label = b:GetFrame():CreateFontString(nil,"OVERLAY","GameFontNormalLarge")
|
flickerstreak@24
|
135 label:SetAllPoints()
|
flickerstreak@24
|
136 label:SetJustifyH("CENTER")
|
flickerstreak@24
|
137 label:SetShadowColor(0,0,0,1)
|
flickerstreak@24
|
138 label:SetShadowOffset(2,-2)
|
flickerstreak@24
|
139 label:SetText(tostring(b:GetActionID()))
|
flickerstreak@24
|
140 b.actionIDLabel = label
|
flickerstreak@24
|
141 end
|
flickerstreak@24
|
142 b.actionIDLabel:Show()
|
flickerstreak@49
|
143 else
|
flickerstreak@49
|
144 if b.actionIDLabel then
|
flickerstreak@49
|
145 b.actionIDLabel:Hide()
|
flickerstreak@49
|
146 end
|
flickerstreak@49
|
147 ActionButton_HideGrid(b.frame)
|
flickerstreak@24
|
148 end
|
flickerstreak@49
|
149
|
flickerstreak@24
|
150 end
|
flickerstreak@24
|
151 end
|
flickerstreak@24
|
152 end
|
flickerstreak@24
|
153 end
|
flickerstreak@24
|
154 end
|
flickerstreak@24
|
155
|
flickerstreak@24
|
156 -- use-count of action IDs
|
flickerstreak@24
|
157 local ActionIDList = setmetatable( {}, {
|
flickerstreak@24
|
158 __index = function(self, idx)
|
flickerstreak@24
|
159 if idx == nil then
|
flickerstreak@24
|
160 for i = 1, 120 do
|
flickerstreak@24
|
161 if rawget(self,i) == nil then
|
flickerstreak@24
|
162 rawset(self,i,1)
|
flickerstreak@24
|
163 return i
|
flickerstreak@24
|
164 end
|
flickerstreak@24
|
165 end
|
flickerstreak@24
|
166 else
|
flickerstreak@24
|
167 local c = rawget(self,idx) or 0
|
flickerstreak@24
|
168 rawset(self,idx,c+1)
|
flickerstreak@24
|
169 return idx
|
flickerstreak@24
|
170 end
|
flickerstreak@24
|
171 end,
|
flickerstreak@24
|
172 __newindex = function(self,idx,value)
|
flickerstreak@24
|
173 if value == nil then
|
flickerstreak@24
|
174 value = rawget(self,idx)
|
flickerstreak@24
|
175 if value == 1 then
|
flickerstreak@24
|
176 value = nil
|
flickerstreak@24
|
177 elseif value then
|
flickerstreak@24
|
178 value = value - 1
|
flickerstreak@24
|
179 end
|
flickerstreak@24
|
180 end
|
flickerstreak@24
|
181 rawset(self,idx,value)
|
flickerstreak@24
|
182 end
|
flickerstreak@24
|
183 })
|
flickerstreak@24
|
184
|
flickerstreak@24
|
185
|
flickerstreak@24
|
186
|
flickerstreak@28
|
187
|
flickerstreak@28
|
188 ------ Button class ------
|
flickerstreak@28
|
189 local Button = { }
|
flickerstreak@28
|
190
|
flickerstreak@28
|
191 local function Constructor( self, bar, idx, config )
|
flickerstreak@24
|
192 self.bar, self.idx, self.config = bar, idx, config
|
flickerstreak@24
|
193
|
flickerstreak@24
|
194 local barFrame = bar:GetFrame()
|
flickerstreak@24
|
195
|
flickerstreak@49
|
196 config.name = config.name or "ReAction_"..bar:GetName().."_"..idx
|
flickerstreak@49
|
197 self.name = config.name
|
flickerstreak@24
|
198 config.actionID = ActionIDList[config.actionID] -- gets a free one if none configured
|
flickerstreak@24
|
199
|
flickerstreak@24
|
200 local f = CreateFrame("CheckButton", self.name, barFrame, "ActionBarButtonTemplate")
|
flickerstreak@49
|
201
|
flickerstreak@24
|
202 -- TODO: re-implement ActionButton event handlers that don't do secure stuff
|
flickerstreak@24
|
203
|
flickerstreak@24
|
204 -- this will probably cause taint, using right now for display/debugging purposes
|
flickerstreak@30
|
205 f:SetScript("OnAttributeChanged", ActionButton_UpdateAction)
|
flickerstreak@24
|
206 f:SetAttribute("action", config.actionID)
|
flickerstreak@49
|
207
|
flickerstreak@24
|
208 barFrame:SetAttribute("addchild",f)
|
flickerstreak@49
|
209
|
flickerstreak@24
|
210 self.frame = f
|
flickerstreak@24
|
211 self:Refresh(bar,idx)
|
flickerstreak@49
|
212
|
flickerstreak@49
|
213 if not module.db.profile.hideEmptyButtons then
|
flickerstreak@49
|
214 ActionButton_ShowGrid(self.frame)
|
flickerstreak@49
|
215 end
|
flickerstreak@24
|
216 end
|
flickerstreak@24
|
217
|
flickerstreak@24
|
218 function Button:Destroy()
|
flickerstreak@24
|
219 local f = self.frame
|
flickerstreak@24
|
220 f:UnregisterAllEvents()
|
flickerstreak@24
|
221 f:Hide()
|
flickerstreak@24
|
222 f:SetParent(UIParent)
|
flickerstreak@24
|
223 f:ClearAllPoints()
|
flickerstreak@28
|
224 if self.name then
|
flickerstreak@28
|
225 _G[self.name] = nil
|
flickerstreak@24
|
226 end
|
flickerstreak@24
|
227 ActionIDList[self.config.actionID] = nil
|
flickerstreak@24
|
228 self.frame = nil
|
flickerstreak@24
|
229 self.config = nil
|
flickerstreak@24
|
230 self.bar = nil
|
flickerstreak@24
|
231 end
|
flickerstreak@24
|
232
|
flickerstreak@24
|
233 function Button:Refresh(bar,idx)
|
flickerstreak@24
|
234 bar:PlaceButton(self.frame, idx, 36, 36)
|
flickerstreak@24
|
235 end
|
flickerstreak@24
|
236
|
flickerstreak@24
|
237 function Button:GetFrame()
|
flickerstreak@24
|
238 return self.frame
|
flickerstreak@24
|
239 end
|
flickerstreak@24
|
240
|
flickerstreak@24
|
241 function Button:GetName()
|
flickerstreak@24
|
242 return self.name
|
flickerstreak@24
|
243 end
|
flickerstreak@24
|
244
|
flickerstreak@24
|
245 function Button:GetActionID()
|
flickerstreak@24
|
246 return self.config.actionID
|
flickerstreak@24
|
247 end
|
flickerstreak@28
|
248
|
flickerstreak@28
|
249
|
flickerstreak@28
|
250 -- export as a class-factory to module
|
flickerstreak@28
|
251 module.BtnClass = {
|
flickerstreak@28
|
252 new = function(self, ...)
|
flickerstreak@28
|
253 local x = { }
|
flickerstreak@28
|
254 for k,v in pairs(Button) do
|
flickerstreak@28
|
255 x[k] = v
|
flickerstreak@28
|
256 end
|
flickerstreak@28
|
257 Constructor(x, ...)
|
flickerstreak@28
|
258 return x
|
flickerstreak@28
|
259 end
|
flickerstreak@28
|
260 }
|