flickerstreak@122
|
1 local ReAction = ReAction
|
flickerstreak@122
|
2 local L = ReAction.L
|
flickerstreak@122
|
3 local _G = _G
|
flickerstreak@122
|
4 local CreateFrame = CreateFrame
|
flickerstreak@122
|
5 local floor = math.floor
|
flickerstreak@122
|
6 local fmod = math.fmod
|
flickerstreak@122
|
7 local format = string.format
|
flickerstreak@122
|
8
|
flickerstreak@122
|
9 ReAction:UpdateRevision("$Revision$")
|
flickerstreak@122
|
10
|
flickerstreak@147
|
11 local KB = LibStub("LibKeyBound-1.0")
|
flickerstreak@147
|
12
|
flickerstreak@155
|
13 ---- Secure snippets ----
|
flickerstreak@155
|
14 local _reaction_init =
|
flickerstreak@155
|
15 [[
|
flickerstreak@155
|
16 anchorKeys = newtable("point","relPoint","x","y")
|
flickerstreak@155
|
17
|
flickerstreak@155
|
18 state = nil
|
flickerstreak@155
|
19 set_state = nil
|
flickerstreak@155
|
20 state_override = nil
|
flickerstreak@155
|
21
|
flickerstreak@155
|
22 showAll = false
|
flickerstreak@155
|
23 hidden = false
|
flickerstreak@155
|
24
|
flickerstreak@155
|
25 defaultAlpha = 1.0
|
flickerstreak@155
|
26 defaultScale = 1.0
|
flickerstreak@155
|
27 defaultAnchor = newtable()
|
flickerstreak@155
|
28
|
flickerstreak@155
|
29 activeStates = newtable()
|
flickerstreak@155
|
30 settings = newtable()
|
flickerstreak@155
|
31 extensions = newtable()
|
flickerstreak@155
|
32 ]]
|
flickerstreak@155
|
33
|
flickerstreak@155
|
34 local _reaction_refresh =
|
flickerstreak@155
|
35 [[
|
flickerstreak@155
|
36 local oldState = state
|
flickerstreak@155
|
37 state = state_override or set_state or state
|
flickerstreak@155
|
38
|
flickerstreak@155
|
39 if state then
|
flickerstreak@155
|
40 local settings = settings[state]
|
flickerstreak@155
|
41 if settings then
|
flickerstreak@155
|
42 -- show/hide
|
flickerstreak@155
|
43 local h = settings.hide and not showAll
|
flickerstreak@155
|
44 if h ~= hidden then
|
flickerstreak@155
|
45 if h then
|
flickerstreak@155
|
46 self:Hide()
|
flickerstreak@155
|
47 else
|
flickerstreak@155
|
48 self:Show()
|
flickerstreak@155
|
49 end
|
flickerstreak@155
|
50 hidden = h
|
flickerstreak@155
|
51 end
|
flickerstreak@155
|
52 -- re-anchor
|
flickerstreak@155
|
53 local old_anchor = activeStates.anchor
|
flickerstreak@155
|
54 activeStates.anchor = settings.anchorEnable and state
|
flickerstreak@155
|
55 if old_anchor ~= activeStates.anchor or not set_state then
|
flickerstreak@155
|
56 if activeStates.anchor then
|
flickerstreak@155
|
57 if settings.anchorPoint then
|
flickerstreak@155
|
58 self:ClearAllPoints()
|
flickerstreak@155
|
59 local f = self:GetAttribute("frameref-anchor-"..state)
|
flickerstreak@155
|
60 if f then
|
flickerstreak@155
|
61 self:SetPoint(settings.anchorPoint, f, settings.anchorRelPoint, settings.anchorX, settings.anchorY)
|
flickerstreak@155
|
62 end
|
flickerstreak@155
|
63 end
|
flickerstreak@155
|
64 elseif defaultAnchor.point then
|
flickerstreak@155
|
65 self:ClearAllPoints()
|
flickerstreak@155
|
66 self:SetPoint(defaultAnchor.point, defaultAnchor.frame,
|
flickerstreak@155
|
67 defaultAnchor.relPoint, defaultAnchor.x, defaultAnchor.y)
|
flickerstreak@155
|
68 end
|
flickerstreak@155
|
69 end
|
flickerstreak@155
|
70 -- re-scale
|
flickerstreak@155
|
71 local old_scale = activeStates.scale
|
flickerstreak@155
|
72 activeStates.scale = settings.enableScale and state
|
flickerstreak@155
|
73 if old_scale ~= activeStates.scale or not set_state then
|
flickerstreak@155
|
74 self:SetScale(activeStates.scale and settings.scale or defaultScale)
|
flickerstreak@155
|
75 end
|
flickerstreak@155
|
76 -- alpha
|
flickerstreak@155
|
77 local old_alpha = activeStates.alpha
|
flickerstreak@155
|
78 activeStates.alpha = settings.enableAlpha and state
|
flickerstreak@155
|
79 if old_alpha ~= activeStates.alpha or not set_state then
|
flickerstreak@155
|
80 self:SetAlpha(activeStates.alpha and settings.alpha or defaultAlpha)
|
flickerstreak@155
|
81 end
|
flickerstreak@155
|
82 end
|
flickerstreak@155
|
83 end
|
flickerstreak@155
|
84
|
flickerstreak@155
|
85 for _, attr in pairs(extensions) do
|
flickerstreak@155
|
86 control:RunAttribute(attr)
|
flickerstreak@155
|
87 end
|
flickerstreak@155
|
88
|
flickerstreak@155
|
89 control:ChildUpdate()
|
flickerstreak@155
|
90
|
flickerstreak@155
|
91 if showAll then
|
flickerstreak@155
|
92 control:CallMethod("UpdateHiddenLabel", state and settings[state] and settings[state].hide)
|
flickerstreak@155
|
93 end
|
flickerstreak@155
|
94
|
flickerstreak@155
|
95 if oldState ~= state then
|
flickerstreak@155
|
96 control:CallMethod("StateRefresh", state)
|
flickerstreak@155
|
97 end
|
flickerstreak@155
|
98 ]]
|
flickerstreak@155
|
99
|
flickerstreak@155
|
100 local _onstate_reaction = -- function( self, stateid, newstate )
|
flickerstreak@155
|
101 [[
|
flickerstreak@155
|
102 set_state = newstate
|
flickerstreak@155
|
103 ]] .. _reaction_refresh
|
flickerstreak@155
|
104
|
flickerstreak@155
|
105 local _onstate_showgrid = -- function( self, stateid, newstate )
|
flickerstreak@155
|
106 [[
|
flickerstreak@155
|
107 control:ChildUpdate(stateid,newstate)
|
flickerstreak@155
|
108 control:CallMethod("UpdateShowGrid")
|
flickerstreak@155
|
109 ]]
|
flickerstreak@155
|
110
|
flickerstreak@155
|
111 local _onstate_unitexists = -- function( self, stateid, newstate )
|
flickerstreak@155
|
112 [[
|
flickerstreak@155
|
113
|
flickerstreak@155
|
114 ]] .. _reaction_refresh
|
flickerstreak@155
|
115
|
flickerstreak@155
|
116 local _onclick = -- function( self, button, down )
|
flickerstreak@155
|
117 [[
|
flickerstreak@155
|
118 if state_override == button then
|
flickerstreak@155
|
119 state_override = nil -- toggle
|
flickerstreak@155
|
120 else
|
flickerstreak@155
|
121 state_override = button
|
flickerstreak@155
|
122 end
|
flickerstreak@155
|
123 ]] .. _reaction_refresh
|
flickerstreak@155
|
124
|
flickerstreak@155
|
125
|
flickerstreak@147
|
126 ---- Bar class ----
|
flickerstreak@122
|
127 local Bar = { }
|
flickerstreak@122
|
128 local weak = { __mode = "k" }
|
flickerstreak@147
|
129 local frameList = { }
|
flickerstreak@122
|
130
|
flickerstreak@122
|
131 ReAction.Bar = Bar -- export to ReAction
|
flickerstreak@122
|
132
|
flickerstreak@122
|
133 function Bar:New( name, config )
|
flickerstreak@122
|
134 if type(config) ~= "table" then
|
flickerstreak@122
|
135 error("ReAction.Bar: config table required")
|
flickerstreak@122
|
136 end
|
flickerstreak@122
|
137
|
flickerstreak@122
|
138 -- create new self
|
flickerstreak@122
|
139 self = setmetatable(
|
flickerstreak@122
|
140 {
|
flickerstreak@122
|
141 config = config,
|
flickerstreak@122
|
142 name = name,
|
flickerstreak@122
|
143 buttons = setmetatable( { }, weak ),
|
flickerstreak@122
|
144 width = config.width or 480,
|
flickerstreak@147
|
145 height = config.height or 40,
|
flickerstreak@122
|
146 },
|
flickerstreak@147
|
147 {__index = self} )
|
flickerstreak@122
|
148
|
flickerstreak@122
|
149 -- The frame type is 'Button' in order to have an OnClick handler. However, the frame itself is
|
flickerstreak@122
|
150 -- not mouse-clickable by the user.
|
flickerstreak@122
|
151 local parent = config.parent and (ReAction:GetBar(config.parent) or _G[config.parent]) or UIParent
|
flickerstreak@147
|
152 name = name and "ReAction-"..name
|
flickerstreak@147
|
153 local f = name and frameList[name]
|
flickerstreak@147
|
154 if not f then
|
flickerstreak@147
|
155 f = CreateFrame("Button", name, parent, "SecureHandlerStateTemplate, SecureHandlerClickTemplate")
|
flickerstreak@147
|
156 if name then
|
flickerstreak@147
|
157 frameList[name] = f
|
flickerstreak@147
|
158 end
|
flickerstreak@147
|
159 end
|
flickerstreak@122
|
160 f:SetFrameStrata("MEDIUM")
|
flickerstreak@122
|
161 f:SetWidth(self.width)
|
flickerstreak@146
|
162 f:SetHeight(self.height)
|
flickerstreak@122
|
163 f:SetAlpha(config.alpha or 1.0)
|
flickerstreak@122
|
164 f:Show()
|
flickerstreak@122
|
165 f:EnableMouse(false)
|
flickerstreak@122
|
166 f:SetClampedToScreen(true)
|
flickerstreak@155
|
167 ReAction.gridProxy:AddFrame(f)
|
flickerstreak@122
|
168
|
flickerstreak@155
|
169 -- secure handlers
|
flickerstreak@155
|
170 f:Execute(_reaction_init)
|
flickerstreak@155
|
171 f:SetAttribute("_onstate-reaction", _onstate_reaction)
|
flickerstreak@155
|
172 f:SetAttribute("_onstate-showgrid", _onstate_showgrid)
|
flickerstreak@155
|
173 f:SetAttribute("_onstate-unitexists", _onstate_unitexists)
|
flickerstreak@155
|
174 f:SetAttribute("_onclick", _onclick)
|
flickerstreak@155
|
175
|
flickerstreak@155
|
176 -- secure handler CallMethod()s
|
flickerstreak@155
|
177 f.UpdateShowGrid = function() self:UpdateShowGrid() end
|
flickerstreak@155
|
178 f.StateRefresh = function() self:RefreshControls() end
|
flickerstreak@155
|
179 f.UpdateHiddenLabel = function(f,hidden) self:SetLabelSubtext(hidden and L["Hidden"]) end
|
flickerstreak@122
|
180
|
flickerstreak@122
|
181 -- Override the default frame accessor to provide strict read-only access
|
flickerstreak@122
|
182 function self:GetFrame()
|
flickerstreak@122
|
183 return f
|
flickerstreak@122
|
184 end
|
flickerstreak@122
|
185
|
flickerstreak@122
|
186 self:ApplyAnchor()
|
flickerstreak@147
|
187 self:SetConfigMode(ReAction:GetConfigMode())
|
flickerstreak@147
|
188 self:SetKeybindMode(ReAction:GetKeybindMode())
|
flickerstreak@147
|
189
|
flickerstreak@122
|
190 ReAction.RegisterCallback(self, "OnConfigModeChanged")
|
flickerstreak@147
|
191 KB.RegisterCallback(self, "LIBKEYBOUND_ENABLED")
|
flickerstreak@147
|
192 KB.RegisterCallback(self, "LIBKEYBOUND_DISABLED")
|
flickerstreak@147
|
193 KB.RegisterCallback(self, "LIBKEYBOUND_MODE_COLOR_CHANGED","LIBKEYBOUND_ENABLED")
|
flickerstreak@122
|
194
|
flickerstreak@122
|
195 return self
|
flickerstreak@122
|
196 end
|
flickerstreak@122
|
197
|
flickerstreak@122
|
198 function Bar:Destroy()
|
flickerstreak@122
|
199 local f = self:GetFrame()
|
flickerstreak@122
|
200 f:UnregisterAllEvents()
|
flickerstreak@125
|
201 self:ShowControls(false)
|
flickerstreak@122
|
202 ReAction.UnregisterAllCallbacks(self)
|
flickerstreak@147
|
203 KB.UnregisterAllCallbacks(self)
|
flickerstreak@122
|
204 ReAction.gridProxy:RemoveFrame(f)
|
flickerstreak@122
|
205 f:SetParent(UIParent)
|
flickerstreak@122
|
206 f:ClearAllPoints()
|
flickerstreak@147
|
207 f:Hide()
|
flickerstreak@122
|
208 end
|
flickerstreak@122
|
209
|
flickerstreak@147
|
210 --
|
flickerstreak@147
|
211 -- Events
|
flickerstreak@147
|
212 --
|
flickerstreak@147
|
213
|
flickerstreak@147
|
214 function Bar:OnConfigModeChanged(event, mode)
|
flickerstreak@147
|
215 self:SetConfigMode(mode)
|
flickerstreak@123
|
216 end
|
flickerstreak@123
|
217
|
flickerstreak@147
|
218 function Bar:LIBKEYBOUND_ENABLED(evt)
|
flickerstreak@147
|
219 self:SetKeybindMode(true)
|
flickerstreak@147
|
220 end
|
flickerstreak@147
|
221
|
flickerstreak@147
|
222 function Bar:LIBKEYBOUND_DISABLED(evt)
|
flickerstreak@147
|
223 self:SetKeybindMode(false)
|
flickerstreak@122
|
224 end
|
flickerstreak@122
|
225
|
flickerstreak@153
|
226 --
|
flickerstreak@153
|
227 -- Accessors
|
flickerstreak@153
|
228 --
|
flickerstreak@153
|
229
|
flickerstreak@153
|
230 function Bar:GetName()
|
flickerstreak@153
|
231 return self.name
|
flickerstreak@153
|
232 end
|
flickerstreak@153
|
233
|
flickerstreak@153
|
234 -- only ReAction:RenameBar() should call this function. Calling from any other
|
flickerstreak@153
|
235 -- context will desync the bar list in the ReAction class.
|
flickerstreak@153
|
236 function Bar:SetName(name)
|
flickerstreak@153
|
237 self.name = name
|
flickerstreak@154
|
238 if self.overlay then
|
flickerstreak@154
|
239 self.overlay:SetLabel(self.name)
|
flickerstreak@154
|
240 end
|
flickerstreak@153
|
241 end
|
flickerstreak@153
|
242
|
flickerstreak@153
|
243 function Bar:GetFrame()
|
flickerstreak@153
|
244 -- this method is included for documentation purposes. It is overridden
|
flickerstreak@153
|
245 -- for each object in the :New() method.
|
flickerstreak@153
|
246 error("Invalid Bar object: used without initialization")
|
flickerstreak@153
|
247 end
|
flickerstreak@153
|
248
|
flickerstreak@153
|
249 function Bar:GetConfig()
|
flickerstreak@153
|
250 return self.config
|
flickerstreak@153
|
251 end
|
flickerstreak@153
|
252
|
flickerstreak@153
|
253 function Bar:GetAnchor()
|
flickerstreak@122
|
254 local c = self.config
|
flickerstreak@153
|
255 return (c.point or "CENTER"),
|
flickerstreak@153
|
256 (c.anchor or self:GetFrame():GetParent():GetName()),
|
flickerstreak@153
|
257 (c.relpoint or c.point or "CENTER"),
|
flickerstreak@153
|
258 (c.x or 0),
|
flickerstreak@153
|
259 (c.y or 0)
|
flickerstreak@122
|
260 end
|
flickerstreak@122
|
261
|
flickerstreak@122
|
262 function Bar:SetAnchor(point, frame, relativePoint, x, y)
|
flickerstreak@122
|
263 local c = self.config
|
flickerstreak@122
|
264 c.point = point or c.point
|
flickerstreak@122
|
265 c.anchor = frame or c.anchor
|
flickerstreak@122
|
266 c.relpoint = relativePoint or c.relpoint
|
flickerstreak@122
|
267 c.x = x or c.x
|
flickerstreak@122
|
268 c.y = y or c.y
|
flickerstreak@122
|
269 self:ApplyAnchor()
|
flickerstreak@122
|
270 ReAction:RefreshBar(self)
|
flickerstreak@122
|
271 end
|
flickerstreak@122
|
272
|
flickerstreak@122
|
273 function Bar:GetSize()
|
flickerstreak@122
|
274 local f = self:GetFrame()
|
flickerstreak@122
|
275 return f:GetWidth(), f:GetHeight()
|
flickerstreak@122
|
276 end
|
flickerstreak@122
|
277
|
flickerstreak@122
|
278 function Bar:SetSize(w,h)
|
flickerstreak@122
|
279 local f = self:GetFrame()
|
flickerstreak@122
|
280 self.config.width = w
|
flickerstreak@122
|
281 self.config.height = h
|
flickerstreak@122
|
282 f:SetWidth(w)
|
flickerstreak@122
|
283 f:SetHeight(h)
|
flickerstreak@122
|
284 end
|
flickerstreak@122
|
285
|
flickerstreak@122
|
286 function Bar:GetButtonSize()
|
flickerstreak@122
|
287 local w = self.config.btnWidth or 32
|
flickerstreak@122
|
288 local h = self.config.btnHeight or 32
|
flickerstreak@122
|
289 -- TODO: get from modules?
|
flickerstreak@122
|
290 return w,h
|
flickerstreak@122
|
291 end
|
flickerstreak@122
|
292
|
flickerstreak@122
|
293 function Bar:SetButtonSize(w,h)
|
flickerstreak@122
|
294 if w > 0 and h > 0 then
|
flickerstreak@122
|
295 self.config.btnWidth = w
|
flickerstreak@122
|
296 self.config.btnHeight = h
|
flickerstreak@122
|
297 end
|
flickerstreak@122
|
298 ReAction:RefreshBar(self)
|
flickerstreak@122
|
299 end
|
flickerstreak@122
|
300
|
flickerstreak@153
|
301 function Bar:GetNumButtons()
|
flickerstreak@153
|
302 local r,c = self:GetButtonGrid()
|
flickerstreak@153
|
303 return r*c
|
flickerstreak@153
|
304 end
|
flickerstreak@153
|
305
|
flickerstreak@122
|
306 function Bar:GetButtonGrid()
|
flickerstreak@122
|
307 local cfg = self.config
|
flickerstreak@122
|
308 local r = cfg.btnRows or 1
|
flickerstreak@122
|
309 local c = cfg.btnColumns or 1
|
flickerstreak@122
|
310 local s = cfg.spacing or 4
|
flickerstreak@122
|
311 return r,c,s
|
flickerstreak@122
|
312 end
|
flickerstreak@122
|
313
|
flickerstreak@122
|
314 function Bar:SetButtonGrid(r,c,s)
|
flickerstreak@122
|
315 if r > 0 and c > 0 and s > 0 then
|
flickerstreak@122
|
316 local cfg = self.config
|
flickerstreak@122
|
317 cfg.btnRows = r
|
flickerstreak@122
|
318 cfg.btnColumns = c
|
flickerstreak@122
|
319 cfg.spacing = s
|
flickerstreak@122
|
320 end
|
flickerstreak@122
|
321 ReAction:RefreshBar(self)
|
flickerstreak@122
|
322 end
|
flickerstreak@122
|
323
|
flickerstreak@122
|
324 function Bar:GetAlpha()
|
flickerstreak@122
|
325 return self.config.alpha or 1.0
|
flickerstreak@122
|
326 end
|
flickerstreak@122
|
327
|
flickerstreak@122
|
328 function Bar:SetAlpha(value)
|
flickerstreak@122
|
329 self.config.alpha = value
|
flickerstreak@122
|
330 self:GetFrame():SetAlpha(value or 1.0)
|
flickerstreak@155
|
331 self:UpdateDefaultStateAlpha()
|
flickerstreak@122
|
332 ReAction:RefreshBar(self)
|
flickerstreak@122
|
333 end
|
flickerstreak@122
|
334
|
flickerstreak@122
|
335 function Bar:IterateButtons()
|
flickerstreak@155
|
336 -- iterator returns button, idx and does NOT iterate in index order
|
flickerstreak@122
|
337 return pairs(self.buttons)
|
flickerstreak@122
|
338 end
|
flickerstreak@122
|
339
|
flickerstreak@153
|
340 --
|
flickerstreak@153
|
341 -- Methods
|
flickerstreak@153
|
342 --
|
flickerstreak@153
|
343
|
flickerstreak@147
|
344 function Bar:SetConfigMode(mode)
|
flickerstreak@155
|
345 self:SetSecureData("showAll",mode)
|
flickerstreak@155
|
346 self:UpdateUnitWatch()
|
flickerstreak@147
|
347 self:ShowControls(mode)
|
flickerstreak@147
|
348 for b in self:IterateButtons() do
|
flickerstreak@147
|
349 b:ShowGridTemp(mode)
|
flickerstreak@147
|
350 b:UpdateActionIDLabel(mode)
|
flickerstreak@147
|
351 end
|
flickerstreak@147
|
352 end
|
flickerstreak@147
|
353
|
flickerstreak@147
|
354 function Bar:SetKeybindMode(mode)
|
flickerstreak@155
|
355 self:SetSecureData("showAll",mode)
|
flickerstreak@155
|
356 self:UpdateUnitWatch()
|
flickerstreak@147
|
357 for b in self:IterateButtons() do
|
flickerstreak@147
|
358 b:SetKeybindMode(mode)
|
flickerstreak@147
|
359 end
|
flickerstreak@147
|
360 end
|
flickerstreak@147
|
361
|
flickerstreak@153
|
362 function Bar:ApplyAnchor()
|
flickerstreak@153
|
363 local f = self:GetFrame()
|
flickerstreak@153
|
364 local c = self.config
|
flickerstreak@153
|
365 local p = c.point
|
flickerstreak@153
|
366
|
flickerstreak@153
|
367 f:SetWidth(c.width)
|
flickerstreak@153
|
368 f:SetHeight(c.height)
|
flickerstreak@153
|
369 f:ClearAllPoints()
|
flickerstreak@153
|
370
|
flickerstreak@153
|
371 if p then
|
flickerstreak@153
|
372 local a = f:GetParent()
|
flickerstreak@153
|
373 if c.anchor then
|
flickerstreak@153
|
374 local bar = ReAction:GetBar(c.anchor)
|
flickerstreak@153
|
375 if bar then
|
flickerstreak@153
|
376 a = bar:GetFrame()
|
flickerstreak@153
|
377 else
|
flickerstreak@153
|
378 a = _G[c.anchor]
|
flickerstreak@153
|
379 end
|
flickerstreak@153
|
380 end
|
flickerstreak@153
|
381 local fr = a or f:GetParent()
|
flickerstreak@153
|
382 f:SetPoint(p, a or f:GetParent(), c.relpoint, c.x or 0, c.y or 0)
|
flickerstreak@153
|
383 else
|
flickerstreak@153
|
384 f:SetPoint("CENTER")
|
flickerstreak@153
|
385 end
|
flickerstreak@155
|
386
|
flickerstreak@155
|
387 self:UpdateDefaultStateAnchor()
|
flickerstreak@153
|
388 end
|
flickerstreak@153
|
389
|
flickerstreak@153
|
390 function Bar:ClipNButtons( n )
|
flickerstreak@153
|
391 local cfg = self.config
|
flickerstreak@153
|
392 local r = cfg.btnRows or 1
|
flickerstreak@153
|
393 local c = cfg.btnColumns or 1
|
flickerstreak@153
|
394
|
flickerstreak@153
|
395 cfg.btnRows = ceil(n/c)
|
flickerstreak@153
|
396 cfg.btnColumns = min(n,c)
|
flickerstreak@153
|
397 end
|
flickerstreak@153
|
398
|
flickerstreak@153
|
399 function Bar:AddButton(idx, button)
|
flickerstreak@153
|
400 local f = self:GetFrame()
|
flickerstreak@153
|
401
|
flickerstreak@153
|
402 -- store in a weak reverse-index array
|
flickerstreak@153
|
403 self.buttons[button] = idx
|
flickerstreak@153
|
404
|
flickerstreak@153
|
405 -- Store a properly wrapped reference to the child frame as an attribute
|
flickerstreak@153
|
406 -- (accessible via "frameref-btn#")
|
flickerstreak@153
|
407 f:SetFrameRef(format("btn%d",idx), button:GetFrame())
|
flickerstreak@153
|
408 end
|
flickerstreak@153
|
409
|
flickerstreak@153
|
410 function Bar:RemoveButton(button)
|
flickerstreak@153
|
411 local idx = self.buttons[button]
|
flickerstreak@153
|
412 if idx then
|
flickerstreak@153
|
413 self:GetFrame():SetAttribute(format("frameref-btn%d",idx),nil)
|
flickerstreak@153
|
414 self.buttons[button] = nil
|
flickerstreak@153
|
415 end
|
flickerstreak@153
|
416 end
|
flickerstreak@153
|
417
|
flickerstreak@122
|
418 function Bar:PlaceButton(button, baseW, baseH)
|
flickerstreak@122
|
419 local idx = self.buttons[button]
|
flickerstreak@122
|
420 if idx then
|
flickerstreak@122
|
421 local r, c, s = self:GetButtonGrid()
|
flickerstreak@122
|
422 local bh, bw = self:GetButtonSize()
|
flickerstreak@122
|
423 local row, col = floor((idx-1)/c), fmod((idx-1),c) -- zero-based
|
flickerstreak@122
|
424 local x, y = col*bw + (col+0.5)*s, -(row*bh + (row+0.5)*s)
|
flickerstreak@122
|
425 local scale = bw/baseW
|
flickerstreak@122
|
426 local b = button:GetFrame()
|
flickerstreak@122
|
427
|
flickerstreak@122
|
428 b:ClearAllPoints()
|
flickerstreak@122
|
429 b:SetPoint("TOPLEFT",x/scale,y/scale)
|
flickerstreak@122
|
430 b:SetScale(scale)
|
flickerstreak@122
|
431 end
|
flickerstreak@122
|
432 end
|
flickerstreak@122
|
433
|
flickerstreak@122
|
434 function Bar:SkinButton()
|
flickerstreak@122
|
435 -- does nothing by default
|
flickerstreak@147
|
436 end
|
flickerstreak@148
|
437
|
flickerstreak@155
|
438 function Bar:UpdateShowGrid()
|
flickerstreak@155
|
439 for button in self:IterateButtons() do
|
flickerstreak@155
|
440 button:UpdateShowGrid()
|
flickerstreak@155
|
441 end
|
flickerstreak@155
|
442 end
|
flickerstreak@155
|
443
|
flickerstreak@155
|
444 function Bar:UpdateUnitWatch()
|
flickerstreak@155
|
445 if self.unitwatch then
|
flickerstreak@155
|
446 if self.unitwatchActive and (ReAction:GetConfigMode() or ReAction:GetKeybindMode()) then
|
flickerstreak@155
|
447 UnregisterUnitWatch(self:GetFrame())
|
flickerstreak@155
|
448 self.unitwatchActive = false
|
flickerstreak@155
|
449 elseif not self.unitwatchActive then
|
flickerstreak@155
|
450 RegisterUnitWatch(self:GetFrame())
|
flickerstreak@155
|
451 self.unitwatchActive = true
|
flickerstreak@155
|
452 end
|
flickerstreak@155
|
453 self:RefreshSecureState()
|
flickerstreak@155
|
454 end
|
flickerstreak@155
|
455 end
|
flickerstreak@155
|
456
|
flickerstreak@154
|
457 function Bar:ShowControls(show)
|
flickerstreak@154
|
458 if show then
|
flickerstreak@155
|
459 if not self.overlay then
|
flickerstreak@155
|
460 self.overlay = Bar.Overlay:New(self) -- see Overlay.lua
|
flickerstreak@154
|
461 end
|
flickerstreak@155
|
462 self.overlay:Show()
|
flickerstreak@155
|
463 self:RefreshSecureState()
|
flickerstreak@155
|
464 elseif self.overlay then
|
flickerstreak@155
|
465 self.overlay:Hide()
|
flickerstreak@154
|
466 end
|
flickerstreak@154
|
467 end
|
flickerstreak@154
|
468
|
flickerstreak@154
|
469 function Bar:RefreshControls()
|
flickerstreak@154
|
470 if self.overlay and self.overlay:IsShown() then
|
flickerstreak@154
|
471 self.overlay:RefreshControls()
|
flickerstreak@154
|
472 end
|
flickerstreak@154
|
473 end
|
flickerstreak@154
|
474
|
flickerstreak@154
|
475 function Bar:SetLabelSubtext(text)
|
flickerstreak@154
|
476 if self.overlay then
|
flickerstreak@154
|
477 self.overlay:SetLabelSubtext(text)
|
flickerstreak@154
|
478 end
|
flickerstreak@154
|
479 end
|
flickerstreak@154
|
480
|
flickerstreak@154
|
481 --
|
flickerstreak@154
|
482 -- Secure state functions
|
flickerstreak@154
|
483 --
|
flickerstreak@154
|
484
|
flickerstreak@155
|
485 function Bar:GetSecureState()
|
flickerstreak@155
|
486 local env = GetManagedEnvironment(self:GetFrame())
|
flickerstreak@155
|
487 return env and env.state
|
flickerstreak@155
|
488 end
|
flickerstreak@155
|
489
|
flickerstreak@155
|
490 function Bar:GetStateProperty(state, propname)
|
flickerstreak@155
|
491 -- override in modules/State.lua for now
|
flickerstreak@155
|
492 end
|
flickerstreak@155
|
493
|
flickerstreak@155
|
494 function Bar:SetStateProperty(state, propname, value)
|
flickerstreak@155
|
495 -- override in modules/State.lua for now
|
flickerstreak@155
|
496 end
|
flickerstreak@155
|
497
|
flickerstreak@155
|
498 function Bar:RefreshSecureState()
|
flickerstreak@155
|
499 self:GetFrame():Execute(_reaction_refresh)
|
flickerstreak@155
|
500 end
|
flickerstreak@155
|
501
|
flickerstreak@155
|
502 -- usage: SetSecureData(globalname, [tblkey1, tblkey2, ...], value)
|
flickerstreak@155
|
503 function Bar:SetSecureData( ... )
|
flickerstreak@155
|
504 local n = select('#',...)
|
flickerstreak@155
|
505 if n < 2 then
|
flickerstreak@155
|
506 error("ReAction.Bar:SetSecureData() requires at least 2 arguments")
|
flickerstreak@155
|
507 end
|
flickerstreak@155
|
508 local f = self:GetFrame()
|
flickerstreak@155
|
509 f:SetAttribute("data-depth",n-1)
|
flickerstreak@155
|
510 f:SetAttribute("data-value",select(n,...))
|
flickerstreak@155
|
511 for i = 1, n-1 do
|
flickerstreak@155
|
512 local key = select(i,...)
|
flickerstreak@155
|
513 if key == nil then
|
flickerstreak@155
|
514 error("ReAction.Bar:SetSecureData() - nil table key in argument list (#"..i..")")
|
flickerstreak@155
|
515 end
|
flickerstreak@155
|
516 f:SetAttribute("data-key-"..i, key)
|
flickerstreak@155
|
517 end
|
flickerstreak@155
|
518 f:Execute(
|
flickerstreak@155
|
519 [[
|
flickerstreak@155
|
520 local n = self:GetAttribute("data-depth")
|
flickerstreak@155
|
521 if n > 0 then
|
flickerstreak@155
|
522 local value = self:GetAttribute("data-value")
|
flickerstreak@155
|
523 local t = _G
|
flickerstreak@155
|
524 for i = 1, n do
|
flickerstreak@155
|
525 local key = self:GetAttribute("data-key-"..i)
|
flickerstreak@155
|
526 if not key then return end
|
flickerstreak@155
|
527 if not t[key] then
|
flickerstreak@155
|
528 t[key] = newtable()
|
flickerstreak@155
|
529 end
|
flickerstreak@155
|
530 if i == n then
|
flickerstreak@155
|
531 t[key] = value
|
flickerstreak@155
|
532 else
|
flickerstreak@155
|
533 t = t[key]
|
flickerstreak@155
|
534 end
|
flickerstreak@155
|
535 end
|
flickerstreak@155
|
536 end
|
flickerstreak@155
|
537 ]])
|
flickerstreak@155
|
538 self:RefreshSecureState()
|
flickerstreak@155
|
539 end
|
flickerstreak@155
|
540
|
flickerstreak@155
|
541 function Bar:SetSecureStateData( state, key, value )
|
flickerstreak@155
|
542 self:SetSecureData("settings",state,key,value)
|
flickerstreak@155
|
543 end
|
flickerstreak@155
|
544
|
flickerstreak@155
|
545 -- sets a snippet to be run as an extension to _onstate-reaction
|
flickerstreak@155
|
546 function Bar:SetSecureStateExtension( id, snippet )
|
flickerstreak@155
|
547 if id == nil then
|
flickerstreak@155
|
548 error("ReAction.Bar:SetSecureStateExtension() requires an id")
|
flickerstreak@155
|
549 end
|
flickerstreak@155
|
550 local f = self:GetFrame()
|
flickerstreak@155
|
551 f:SetAttribute("input-secure-ext-id",id)
|
flickerstreak@155
|
552 f:SetAttribute("secure-ext-"..id,snippet)
|
flickerstreak@155
|
553 f:Execute(
|
flickerstreak@155
|
554 [[
|
flickerstreak@155
|
555 local id = self:GetAttribute("input-secure-ext-id")
|
flickerstreak@155
|
556 if id then
|
flickerstreak@155
|
557 extensions[id] = self:GetAttribute("secure-ext-"..id) or nil
|
flickerstreak@155
|
558 end
|
flickerstreak@155
|
559 ]])
|
flickerstreak@155
|
560 self:RefreshSecureState()
|
flickerstreak@155
|
561 end
|
flickerstreak@155
|
562
|
flickerstreak@155
|
563 function Bar:SetFrameRef( name, refFrame )
|
flickerstreak@155
|
564 if refFrame then
|
flickerstreak@155
|
565 local _, explicit = refFrame:IsProtected()
|
flickerstreak@155
|
566 if not explicit then
|
flickerstreak@155
|
567 refFrame = nil
|
flickerstreak@155
|
568 end
|
flickerstreak@155
|
569 end
|
flickerstreak@155
|
570 if refFrame then
|
flickerstreak@155
|
571 self:GetFrame():SetFrameRef(name,refFrame)
|
flickerstreak@155
|
572 else
|
flickerstreak@155
|
573 self:GetFrame():SetAttribute("frameref-"..name,nil)
|
flickerstreak@155
|
574 end
|
flickerstreak@155
|
575 end
|
flickerstreak@155
|
576
|
flickerstreak@155
|
577 function Bar:SetStateDriver( rule )
|
flickerstreak@155
|
578 if rule then
|
flickerstreak@155
|
579 RegisterStateDriver(self:GetFrame(),"reaction",rule)
|
flickerstreak@155
|
580 elseif self.statedriver then
|
flickerstreak@155
|
581 UnregisterStateDriver(self:GetFrame(),"reaction")
|
flickerstreak@155
|
582 end
|
flickerstreak@155
|
583 self.statedriver = rule
|
flickerstreak@155
|
584 self:RefreshSecureState()
|
flickerstreak@155
|
585 end
|
flickerstreak@155
|
586
|
flickerstreak@148
|
587 -- pass unit=nil to set up the unit elsewhere, if you want something more complex
|
flickerstreak@148
|
588 function Bar:RegisterUnitWatch( unit, enable )
|
flickerstreak@148
|
589 local f = self:GetFrame()
|
flickerstreak@148
|
590 if unit then
|
flickerstreak@148
|
591 f:SetAttribute("unit",unit)
|
flickerstreak@148
|
592 end
|
flickerstreak@148
|
593 self.unitwatch = enable
|
flickerstreak@155
|
594 self:UpdateUnitWatch()
|
flickerstreak@148
|
595 end
|
flickerstreak@148
|
596
|
flickerstreak@155
|
597 -- set a keybind to push a value into "state-reaction" attribute
|
flickerstreak@155
|
598 function Bar:SetStateKeybind( key, state )
|
flickerstreak@155
|
599 local f = self:GetFrame()
|
flickerstreak@155
|
600 local binds = self.statebinds
|
flickerstreak@155
|
601 if not binds then
|
flickerstreak@155
|
602 binds = { }
|
flickerstreak@155
|
603 self.statebinds = binds
|
flickerstreak@155
|
604 end
|
flickerstreak@155
|
605
|
flickerstreak@155
|
606 -- clear the old binding, if any
|
flickerstreak@155
|
607 if binds[state] then
|
flickerstreak@155
|
608 SetOverrideBinding(f, false, binds[state], nil)
|
flickerstreak@155
|
609 end
|
flickerstreak@155
|
610
|
flickerstreak@155
|
611 if key then
|
flickerstreak@155
|
612 SetOverrideBinding(f, false, key, state, nil) -- state name is virtual mouse button
|
flickerstreak@155
|
613 end
|
flickerstreak@155
|
614 binds[state] = key
|
flickerstreak@155
|
615 end
|
flickerstreak@155
|
616
|
flickerstreak@155
|
617 function Bar:GetStateKeybind( state )
|
flickerstreak@155
|
618 if self.statebinds and state then
|
flickerstreak@155
|
619 return self.statebinds[state]
|
flickerstreak@155
|
620 end
|
flickerstreak@155
|
621 end
|
flickerstreak@155
|
622
|
flickerstreak@155
|
623 function Bar:UpdateDefaultStateAnchor()
|
flickerstreak@155
|
624 local point, frame, relPoint, x, y = self:GetAnchor()
|
flickerstreak@155
|
625 local f = self:GetFrame()
|
flickerstreak@155
|
626 f:SetAttribute("defaultAnchor-point",point)
|
flickerstreak@155
|
627 f:SetAttribute("defaultAnchor-relPoint",relPoint)
|
flickerstreak@155
|
628 f:SetAttribute("defaultAnchor-x",x)
|
flickerstreak@155
|
629 f:SetAttribute("defaultAnchor-y",y)
|
flickerstreak@155
|
630 self:SetFrameRef("defaultAnchor",_G[frame or "UIParent"])
|
flickerstreak@155
|
631 f:Execute([[
|
flickerstreak@155
|
632 for _, k in pairs(anchorKeys) do
|
flickerstreak@155
|
633 defaultAnchor[k] = self:GetAttribute("defaultAnchor-"..k)
|
flickerstreak@155
|
634 end
|
flickerstreak@155
|
635 defaultAnchor.frame = self:GetAttribute("frameref-defaultAnchor")
|
flickerstreak@155
|
636 ]])
|
flickerstreak@155
|
637 end
|
flickerstreak@155
|
638
|
flickerstreak@155
|
639 function Bar:UpdateDefaultStateAlpha()
|
flickerstreak@155
|
640 local f = self:GetFrame()
|
flickerstreak@155
|
641 f:SetAttribute("defaultAlpha",self:GetAlpha())
|
flickerstreak@155
|
642 f:Execute([[
|
flickerstreak@155
|
643 defaultAlpha = self:GetAttribute("defaultAlpha")
|
flickerstreak@155
|
644 ]])
|
flickerstreak@155
|
645 end
|