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