flickerstreak@175
|
1 local addonName, addonTable = ...
|
flickerstreak@175
|
2 local ReAction = addonTable.ReAction
|
flickerstreak@122
|
3 local L = ReAction.L
|
flickerstreak@183
|
4 local LKB = ReAction.LKB
|
flickerstreak@122
|
5 local _G = _G
|
flickerstreak@122
|
6 local CreateFrame = CreateFrame
|
flickerstreak@122
|
7 local floor = math.floor
|
flickerstreak@122
|
8 local fmod = math.fmod
|
flickerstreak@122
|
9 local format = string.format
|
flickerstreak@122
|
10
|
flickerstreak@193
|
11 local LSG = LibStub("ReAction-LibShowActionGrid-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@159
|
118 unithide = not newstate or newstate == "hide"
|
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@157
|
130 -- For reference
|
flickerstreak@157
|
131 -- the option field names must match the field names of the options table, below
|
flickerstreak@157
|
132 local stateProperties = {
|
flickerstreak@157
|
133 hide = true,
|
flickerstreak@157
|
134 --keybindState = true, TODO: broken
|
flickerstreak@157
|
135 anchorEnable = true,
|
flickerstreak@157
|
136 anchorFrame = true,
|
flickerstreak@157
|
137 anchorPoint = true,
|
flickerstreak@157
|
138 anchorRelPoint = true,
|
flickerstreak@157
|
139 anchorX = true,
|
flickerstreak@157
|
140 anchorY = true,
|
flickerstreak@157
|
141 enableScale = true,
|
flickerstreak@157
|
142 scale = true,
|
flickerstreak@157
|
143 enableAlpha = true,
|
flickerstreak@157
|
144 alpha = true,
|
flickerstreak@157
|
145 }
|
flickerstreak@157
|
146
|
flickerstreak@157
|
147
|
flickerstreak@157
|
148 ---- Utility functions ----
|
flickerstreak@157
|
149
|
flickerstreak@157
|
150 -- traverse a table tree by key list and fetch the result or first nil
|
flickerstreak@157
|
151 local function tfetch(t, ...)
|
flickerstreak@157
|
152 for i = 1, select('#', ...) do
|
flickerstreak@157
|
153 t = t and t[select(i, ...)]
|
flickerstreak@157
|
154 end
|
flickerstreak@157
|
155 return t
|
flickerstreak@157
|
156 end
|
flickerstreak@157
|
157
|
flickerstreak@157
|
158 -- traverse a table tree by key list and build tree as necessary
|
flickerstreak@157
|
159 local function tbuild(t, ...)
|
flickerstreak@157
|
160 for i = 1, select('#', ...) do
|
flickerstreak@157
|
161 local key = select(i, ...)
|
flickerstreak@157
|
162 if not t[key] then t[key] = { } end
|
flickerstreak@157
|
163 t = t[key]
|
flickerstreak@157
|
164 end
|
flickerstreak@157
|
165 return t
|
flickerstreak@157
|
166 end
|
flickerstreak@157
|
167
|
flickerstreak@157
|
168 -- return a new array of keys of table 't', sorted by comparing
|
flickerstreak@157
|
169 -- sub-fields (obtained via tfetch) of the table values
|
flickerstreak@157
|
170 local function fieldsort( t, ... )
|
flickerstreak@157
|
171 local r = { }
|
flickerstreak@157
|
172 for k in pairs(t) do
|
flickerstreak@157
|
173 table.insert(r,k)
|
flickerstreak@157
|
174 end
|
flickerstreak@157
|
175 local path = { ... }
|
flickerstreak@157
|
176 table.sort(r, function(lhs, rhs)
|
flickerstreak@157
|
177 local olhs = tfetch(t[lhs], unpack(path)) or 0
|
flickerstreak@157
|
178 local orhs = tfetch(t[rhs], unpack(path)) or 0
|
flickerstreak@157
|
179 return olhs < orhs
|
flickerstreak@157
|
180 end)
|
flickerstreak@157
|
181 return r
|
flickerstreak@157
|
182 end
|
flickerstreak@157
|
183
|
flickerstreak@155
|
184
|
flickerstreak@147
|
185 ---- Bar class ----
|
flickerstreak@122
|
186 local Bar = { }
|
flickerstreak@147
|
187 local frameList = { }
|
flickerstreak@122
|
188
|
flickerstreak@122
|
189 ReAction.Bar = Bar -- export to ReAction
|
flickerstreak@122
|
190
|
Flick@234
|
191 function Bar:New( name, config, buttonClass )
|
flickerstreak@122
|
192 if type(config) ~= "table" then
|
flickerstreak@122
|
193 error("ReAction.Bar: config table required")
|
flickerstreak@122
|
194 end
|
flickerstreak@122
|
195
|
flickerstreak@122
|
196 -- create new self
|
flickerstreak@122
|
197 self = setmetatable(
|
flickerstreak@122
|
198 {
|
Flick@234
|
199 config = config,
|
Flick@234
|
200 name = name,
|
Flick@234
|
201 buttons = { },
|
Flick@234
|
202 buttonClass = buttonClass,
|
Flick@234
|
203 width = config.width or 480,
|
Flick@234
|
204 height = config.height or 40,
|
flickerstreak@122
|
205 },
|
flickerstreak@147
|
206 {__index = self} )
|
flickerstreak@122
|
207
|
flickerstreak@122
|
208 -- The frame type is 'Button' in order to have an OnClick handler. However, the frame itself is
|
flickerstreak@122
|
209 -- not mouse-clickable by the user.
|
flickerstreak@122
|
210 local parent = config.parent and (ReAction:GetBar(config.parent) or _G[config.parent]) or UIParent
|
flickerstreak@147
|
211 name = name and "ReAction-"..name
|
flickerstreak@147
|
212 local f = name and frameList[name]
|
flickerstreak@147
|
213 if not f then
|
flickerstreak@147
|
214 f = CreateFrame("Button", name, parent, "SecureHandlerStateTemplate, SecureHandlerClickTemplate")
|
flickerstreak@147
|
215 if name then
|
flickerstreak@147
|
216 frameList[name] = f
|
flickerstreak@147
|
217 end
|
flickerstreak@147
|
218 end
|
flickerstreak@122
|
219 f:SetFrameStrata("MEDIUM")
|
flickerstreak@122
|
220 f:SetWidth(self.width)
|
flickerstreak@146
|
221 f:SetHeight(self.height)
|
flickerstreak@122
|
222 f:SetAlpha(config.alpha or 1.0)
|
flickerstreak@122
|
223 f:Show()
|
flickerstreak@122
|
224 f:EnableMouse(false)
|
flickerstreak@122
|
225 f:SetClampedToScreen(true)
|
flickerstreak@171
|
226 LSG:AddFrame(f)
|
flickerstreak@122
|
227
|
flickerstreak@155
|
228 -- secure handlers
|
flickerstreak@155
|
229 f:Execute(_reaction_init)
|
flickerstreak@155
|
230 f:SetAttribute("_onstate-reaction", _onstate_reaction)
|
flickerstreak@155
|
231 f:SetAttribute("_onstate-showgrid", _onstate_showgrid)
|
flickerstreak@155
|
232 f:SetAttribute("_onstate-unitexists", _onstate_unitexists)
|
flickerstreak@155
|
233 f:SetAttribute("_onclick", _onclick)
|
flickerstreak@155
|
234
|
flickerstreak@155
|
235 -- secure handler CallMethod()s
|
flickerstreak@155
|
236 f.UpdateShowGrid = function() self:UpdateShowGrid() end
|
flickerstreak@155
|
237 f.StateRefresh = function() self:RefreshControls() end
|
flickerstreak@155
|
238 f.UpdateHiddenLabel = function(f,hidden) self:SetLabelSubtext(hidden and L["Hidden"]) end
|
flickerstreak@122
|
239
|
flickerstreak@122
|
240 -- Override the default frame accessor to provide strict read-only access
|
flickerstreak@122
|
241 function self:GetFrame()
|
flickerstreak@122
|
242 return f
|
flickerstreak@122
|
243 end
|
flickerstreak@122
|
244
|
flickerstreak@122
|
245 self:ApplyAnchor()
|
flickerstreak@147
|
246 self:SetConfigMode(ReAction:GetConfigMode())
|
flickerstreak@147
|
247 self:SetKeybindMode(ReAction:GetKeybindMode())
|
flickerstreak@147
|
248
|
flickerstreak@213
|
249 if ReAction.LBF then
|
flickerstreak@213
|
250 local g = ReAction.LBF:Group(L["ReAction"], self.name)
|
flickerstreak@213
|
251 self.config.ButtonFacade = self.config.ButtonFacade or {
|
flickerstreak@213
|
252 skinID = "Blizzard",
|
flickerstreak@213
|
253 backdrop = true,
|
flickerstreak@213
|
254 gloss = 0,
|
flickerstreak@213
|
255 colors = {},
|
flickerstreak@213
|
256 }
|
flickerstreak@213
|
257 local c = self.config.ButtonFacade
|
flickerstreak@213
|
258 g:Skin(c.skinID, c.gloss, c.backdrop, c.colors)
|
flickerstreak@213
|
259 self.LBFGroup = g
|
flickerstreak@213
|
260 end
|
flickerstreak@213
|
261
|
flickerstreak@122
|
262 ReAction.RegisterCallback(self, "OnConfigModeChanged")
|
flickerstreak@122
|
263
|
Flick@234
|
264 buttonClass:SetupBar(self)
|
Flick@234
|
265
|
flickerstreak@122
|
266 return self
|
flickerstreak@122
|
267 end
|
flickerstreak@122
|
268
|
flickerstreak@122
|
269 function Bar:Destroy()
|
flickerstreak@122
|
270 local f = self:GetFrame()
|
Flick@234
|
271 for idx, b in self:IterateButtons() do
|
Flick@234
|
272 b:Destroy()
|
Flick@234
|
273 end
|
flickerstreak@122
|
274 f:UnregisterAllEvents()
|
flickerstreak@125
|
275 self:ShowControls(false)
|
flickerstreak@122
|
276 ReAction.UnregisterAllCallbacks(self)
|
flickerstreak@171
|
277 LKB.UnregisterAllCallbacks(self)
|
flickerstreak@213
|
278 if self.LBFGroup then
|
flickerstreak@213
|
279 self.LBFGroup:Delete(true)
|
flickerstreak@213
|
280 end
|
flickerstreak@171
|
281 LSG:RemoveFrame(f)
|
flickerstreak@122
|
282 f:SetParent(UIParent)
|
flickerstreak@122
|
283 f:ClearAllPoints()
|
flickerstreak@147
|
284 f:Hide()
|
flickerstreak@122
|
285 end
|
flickerstreak@122
|
286
|
flickerstreak@147
|
287 --
|
flickerstreak@147
|
288 -- Events
|
flickerstreak@147
|
289 --
|
flickerstreak@147
|
290
|
flickerstreak@147
|
291 function Bar:OnConfigModeChanged(event, mode)
|
flickerstreak@147
|
292 self:SetConfigMode(mode)
|
flickerstreak@123
|
293 end
|
flickerstreak@123
|
294
|
flickerstreak@153
|
295 --
|
flickerstreak@153
|
296 -- Accessors
|
flickerstreak@153
|
297 --
|
flickerstreak@153
|
298
|
flickerstreak@153
|
299 function Bar:GetName()
|
flickerstreak@153
|
300 return self.name
|
flickerstreak@153
|
301 end
|
flickerstreak@153
|
302
|
flickerstreak@153
|
303 -- only ReAction:RenameBar() should call this function. Calling from any other
|
flickerstreak@153
|
304 -- context will desync the bar list in the ReAction class.
|
flickerstreak@153
|
305 function Bar:SetName(name)
|
flickerstreak@213
|
306 if self.LBFGroup then
|
flickerstreak@213
|
307 -- LBF doesn't offer a method of renaming a group, so delete and remake the group.
|
flickerstreak@213
|
308 local c = self.config.ButtonFacade
|
flickerstreak@213
|
309 local g = ReAction.LBF:Group(L["ReAction"], name)
|
Flick@234
|
310 for idx, b in self:IterateButtons() do
|
flickerstreak@213
|
311 self.LBFGroup:RemoveButton(b:GetFrame(), true)
|
flickerstreak@213
|
312 g:AddButton(b:GetFrame())
|
flickerstreak@213
|
313 end
|
flickerstreak@213
|
314 self.LBFGroup:Delete(true)
|
flickerstreak@213
|
315 self.LBFGroup = g
|
flickerstreak@213
|
316 self.LBFGroup:Skin(c.skinID, c.gloss, c.backdrop, c.colors)
|
flickerstreak@213
|
317 end
|
flickerstreak@153
|
318 self.name = name
|
flickerstreak@154
|
319 if self.overlay then
|
flickerstreak@154
|
320 self.overlay:SetLabel(self.name)
|
flickerstreak@154
|
321 end
|
flickerstreak@153
|
322 end
|
flickerstreak@153
|
323
|
flickerstreak@153
|
324 function Bar:GetFrame()
|
flickerstreak@153
|
325 -- this method is included for documentation purposes. It is overridden
|
flickerstreak@153
|
326 -- for each object in the :New() method.
|
flickerstreak@153
|
327 error("Invalid Bar object: used without initialization")
|
flickerstreak@153
|
328 end
|
flickerstreak@153
|
329
|
Flick@234
|
330 function Bar:GetButton(idx)
|
Flick@234
|
331 return self.buttons[idx]
|
Flick@234
|
332 end
|
Flick@234
|
333
|
flickerstreak@153
|
334 function Bar:GetConfig()
|
flickerstreak@153
|
335 return self.config
|
flickerstreak@153
|
336 end
|
flickerstreak@153
|
337
|
flickerstreak@153
|
338 function Bar:GetAnchor()
|
flickerstreak@122
|
339 local c = self.config
|
flickerstreak@153
|
340 return (c.point or "CENTER"),
|
flickerstreak@153
|
341 (c.anchor or self:GetFrame():GetParent():GetName()),
|
flickerstreak@153
|
342 (c.relpoint or c.point or "CENTER"),
|
flickerstreak@153
|
343 (c.x or 0),
|
flickerstreak@153
|
344 (c.y or 0)
|
flickerstreak@122
|
345 end
|
flickerstreak@122
|
346
|
flickerstreak@122
|
347 function Bar:SetAnchor(point, frame, relativePoint, x, y)
|
flickerstreak@122
|
348 local c = self.config
|
flickerstreak@122
|
349 c.point = point or c.point
|
flickerstreak@122
|
350 c.anchor = frame or c.anchor
|
flickerstreak@122
|
351 c.relpoint = relativePoint or c.relpoint
|
flickerstreak@122
|
352 c.x = x or c.x
|
flickerstreak@122
|
353 c.y = y or c.y
|
flickerstreak@122
|
354 self:ApplyAnchor()
|
flickerstreak@122
|
355 ReAction:RefreshBar(self)
|
flickerstreak@122
|
356 end
|
flickerstreak@122
|
357
|
flickerstreak@122
|
358 function Bar:GetSize()
|
flickerstreak@122
|
359 local f = self:GetFrame()
|
flickerstreak@122
|
360 return f:GetWidth(), f:GetHeight()
|
flickerstreak@122
|
361 end
|
flickerstreak@122
|
362
|
flickerstreak@122
|
363 function Bar:SetSize(w,h)
|
flickerstreak@122
|
364 local f = self:GetFrame()
|
flickerstreak@122
|
365 self.config.width = w
|
flickerstreak@122
|
366 self.config.height = h
|
flickerstreak@122
|
367 f:SetWidth(w)
|
flickerstreak@122
|
368 f:SetHeight(h)
|
flickerstreak@122
|
369 end
|
flickerstreak@122
|
370
|
flickerstreak@122
|
371 function Bar:GetButtonSize()
|
flickerstreak@122
|
372 local w = self.config.btnWidth or 32
|
flickerstreak@122
|
373 local h = self.config.btnHeight or 32
|
flickerstreak@122
|
374 -- TODO: get from modules?
|
flickerstreak@122
|
375 return w,h
|
flickerstreak@122
|
376 end
|
flickerstreak@122
|
377
|
flickerstreak@122
|
378 function Bar:SetButtonSize(w,h)
|
flickerstreak@122
|
379 if w > 0 and h > 0 then
|
flickerstreak@122
|
380 self.config.btnWidth = w
|
flickerstreak@122
|
381 self.config.btnHeight = h
|
flickerstreak@122
|
382 end
|
flickerstreak@122
|
383 ReAction:RefreshBar(self)
|
flickerstreak@122
|
384 end
|
flickerstreak@122
|
385
|
flickerstreak@153
|
386 function Bar:GetNumButtons()
|
flickerstreak@153
|
387 local r,c = self:GetButtonGrid()
|
flickerstreak@153
|
388 return r*c
|
flickerstreak@153
|
389 end
|
flickerstreak@153
|
390
|
flickerstreak@122
|
391 function Bar:GetButtonGrid()
|
flickerstreak@122
|
392 local cfg = self.config
|
flickerstreak@122
|
393 local r = cfg.btnRows or 1
|
flickerstreak@122
|
394 local c = cfg.btnColumns or 1
|
flickerstreak@122
|
395 local s = cfg.spacing or 4
|
flickerstreak@122
|
396 return r,c,s
|
flickerstreak@122
|
397 end
|
flickerstreak@122
|
398
|
flickerstreak@122
|
399 function Bar:SetButtonGrid(r,c,s)
|
flickerstreak@122
|
400 if r > 0 and c > 0 and s > 0 then
|
flickerstreak@122
|
401 local cfg = self.config
|
flickerstreak@122
|
402 cfg.btnRows = r
|
flickerstreak@122
|
403 cfg.btnColumns = c
|
flickerstreak@122
|
404 cfg.spacing = s
|
flickerstreak@122
|
405 end
|
Flick@234
|
406 self.buttonClass:SetupBar(self)
|
flickerstreak@122
|
407 ReAction:RefreshBar(self)
|
flickerstreak@122
|
408 end
|
flickerstreak@122
|
409
|
flickerstreak@122
|
410 function Bar:GetAlpha()
|
flickerstreak@122
|
411 return self.config.alpha or 1.0
|
flickerstreak@122
|
412 end
|
flickerstreak@122
|
413
|
flickerstreak@122
|
414 function Bar:SetAlpha(value)
|
flickerstreak@122
|
415 self.config.alpha = value
|
flickerstreak@122
|
416 self:GetFrame():SetAlpha(value or 1.0)
|
flickerstreak@155
|
417 self:UpdateDefaultStateAlpha()
|
flickerstreak@122
|
418 ReAction:RefreshBar(self)
|
flickerstreak@122
|
419 end
|
flickerstreak@122
|
420
|
flickerstreak@122
|
421 function Bar:IterateButtons()
|
Flick@234
|
422 -- iterator returns idx, button, but does NOT iterate in index order
|
flickerstreak@122
|
423 return pairs(self.buttons)
|
flickerstreak@122
|
424 end
|
flickerstreak@122
|
425
|
flickerstreak@153
|
426 --
|
flickerstreak@153
|
427 -- Methods
|
flickerstreak@153
|
428 --
|
flickerstreak@153
|
429
|
flickerstreak@147
|
430 function Bar:SetConfigMode(mode)
|
flickerstreak@155
|
431 self:SetSecureData("showAll",mode)
|
flickerstreak@147
|
432 self:ShowControls(mode)
|
Flick@234
|
433 for idx, b in self:IterateButtons() do
|
flickerstreak@147
|
434 b:ShowGridTemp(mode)
|
flickerstreak@147
|
435 b:UpdateActionIDLabel(mode)
|
flickerstreak@147
|
436 end
|
flickerstreak@147
|
437 end
|
flickerstreak@147
|
438
|
flickerstreak@147
|
439 function Bar:SetKeybindMode(mode)
|
flickerstreak@155
|
440 self:SetSecureData("showAll",mode)
|
Flick@234
|
441 for idx, b in self:IterateButtons() do
|
flickerstreak@147
|
442 b:SetKeybindMode(mode)
|
flickerstreak@147
|
443 end
|
flickerstreak@147
|
444 end
|
flickerstreak@147
|
445
|
flickerstreak@153
|
446 function Bar:ApplyAnchor()
|
flickerstreak@153
|
447 local f = self:GetFrame()
|
flickerstreak@153
|
448 local c = self.config
|
flickerstreak@153
|
449 local p = c.point
|
flickerstreak@153
|
450
|
flickerstreak@153
|
451 f:SetWidth(c.width)
|
flickerstreak@153
|
452 f:SetHeight(c.height)
|
flickerstreak@153
|
453 f:ClearAllPoints()
|
flickerstreak@153
|
454
|
flickerstreak@153
|
455 if p then
|
flickerstreak@153
|
456 local a = f:GetParent()
|
flickerstreak@153
|
457 if c.anchor then
|
flickerstreak@153
|
458 local bar = ReAction:GetBar(c.anchor)
|
flickerstreak@153
|
459 if bar then
|
flickerstreak@153
|
460 a = bar:GetFrame()
|
flickerstreak@153
|
461 else
|
flickerstreak@153
|
462 a = _G[c.anchor]
|
flickerstreak@153
|
463 end
|
flickerstreak@153
|
464 end
|
flickerstreak@153
|
465 local fr = a or f:GetParent()
|
flickerstreak@153
|
466 f:SetPoint(p, a or f:GetParent(), c.relpoint, c.x or 0, c.y or 0)
|
flickerstreak@153
|
467 else
|
flickerstreak@153
|
468 f:SetPoint("CENTER")
|
flickerstreak@153
|
469 end
|
flickerstreak@155
|
470
|
flickerstreak@155
|
471 self:UpdateDefaultStateAnchor()
|
flickerstreak@153
|
472 end
|
flickerstreak@153
|
473
|
flickerstreak@153
|
474 function Bar:ClipNButtons( n )
|
flickerstreak@153
|
475 local cfg = self.config
|
flickerstreak@153
|
476 local r = cfg.btnRows or 1
|
flickerstreak@153
|
477 local c = cfg.btnColumns or 1
|
flickerstreak@153
|
478
|
flickerstreak@153
|
479 cfg.btnRows = ceil(n/c)
|
flickerstreak@153
|
480 cfg.btnColumns = min(n,c)
|
flickerstreak@153
|
481 end
|
flickerstreak@153
|
482
|
flickerstreak@153
|
483 function Bar:AddButton(idx, button)
|
flickerstreak@153
|
484 local f = self:GetFrame()
|
flickerstreak@153
|
485
|
Flick@234
|
486 self.buttons[idx] = button
|
flickerstreak@153
|
487
|
flickerstreak@153
|
488 -- Store a properly wrapped reference to the child frame as an attribute
|
flickerstreak@153
|
489 -- (accessible via "frameref-btn#")
|
flickerstreak@153
|
490 f:SetFrameRef(format("btn%d",idx), button:GetFrame())
|
flickerstreak@213
|
491
|
flickerstreak@213
|
492 -- button constructors are responsible for calling SkinButton
|
flickerstreak@153
|
493 end
|
flickerstreak@153
|
494
|
flickerstreak@153
|
495 function Bar:RemoveButton(button)
|
Flick@234
|
496 local idx = button:GetIndex()
|
flickerstreak@153
|
497 if idx then
|
flickerstreak@153
|
498 self:GetFrame():SetAttribute(format("frameref-btn%d",idx),nil)
|
Flick@234
|
499 self.buttons[idx] = nil
|
flickerstreak@153
|
500 end
|
flickerstreak@213
|
501 if self.LBFGroup then
|
flickerstreak@213
|
502 self.LBFGroup:RemoveButton(button:GetFrame(),true)
|
flickerstreak@213
|
503 end
|
flickerstreak@153
|
504 end
|
flickerstreak@153
|
505
|
flickerstreak@122
|
506 function Bar:PlaceButton(button, baseW, baseH)
|
Flick@234
|
507 local idx = button:GetIndex()
|
flickerstreak@122
|
508 if idx then
|
flickerstreak@122
|
509 local r, c, s = self:GetButtonGrid()
|
flickerstreak@122
|
510 local bh, bw = self:GetButtonSize()
|
flickerstreak@122
|
511 local row, col = floor((idx-1)/c), fmod((idx-1),c) -- zero-based
|
flickerstreak@122
|
512 local x, y = col*bw + (col+0.5)*s, -(row*bh + (row+0.5)*s)
|
flickerstreak@122
|
513 local scale = bw/baseW
|
flickerstreak@122
|
514 local b = button:GetFrame()
|
flickerstreak@122
|
515
|
flickerstreak@122
|
516 b:ClearAllPoints()
|
flickerstreak@122
|
517 b:SetPoint("TOPLEFT",x/scale,y/scale)
|
flickerstreak@122
|
518 b:SetScale(scale)
|
flickerstreak@122
|
519 end
|
flickerstreak@122
|
520 end
|
flickerstreak@122
|
521
|
flickerstreak@213
|
522 function Bar:SkinButton( button, data )
|
flickerstreak@213
|
523 if self.LBFGroup then
|
flickerstreak@213
|
524 self.LBFGroup:AddButton(button:GetFrame(), data)
|
flickerstreak@213
|
525 end
|
flickerstreak@147
|
526 end
|
flickerstreak@148
|
527
|
flickerstreak@155
|
528 function Bar:UpdateShowGrid()
|
Flick@234
|
529 for idx, button in self:IterateButtons() do
|
flickerstreak@155
|
530 button:UpdateShowGrid()
|
flickerstreak@155
|
531 end
|
flickerstreak@155
|
532 end
|
flickerstreak@155
|
533
|
flickerstreak@154
|
534 function Bar:ShowControls(show)
|
flickerstreak@154
|
535 if show then
|
flickerstreak@155
|
536 if not self.overlay then
|
flickerstreak@155
|
537 self.overlay = Bar.Overlay:New(self) -- see Overlay.lua
|
flickerstreak@154
|
538 end
|
flickerstreak@155
|
539 self.overlay:Show()
|
flickerstreak@155
|
540 self:RefreshSecureState()
|
flickerstreak@155
|
541 elseif self.overlay then
|
flickerstreak@155
|
542 self.overlay:Hide()
|
flickerstreak@154
|
543 end
|
flickerstreak@154
|
544 end
|
flickerstreak@154
|
545
|
flickerstreak@154
|
546 function Bar:RefreshControls()
|
flickerstreak@154
|
547 if self.overlay and self.overlay:IsShown() then
|
flickerstreak@154
|
548 self.overlay:RefreshControls()
|
flickerstreak@154
|
549 end
|
flickerstreak@154
|
550 end
|
flickerstreak@154
|
551
|
flickerstreak@154
|
552 function Bar:SetLabelSubtext(text)
|
flickerstreak@154
|
553 if self.overlay then
|
flickerstreak@154
|
554 self.overlay:SetLabelSubtext(text)
|
flickerstreak@154
|
555 end
|
flickerstreak@154
|
556 end
|
flickerstreak@154
|
557
|
flickerstreak@154
|
558 --
|
flickerstreak@154
|
559 -- Secure state functions
|
flickerstreak@154
|
560 --
|
flickerstreak@154
|
561
|
flickerstreak@155
|
562 function Bar:GetSecureState()
|
flickerstreak@155
|
563 local env = GetManagedEnvironment(self:GetFrame())
|
flickerstreak@155
|
564 return env and env.state
|
flickerstreak@155
|
565 end
|
flickerstreak@155
|
566
|
flickerstreak@155
|
567 function Bar:GetStateProperty(state, propname)
|
flickerstreak@155
|
568 -- override in modules/State.lua for now
|
flickerstreak@155
|
569 end
|
flickerstreak@155
|
570
|
flickerstreak@155
|
571 function Bar:SetStateProperty(state, propname, value)
|
flickerstreak@155
|
572 -- override in modules/State.lua for now
|
flickerstreak@155
|
573 end
|
flickerstreak@155
|
574
|
flickerstreak@155
|
575 function Bar:RefreshSecureState()
|
flickerstreak@155
|
576 self:GetFrame():Execute(_reaction_refresh)
|
flickerstreak@155
|
577 end
|
flickerstreak@155
|
578
|
flickerstreak@155
|
579 -- usage: SetSecureData(globalname, [tblkey1, tblkey2, ...], value)
|
flickerstreak@155
|
580 function Bar:SetSecureData( ... )
|
flickerstreak@155
|
581 local n = select('#',...)
|
flickerstreak@155
|
582 if n < 2 then
|
flickerstreak@155
|
583 error("ReAction.Bar:SetSecureData() requires at least 2 arguments")
|
flickerstreak@155
|
584 end
|
flickerstreak@155
|
585 local f = self:GetFrame()
|
flickerstreak@155
|
586 f:SetAttribute("data-depth",n-1)
|
flickerstreak@155
|
587 f:SetAttribute("data-value",select(n,...))
|
flickerstreak@155
|
588 for i = 1, n-1 do
|
flickerstreak@155
|
589 local key = select(i,...)
|
flickerstreak@155
|
590 if key == nil then
|
flickerstreak@155
|
591 error("ReAction.Bar:SetSecureData() - nil table key in argument list (#"..i..")")
|
flickerstreak@155
|
592 end
|
flickerstreak@155
|
593 f:SetAttribute("data-key-"..i, key)
|
flickerstreak@155
|
594 end
|
flickerstreak@155
|
595 f:Execute(
|
flickerstreak@155
|
596 [[
|
flickerstreak@155
|
597 local n = self:GetAttribute("data-depth")
|
flickerstreak@155
|
598 if n > 0 then
|
flickerstreak@155
|
599 local value = self:GetAttribute("data-value")
|
flickerstreak@155
|
600 local t = _G
|
flickerstreak@155
|
601 for i = 1, n do
|
flickerstreak@155
|
602 local key = self:GetAttribute("data-key-"..i)
|
flickerstreak@155
|
603 if not key then return end
|
flickerstreak@155
|
604 if not t[key] then
|
flickerstreak@155
|
605 t[key] = newtable()
|
flickerstreak@155
|
606 end
|
flickerstreak@155
|
607 if i == n then
|
flickerstreak@155
|
608 t[key] = value
|
flickerstreak@155
|
609 else
|
flickerstreak@155
|
610 t = t[key]
|
flickerstreak@155
|
611 end
|
flickerstreak@155
|
612 end
|
flickerstreak@155
|
613 end
|
flickerstreak@155
|
614 ]])
|
flickerstreak@155
|
615 self:RefreshSecureState()
|
flickerstreak@155
|
616 end
|
flickerstreak@155
|
617
|
flickerstreak@155
|
618 function Bar:SetSecureStateData( state, key, value )
|
flickerstreak@155
|
619 self:SetSecureData("settings",state,key,value)
|
flickerstreak@155
|
620 end
|
flickerstreak@155
|
621
|
flickerstreak@155
|
622 -- sets a snippet to be run as an extension to _onstate-reaction
|
flickerstreak@155
|
623 function Bar:SetSecureStateExtension( id, snippet )
|
flickerstreak@155
|
624 if id == nil then
|
flickerstreak@155
|
625 error("ReAction.Bar:SetSecureStateExtension() requires an id")
|
flickerstreak@155
|
626 end
|
flickerstreak@155
|
627 local f = self:GetFrame()
|
flickerstreak@155
|
628 f:SetAttribute("input-secure-ext-id",id)
|
flickerstreak@155
|
629 f:SetAttribute("secure-ext-"..id,snippet)
|
flickerstreak@155
|
630 f:Execute(
|
flickerstreak@155
|
631 [[
|
flickerstreak@155
|
632 local id = self:GetAttribute("input-secure-ext-id")
|
flickerstreak@155
|
633 if id then
|
flickerstreak@155
|
634 extensions[id] = self:GetAttribute("secure-ext-"..id) or nil
|
flickerstreak@155
|
635 end
|
flickerstreak@155
|
636 ]])
|
flickerstreak@155
|
637 self:RefreshSecureState()
|
flickerstreak@155
|
638 end
|
flickerstreak@155
|
639
|
flickerstreak@155
|
640 function Bar:SetFrameRef( name, refFrame )
|
flickerstreak@155
|
641 if refFrame then
|
flickerstreak@155
|
642 local _, explicit = refFrame:IsProtected()
|
flickerstreak@155
|
643 if not explicit then
|
flickerstreak@155
|
644 refFrame = nil
|
flickerstreak@155
|
645 end
|
flickerstreak@155
|
646 end
|
flickerstreak@155
|
647 if refFrame then
|
flickerstreak@155
|
648 self:GetFrame():SetFrameRef(name,refFrame)
|
flickerstreak@155
|
649 else
|
flickerstreak@155
|
650 self:GetFrame():SetAttribute("frameref-"..name,nil)
|
flickerstreak@155
|
651 end
|
flickerstreak@155
|
652 end
|
flickerstreak@155
|
653
|
flickerstreak@157
|
654 function Bar:SetStateDriver( states )
|
flickerstreak@157
|
655 if states then
|
flickerstreak@157
|
656 for state, props in pairs(states) do
|
flickerstreak@157
|
657 self:SetSecureStateData(state, "active_", true) -- make sure there's a 'settings' field for this state
|
flickerstreak@157
|
658 for propname, value in pairs(props) do
|
flickerstreak@157
|
659 if propname == "anchorFrame" then
|
flickerstreak@157
|
660 self:SetFrameRef("anchor-"..state, _G[value])
|
flickerstreak@157
|
661 elseif propname == "rule" then
|
flickerstreak@157
|
662 -- do nothing
|
flickerstreak@157
|
663 else
|
flickerstreak@157
|
664 self:SetSecureStateData(state, propname, value)
|
flickerstreak@157
|
665 end
|
flickerstreak@157
|
666 end
|
flickerstreak@157
|
667 end
|
flickerstreak@157
|
668 end
|
flickerstreak@157
|
669 local rule = states and self:BuildStateRule(states)
|
flickerstreak@155
|
670 if rule then
|
flickerstreak@155
|
671 RegisterStateDriver(self:GetFrame(),"reaction",rule)
|
flickerstreak@155
|
672 elseif self.statedriver then
|
flickerstreak@155
|
673 UnregisterStateDriver(self:GetFrame(),"reaction")
|
flickerstreak@155
|
674 end
|
flickerstreak@155
|
675 self.statedriver = rule
|
flickerstreak@157
|
676 self:BuildStateKeybinds(states)
|
flickerstreak@155
|
677 self:RefreshSecureState()
|
flickerstreak@155
|
678 end
|
flickerstreak@155
|
679
|
flickerstreak@148
|
680 -- pass unit=nil to set up the unit elsewhere, if you want something more complex
|
flickerstreak@148
|
681 function Bar:RegisterUnitWatch( unit, enable )
|
flickerstreak@148
|
682 local f = self:GetFrame()
|
flickerstreak@148
|
683 if unit then
|
flickerstreak@148
|
684 f:SetAttribute("unit",unit)
|
flickerstreak@148
|
685 end
|
flickerstreak@156
|
686 if enable then
|
Flick@234
|
687 if not self.unitwatch then
|
Flick@234
|
688 RegisterUnitWatch(self:GetFrame(),true)
|
Flick@234
|
689 end
|
flickerstreak@156
|
690 elseif self.unitwatch then
|
flickerstreak@156
|
691 UnregisterUnitWatch(self:GetFrame())
|
flickerstreak@156
|
692 end
|
flickerstreak@148
|
693 self.unitwatch = enable
|
flickerstreak@156
|
694 self:RefreshSecureState()
|
flickerstreak@148
|
695 end
|
flickerstreak@148
|
696
|
flickerstreak@155
|
697 function Bar:SetStateKeybind( key, state )
|
flickerstreak@155
|
698 local f = self:GetFrame()
|
flickerstreak@155
|
699 local binds = self.statebinds
|
flickerstreak@155
|
700 if not binds then
|
flickerstreak@155
|
701 binds = { }
|
flickerstreak@155
|
702 self.statebinds = binds
|
flickerstreak@155
|
703 end
|
flickerstreak@155
|
704
|
flickerstreak@155
|
705 -- clear the old binding, if any
|
flickerstreak@155
|
706 if binds[state] then
|
flickerstreak@155
|
707 SetOverrideBinding(f, false, binds[state], nil)
|
flickerstreak@155
|
708 end
|
flickerstreak@155
|
709
|
flickerstreak@155
|
710 if key then
|
flickerstreak@157
|
711 SetOverrideBindingClick(f, false, key, f:GetName(), state) -- state name is virtual mouse button
|
flickerstreak@155
|
712 end
|
flickerstreak@155
|
713 binds[state] = key
|
flickerstreak@155
|
714 end
|
flickerstreak@155
|
715
|
flickerstreak@155
|
716 function Bar:GetStateKeybind( state )
|
flickerstreak@155
|
717 if self.statebinds and state then
|
flickerstreak@155
|
718 return self.statebinds[state]
|
flickerstreak@155
|
719 end
|
flickerstreak@155
|
720 end
|
flickerstreak@155
|
721
|
flickerstreak@155
|
722 function Bar:UpdateDefaultStateAnchor()
|
flickerstreak@155
|
723 local point, frame, relPoint, x, y = self:GetAnchor()
|
flickerstreak@155
|
724 local f = self:GetFrame()
|
flickerstreak@155
|
725 f:SetAttribute("defaultAnchor-point",point)
|
flickerstreak@155
|
726 f:SetAttribute("defaultAnchor-relPoint",relPoint)
|
flickerstreak@155
|
727 f:SetAttribute("defaultAnchor-x",x)
|
flickerstreak@155
|
728 f:SetAttribute("defaultAnchor-y",y)
|
flickerstreak@155
|
729 self:SetFrameRef("defaultAnchor",_G[frame or "UIParent"])
|
flickerstreak@155
|
730 f:Execute([[
|
flickerstreak@155
|
731 for _, k in pairs(anchorKeys) do
|
flickerstreak@155
|
732 defaultAnchor[k] = self:GetAttribute("defaultAnchor-"..k)
|
flickerstreak@155
|
733 end
|
flickerstreak@155
|
734 defaultAnchor.frame = self:GetAttribute("frameref-defaultAnchor")
|
flickerstreak@155
|
735 ]])
|
flickerstreak@155
|
736 end
|
flickerstreak@155
|
737
|
flickerstreak@155
|
738 function Bar:UpdateDefaultStateAlpha()
|
flickerstreak@155
|
739 local f = self:GetFrame()
|
flickerstreak@155
|
740 f:SetAttribute("defaultAlpha",self:GetAlpha())
|
flickerstreak@155
|
741 f:Execute([[
|
flickerstreak@155
|
742 defaultAlpha = self:GetAttribute("defaultAlpha")
|
flickerstreak@155
|
743 ]])
|
flickerstreak@155
|
744 end
|
flickerstreak@157
|
745
|
flickerstreak@157
|
746 ---- secure state driver rules ----
|
flickerstreak@157
|
747
|
flickerstreak@157
|
748 local playerClass = select(2, UnitClass("player"))
|
flickerstreak@157
|
749 local function ClassFilter(...)
|
flickerstreak@157
|
750 for i = 1, select('#',...) do
|
flickerstreak@157
|
751 if playerClass == select(i,...) then
|
flickerstreak@157
|
752 return false
|
flickerstreak@157
|
753 end
|
flickerstreak@157
|
754 end
|
flickerstreak@157
|
755 return true
|
flickerstreak@157
|
756 end
|
flickerstreak@157
|
757
|
flickerstreak@157
|
758 local ruleformats = {
|
flickerstreak@157
|
759 stealth = { format = "stealth", filter = ClassFilter("ROGUE","DRUID") },
|
flickerstreak@157
|
760 nostealth = { format = "nostealth", filter = ClassFilter("ROGUE","DRUID") },
|
flickerstreak@157
|
761 shadowdance = { format = "bonusbar:2", filter = ClassFilter("ROGUE") },
|
flickerstreak@157
|
762 shadowform = { format = "form:1", filter = ClassFilter("PRIEST") },
|
flickerstreak@157
|
763 noshadowform = { format = "noform", filter = ClassFilter("PRIEST") },
|
flickerstreak@157
|
764 battle = { format = "stance:1", filter = ClassFilter("WARRIOR") },
|
flickerstreak@157
|
765 defensive = { format = "stance:2", filter = ClassFilter("WARRIOR") },
|
flickerstreak@157
|
766 berserker = { format = "stance:3", filter = ClassFilter("WARRIOR") },
|
flickerstreak@157
|
767 caster = { format = "form:0/2/4/5/6", filter = ClassFilter("DRUID") },
|
flickerstreak@157
|
768 bear = { format = "form:1", filter = ClassFilter("DRUID") },
|
flickerstreak@157
|
769 cat = { format = "form:3", filter = ClassFilter("DRUID") },
|
flickerstreak@157
|
770 tree = { format = "form:5", filter = ClassFilter("DRUID") },
|
flickerstreak@157
|
771 moonkin = { format = "form:5", filter = ClassFilter("DRUID") },
|
flickerstreak@178
|
772 demon = { format = "form:2", filter = ClassFilter("WARLOCK") },
|
flickerstreak@178
|
773 nodemon = { format = "noform", filter = ClassFilter("WARLOCK") },
|
flickerstreak@157
|
774 pet = { format = "pet" },
|
flickerstreak@157
|
775 nopet = { format = "nopet" },
|
flickerstreak@176
|
776 harm = { format = "@target,harm" },
|
flickerstreak@176
|
777 help = { format = "@target,help" },
|
flickerstreak@176
|
778 notarget = { format = "@target,noexists" },
|
flickerstreak@176
|
779 focusharm = { format = "@focus,harm" },
|
flickerstreak@176
|
780 focushelp = { format = "@focus,help" },
|
flickerstreak@176
|
781 nofocus = { format = "@focus,noexists" },
|
flickerstreak@157
|
782 raid = { format = "group:raid" },
|
flickerstreak@157
|
783 party = { format = "group:party" },
|
flickerstreak@157
|
784 solo = { format = "nogroup" },
|
flickerstreak@157
|
785 combat = { format = "combat" },
|
flickerstreak@157
|
786 nocombat = { format = "nocombat" },
|
flickerstreak@176
|
787 possess = { format = "@vehicle,noexists,bonusbar:5" },
|
flickerstreak@176
|
788 vehicle = { format = "@vehicle,exists,bonusbar:5" },
|
flickerstreak@157
|
789 }
|
flickerstreak@157
|
790
|
flickerstreak@157
|
791 function Bar.InitRuleFormats()
|
flickerstreak@157
|
792 local forms = { }
|
flickerstreak@157
|
793 for i = 1, GetNumShapeshiftForms() do
|
flickerstreak@157
|
794 local _, name = GetShapeshiftFormInfo(i)
|
flickerstreak@157
|
795 forms[name] = i;
|
flickerstreak@157
|
796 end
|
flickerstreak@157
|
797 -- use 9 if not found since 9 is never a valid stance/form
|
flickerstreak@157
|
798 local defensive = forms[GetSpellInfo(71)] or 9
|
flickerstreak@157
|
799 local berserker = forms[GetSpellInfo(2458)] or 9
|
flickerstreak@176
|
800 local bear = forms[GetSpellInfo(5487)] or 9
|
flickerstreak@157
|
801 local aquatic = forms[GetSpellInfo(1066)] or 9
|
flickerstreak@157
|
802 local cat = forms[GetSpellInfo(768)] or 9
|
flickerstreak@157
|
803 local travel = forms[GetSpellInfo(783)] or 9
|
flickerstreak@157
|
804 local tree = forms[GetSpellInfo(33891)] or 9
|
flickerstreak@157
|
805 local moonkin = forms[GetSpellInfo(24858)] or 9
|
flickerstreak@157
|
806 local flight = forms[GetSpellInfo(40120)] or forms[GetSpellInfo(33943)] or 9
|
flickerstreak@157
|
807
|
flickerstreak@157
|
808 ruleformats.defensive.format = "stance:"..defensive
|
flickerstreak@157
|
809 ruleformats.berserker.format = "stance:"..berserker
|
flickerstreak@157
|
810 ruleformats.caster.format = format("form:0/%d/%d/%d", aquatic, travel, flight)
|
flickerstreak@157
|
811 ruleformats.bear.format = "form:"..bear
|
flickerstreak@157
|
812 ruleformats.cat.format = "form:"..cat
|
flickerstreak@157
|
813 ruleformats.tree.format = "form:"..tree
|
flickerstreak@157
|
814 ruleformats.moonkin.format = "form:"..moonkin
|
flickerstreak@157
|
815 end
|
flickerstreak@157
|
816
|
flickerstreak@157
|
817 function Bar:BuildStateRule(states)
|
flickerstreak@157
|
818 -- states is a table :
|
flickerstreak@157
|
819 -- states[statename].rule = {
|
flickerstreak@157
|
820 -- order = #,
|
flickerstreak@157
|
821 -- type = "default"/"custom"/"any"/"all",
|
flickerstreak@157
|
822 -- values = { ... }, -- keys of ruleformats[]
|
flickerstreak@157
|
823 -- custom = "...",
|
flickerstreak@157
|
824 -- }
|
flickerstreak@157
|
825 local rules = { }
|
flickerstreak@157
|
826 local default
|
flickerstreak@157
|
827
|
flickerstreak@157
|
828 for idx, state in ipairs(fieldsort(states, "rule", "order")) do
|
flickerstreak@157
|
829 local c = states[state].rule
|
flickerstreak@157
|
830 local type = c.type
|
flickerstreak@157
|
831 if type == "default" then
|
flickerstreak@157
|
832 default = default or state
|
flickerstreak@157
|
833 elseif type == "custom" then
|
flickerstreak@157
|
834 if c.custom then
|
flickerstreak@157
|
835 -- strip out all spaces from the custom rule
|
flickerstreak@157
|
836 table.insert(rules, format("%s %s", c.custom:gsub("%s",""), state))
|
flickerstreak@157
|
837 end
|
flickerstreak@157
|
838 elseif type == "any" or type == "all" then
|
flickerstreak@157
|
839 if c.values then
|
flickerstreak@157
|
840 local clauses = { }
|
flickerstreak@157
|
841 for key, value in pairs(c.values) do
|
flickerstreak@157
|
842 if ruleformats[key] and not ruleformats[key].filter then
|
flickerstreak@157
|
843 table.insert(clauses, ruleformats[key].format)
|
flickerstreak@157
|
844 end
|
flickerstreak@157
|
845 end
|
flickerstreak@157
|
846 if #clauses > 0 then
|
flickerstreak@157
|
847 local sep = (type == "any") and "][" or ","
|
flickerstreak@157
|
848 table.insert(rules, format("[%s] %s", table.concat(clauses,sep), state))
|
flickerstreak@157
|
849 end
|
flickerstreak@157
|
850 end
|
flickerstreak@157
|
851 end
|
flickerstreak@157
|
852 end
|
flickerstreak@157
|
853 -- make sure that the default, if any, is last
|
flickerstreak@157
|
854 if default then
|
flickerstreak@157
|
855 table.insert(rules, default)
|
flickerstreak@157
|
856 end
|
flickerstreak@157
|
857 return table.concat(rules,";")
|
flickerstreak@157
|
858 end
|
flickerstreak@157
|
859
|
flickerstreak@157
|
860 function Bar:BuildStateKeybinds( states )
|
flickerstreak@157
|
861 if states then
|
flickerstreak@157
|
862 for name, state in pairs(states) do
|
flickerstreak@157
|
863 local rule = tfetch(state, "rule")
|
flickerstreak@157
|
864 if rule and rule.type == "keybind" then
|
flickerstreak@157
|
865 self:SetStateKeybind(rule.keybind, name)
|
flickerstreak@157
|
866 else
|
flickerstreak@157
|
867 self:SetStateKeybind(nil, name) -- this clears an existing keybind
|
flickerstreak@157
|
868 end
|
flickerstreak@157
|
869 end
|
flickerstreak@157
|
870 end
|
flickerstreak@157
|
871 end
|
flickerstreak@157
|
872
|