flickerstreak@63
|
1 --[[
|
flickerstreak@63
|
2 ReAction.lua
|
flickerstreak@63
|
3
|
flickerstreak@63
|
4 The ReAction core manages 4 collections:
|
flickerstreak@63
|
5 - modules (via AceAddon)
|
flickerstreak@63
|
6 - bars
|
flickerstreak@63
|
7 - options
|
flickerstreak@63
|
8 - bar-type constructors
|
flickerstreak@63
|
9
|
flickerstreak@90
|
10 and publishes events when those collections change. It also implements a couple properties
|
flickerstreak@63
|
11 and has a couple convenience methods which drill down to particular modules.
|
flickerstreak@63
|
12
|
flickerstreak@90
|
13 Most of the "real work" of the addon happens in Bar.lua, Overlay.lua, State.lua, and the various modules.
|
flickerstreak@63
|
14
|
flickerstreak@63
|
15 Events (with handler arguments):
|
flickerstreak@63
|
16 --------------------------------
|
flickerstreak@63
|
17 "OnCreateBar" (bar, name) : after a bar object is created
|
flickerstreak@63
|
18 "OnDestroyBar" (bar, name) : before a bar object is destroyed
|
flickerstreak@63
|
19 "OnEraseBar" (bar, name) : before a bar config is removed from the profile db
|
flickerstreak@63
|
20 "OnRenameBar" (bar, oldname, newname) : after a bar is renamed
|
flickerstreak@63
|
21 "OnRefreshBar" (bar, name) : after a bar's state has been updated
|
flickerstreak@63
|
22 "OnOptionsRefreshed" () : after the global options tree is refreshed
|
flickerstreak@63
|
23 "OnConfigModeChanged" (mode) : after the config mode is changed
|
flickerstreak@63
|
24 "OnBarOptionGeneratorRegistered" (module, function) : after an options generator function is registered
|
flickerstreak@63
|
25
|
flickerstreak@63
|
26 ReAction is also an AceAddon-3.0 and contains an AceDB-3.0, which in turn publish more events.
|
flickerstreak@63
|
27 ]]--
|
flickerstreak@63
|
28 local version = GetAddOnMetadata("ReAction","Version")
|
flickerstreak@27
|
29
|
flickerstreak@27
|
30 ------ CORE ------
|
flickerstreak@30
|
31 local ReAction = LibStub("AceAddon-3.0"):NewAddon( "ReAction",
|
flickerstreak@33
|
32 "AceConsole-3.0",
|
flickerstreak@33
|
33 "AceEvent-3.0"
|
flickerstreak@30
|
34 )
|
flickerstreak@27
|
35
|
flickerstreak@28
|
36 ------ GLOBALS ------
|
flickerstreak@28
|
37 _G["ReAction"] = ReAction
|
flickerstreak@27
|
38
|
flickerstreak@28
|
39 ------ DEBUGGING ------
|
flickerstreak@25
|
40 ReAction.debug = true
|
flickerstreak@36
|
41 local dbprint
|
flickerstreak@25
|
42 if ReAction.debug then
|
flickerstreak@36
|
43 dbprint = function(msg)
|
flickerstreak@25
|
44 DEFAULT_CHAT_FRAME:AddMessage(msg)
|
flickerstreak@25
|
45 end
|
flickerstreak@25
|
46 else
|
flickerstreak@36
|
47 dbprint = function() end
|
flickerstreak@25
|
48 end
|
flickerstreak@36
|
49 ReAction.dbprint = dbprint
|
flickerstreak@25
|
50
|
flickerstreak@33
|
51 ------ LIBRARIES ------
|
flickerstreak@63
|
52 local callbacks = LibStub("CallbackHandler-1.0"):New(ReAction)
|
flickerstreak@88
|
53 local KB = LibStub("LibKeyBound-1.0")
|
flickerstreak@33
|
54 local L = LibStub("AceLocale-3.0"):GetLocale("ReAction")
|
flickerstreak@33
|
55 ReAction.L = L
|
flickerstreak@33
|
56
|
flickerstreak@28
|
57 ------ PRIVATE ------
|
flickerstreak@88
|
58 local weak = {__mode="k"}
|
flickerstreak@116
|
59 local private = { }
|
flickerstreak@63
|
60 local bars = {}
|
flickerstreak@63
|
61 local defaultBarConfig = {}
|
flickerstreak@63
|
62 local barOptionGenerators = { }
|
flickerstreak@63
|
63 local options = {
|
flickerstreak@63
|
64 type = "group",
|
flickerstreak@63
|
65 name = "ReAction",
|
flickerstreak@63
|
66 childGroups = "tab",
|
flickerstreak@63
|
67 args = {
|
flickerstreak@63
|
68 _desc = {
|
flickerstreak@63
|
69 type = "description",
|
flickerstreak@63
|
70 name = L["Customizable replacement for Blizzard's Action Bars"],
|
flickerstreak@63
|
71 order = 1,
|
flickerstreak@63
|
72 },
|
flickerstreak@63
|
73 global = {
|
flickerstreak@63
|
74 type = "group",
|
flickerstreak@63
|
75 name = L["Global Settings"],
|
flickerstreak@63
|
76 desc = L["Global configuration settings"],
|
flickerstreak@63
|
77 args = {
|
flickerstreak@63
|
78 unlock = {
|
flickerstreak@63
|
79 type = "toggle",
|
flickerstreak@63
|
80 name = L["Unlock Bars"],
|
flickerstreak@63
|
81 desc = L["Unlock bars for dragging and resizing with the mouse"],
|
flickerstreak@63
|
82 handler = ReAction,
|
flickerstreak@63
|
83 get = "GetConfigMode",
|
flickerstreak@63
|
84 set = function(info, value) ReAction:SetConfigMode(value) end,
|
flickerstreak@116
|
85 width = "double",
|
flickerstreak@63
|
86 disabled = InCombatLockdown,
|
flickerstreak@63
|
87 order = 1
|
flickerstreak@63
|
88 },
|
flickerstreak@116
|
89 skipProfileWarning = {
|
flickerstreak@116
|
90 type = "toggle",
|
flickerstreak@116
|
91 name = L["Skip profile keybind warning"],
|
flickerstreak@116
|
92 desc = L["Don't show a warning about updating keybinds when switching profiles"],
|
flickerstreak@116
|
93 get = function() return ReAction.db.global.skipKeybindWarning end,
|
flickerstreak@116
|
94 set = function(info, value) ReAction.db.global.skipKeybindWarning = value end,
|
flickerstreak@116
|
95 width = "double",
|
flickerstreak@116
|
96 order = 2,
|
flickerstreak@116
|
97 },
|
flickerstreak@63
|
98 },
|
flickerstreak@63
|
99 plugins = { },
|
flickerstreak@63
|
100 order = 2,
|
flickerstreak@63
|
101 },
|
flickerstreak@63
|
102 module = {
|
flickerstreak@63
|
103 type = "group",
|
flickerstreak@63
|
104 childGroups = "select",
|
flickerstreak@63
|
105 name = L["Module Settings"],
|
flickerstreak@63
|
106 desc = L["Configuration settings for each module"],
|
flickerstreak@63
|
107 args = { },
|
flickerstreak@63
|
108 plugins = { },
|
flickerstreak@63
|
109 order = 3,
|
flickerstreak@63
|
110 },
|
flickerstreak@63
|
111 },
|
flickerstreak@63
|
112 plugins = { }
|
flickerstreak@63
|
113 }
|
flickerstreak@63
|
114 ReAction.options = options
|
flickerstreak@63
|
115
|
flickerstreak@116
|
116 -- insert an entry into the WoW static popup dialogs list
|
flickerstreak@116
|
117 StaticPopupDialogs["REACTION_KB_WARN"] = {
|
flickerstreak@116
|
118 text = L["ReAction profile changed: check your keybinds, they may need to be updated."],
|
flickerstreak@116
|
119 button1 = L["OK"],
|
flickerstreak@116
|
120 hideOnEscape = true,
|
flickerstreak@116
|
121 enterClicksFirstButton = true,
|
flickerstreak@116
|
122 timeout = 0,
|
flickerstreak@116
|
123 showAlert = true,
|
flickerstreak@116
|
124 whileDead = true,
|
flickerstreak@116
|
125 }
|
flickerstreak@116
|
126
|
flickerstreak@116
|
127 local SelectBar, DestroyBar, InitializeBars, TearDownBars, DeepCopy, CallModuleMethod, SlashHandler
|
flickerstreak@28
|
128 do
|
flickerstreak@28
|
129 local pcall = pcall
|
flickerstreak@28
|
130 local geterrorhandler = geterrorhandler
|
flickerstreak@63
|
131 local self = ReAction
|
flickerstreak@63
|
132 local inited = false
|
flickerstreak@28
|
133
|
flickerstreak@63
|
134 function SelectBar(x)
|
flickerstreak@28
|
135 local bar, name
|
flickerstreak@28
|
136 if type(x) == "string" then
|
flickerstreak@28
|
137 name = x
|
flickerstreak@63
|
138 bar = self:GetBar(name)
|
flickerstreak@50
|
139 else
|
flickerstreak@63
|
140 for k,v in pairs(bars) do
|
flickerstreak@50
|
141 if v == x then
|
flickerstreak@28
|
142 name = k
|
flickerstreak@50
|
143 bar = x
|
flickerstreak@28
|
144 end
|
flickerstreak@28
|
145 end
|
flickerstreak@28
|
146 end
|
flickerstreak@28
|
147 return bar, name
|
flickerstreak@28
|
148 end
|
flickerstreak@28
|
149
|
flickerstreak@63
|
150 function DestroyBar(x)
|
flickerstreak@28
|
151 local bar, name = SelectBar(x)
|
flickerstreak@63
|
152 if bar and name then
|
flickerstreak@63
|
153 bars[name] = nil
|
flickerstreak@63
|
154 callbacks:Fire("OnDestroyBar", bar, name)
|
flickerstreak@28
|
155 bar:Destroy()
|
flickerstreak@28
|
156 end
|
flickerstreak@28
|
157 end
|
flickerstreak@28
|
158
|
flickerstreak@63
|
159 function InitializeBars()
|
flickerstreak@63
|
160 if not inited then
|
flickerstreak@63
|
161 for name, config in pairs(self.db.profile.bars) do
|
flickerstreak@28
|
162 if config then
|
flickerstreak@63
|
163 self:CreateBar(name, config)
|
flickerstreak@28
|
164 end
|
flickerstreak@28
|
165 end
|
flickerstreak@101
|
166 -- re-anchor and refresh in case anchor order does not match init order
|
flickerstreak@63
|
167 for name, bar in pairs(bars) do
|
flickerstreak@63
|
168 bar:ApplyAnchor()
|
flickerstreak@101
|
169 callbacks:Fire("OnRefreshBar", bar, name)
|
flickerstreak@63
|
170 end
|
flickerstreak@63
|
171 inited = true
|
flickerstreak@28
|
172 end
|
flickerstreak@28
|
173 end
|
flickerstreak@28
|
174
|
flickerstreak@63
|
175 function TearDownBars()
|
flickerstreak@63
|
176 for name, bar in pairs(bars) do
|
flickerstreak@28
|
177 if bar then
|
flickerstreak@63
|
178 bars[name] = DestroyBar(bar)
|
flickerstreak@28
|
179 end
|
flickerstreak@28
|
180 end
|
flickerstreak@63
|
181 inited = false
|
flickerstreak@28
|
182 end
|
flickerstreak@28
|
183
|
flickerstreak@63
|
184 function DeepCopy(x)
|
flickerstreak@28
|
185 if type(x) ~= "table" then
|
flickerstreak@28
|
186 return x
|
flickerstreak@28
|
187 end
|
flickerstreak@28
|
188 local r = {}
|
flickerstreak@28
|
189 for k,v in pairs(x) do
|
flickerstreak@28
|
190 r[k] = DeepCopy(v)
|
flickerstreak@28
|
191 end
|
flickerstreak@28
|
192 return r
|
flickerstreak@28
|
193 end
|
flickerstreak@28
|
194
|
flickerstreak@63
|
195 function CallModuleMethod(modulename, method, ...)
|
flickerstreak@63
|
196 local m = self:GetModule(modulename,true)
|
flickerstreak@63
|
197 if m then
|
flickerstreak@63
|
198 if type(m) == "table" and type(m[method]) == "function" then
|
flickerstreak@63
|
199 m[method](m,...)
|
flickerstreak@63
|
200 else
|
flickerstreak@63
|
201 dbprint(("Bad call '%s' to %s module"):format(tostring(method),modulename));
|
flickerstreak@63
|
202 end
|
flickerstreak@63
|
203 else
|
flickerstreak@63
|
204 self:Print(("Module '%s' not found"):format(tostring(modulename)))
|
flickerstreak@63
|
205 end
|
flickerstreak@28
|
206 end
|
flickerstreak@28
|
207
|
flickerstreak@63
|
208 function SlashHandler(option)
|
flickerstreak@30
|
209 if option == "config" then
|
flickerstreak@63
|
210 self:ShowConfig()
|
flickerstreak@58
|
211 elseif option == "edit" then
|
flickerstreak@63
|
212 self:ShowEditor()
|
flickerstreak@50
|
213 elseif option == "unlock" then
|
flickerstreak@63
|
214 self:SetConfigMode(true)
|
flickerstreak@50
|
215 elseif option == "lock" then
|
flickerstreak@63
|
216 self:SetConfigMode(false)
|
flickerstreak@88
|
217 elseif option == "kb" then
|
flickerstreak@88
|
218 self:SetKeybindMode(true)
|
flickerstreak@30
|
219 else
|
flickerstreak@169
|
220 self:Print(("%3.1f"):format(version))
|
flickerstreak@63
|
221 self:Print("/rxn config")
|
flickerstreak@63
|
222 self:Print("/rxn edit")
|
flickerstreak@63
|
223 self:Print("/rxn lock")
|
flickerstreak@63
|
224 self:Print("/rxn unlock")
|
flickerstreak@88
|
225 self:Print("/rxn kb")
|
flickerstreak@30
|
226 end
|
flickerstreak@30
|
227 end
|
flickerstreak@92
|
228
|
flickerstreak@28
|
229 end
|
flickerstreak@28
|
230
|
flickerstreak@28
|
231
|
flickerstreak@28
|
232 ------ HANDLERS ------
|
flickerstreak@28
|
233 function ReAction:OnInitialize()
|
flickerstreak@28
|
234 self.db = LibStub("AceDB-3.0"):New("ReAction_DB",
|
flickerstreak@28
|
235 {
|
flickerstreak@28
|
236 profile = {
|
flickerstreak@28
|
237 bars = { },
|
flickerstreak@28
|
238 defaultBar = { }
|
flickerstreak@28
|
239 }
|
flickerstreak@111
|
240 },
|
flickerstreak@114
|
241 L["Default"]
|
flickerstreak@28
|
242 )
|
flickerstreak@28
|
243 self.db.RegisterCallback(self,"OnProfileChanged")
|
flickerstreak@95
|
244 self.db.RegisterCallback(self,"OnProfileReset", "OnProfileChanged")
|
flickerstreak@95
|
245 self.db.RegisterCallback(self,"OnProfileCopied","OnProfileChanged")
|
flickerstreak@63
|
246
|
flickerstreak@88
|
247 KB.RegisterCallback(self,"LIBKEYBOUND_ENABLED")
|
flickerstreak@88
|
248 KB.RegisterCallback(self,"LIBKEYBOUND_DISABLED")
|
flickerstreak@88
|
249
|
flickerstreak@63
|
250 options.args.profile = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db)
|
flickerstreak@63
|
251
|
flickerstreak@30
|
252 self:RegisterChatCommand("reaction", SlashHandler)
|
flickerstreak@30
|
253 self:RegisterChatCommand("rxn", SlashHandler)
|
flickerstreak@33
|
254 self:RegisterEvent("PLAYER_REGEN_DISABLED")
|
flickerstreak@28
|
255 end
|
flickerstreak@28
|
256
|
flickerstreak@28
|
257 function ReAction:OnEnable()
|
flickerstreak@28
|
258 InitializeBars()
|
flickerstreak@28
|
259 end
|
flickerstreak@28
|
260
|
flickerstreak@28
|
261 function ReAction:OnDisable()
|
flickerstreak@28
|
262 TearDownBars()
|
flickerstreak@28
|
263 end
|
flickerstreak@28
|
264
|
flickerstreak@28
|
265 function ReAction:OnProfileChanged()
|
flickerstreak@33
|
266 TearDownBars()
|
flickerstreak@33
|
267 InitializeBars()
|
flickerstreak@116
|
268 self:PopKeybindWarning()
|
flickerstreak@28
|
269 end
|
flickerstreak@28
|
270
|
flickerstreak@33
|
271 function ReAction:PLAYER_REGEN_DISABLED()
|
flickerstreak@63
|
272 if private.configMode == true then
|
flickerstreak@63
|
273 self:UserError(L["ReAction config mode disabled during combat."])
|
flickerstreak@33
|
274 self:SetConfigMode(false)
|
flickerstreak@88
|
275 self:SetKeybindMode(false)
|
flickerstreak@33
|
276 end
|
flickerstreak@33
|
277 end
|
flickerstreak@33
|
278
|
flickerstreak@88
|
279 function ReAction:LIBKEYBOUND_ENABLED( evt )
|
flickerstreak@88
|
280 self:SetKeybindMode(true)
|
flickerstreak@88
|
281 end
|
flickerstreak@88
|
282
|
flickerstreak@88
|
283 function ReAction:LIBKEYBOUND_DISABLED( evt )
|
flickerstreak@88
|
284 return self:SetKeybindMode(false)
|
flickerstreak@88
|
285 end
|
flickerstreak@88
|
286
|
flickerstreak@33
|
287
|
flickerstreak@28
|
288
|
flickerstreak@28
|
289 ------ API ------
|
flickerstreak@77
|
290
|
flickerstreak@61
|
291 function ReAction:UserError(msg)
|
flickerstreak@61
|
292 -- any user errors should be flashed to the UIErrorsFrame
|
flickerstreak@61
|
293 UIErrorsFrame:AddMessage(msg)
|
flickerstreak@61
|
294 end
|
flickerstreak@61
|
295
|
flickerstreak@63
|
296 -- usage:
|
flickerstreak@91
|
297 -- (1) ReAction:CreateBar(name, [cfgTable])
|
flickerstreak@63
|
298 -- (2) ReAction:CreateBar(name, "barType", [nRows], [nCols], [btnSize], [btnSpacing])
|
flickerstreak@91
|
299 function ReAction:CreateBar(name, config, ...)
|
flickerstreak@91
|
300 local profile = self.db.profile
|
flickerstreak@91
|
301
|
flickerstreak@127
|
302 if name then
|
flickerstreak@127
|
303 if bars[name] then
|
flickerstreak@127
|
304 self:UserError(format(L["ReAction: name '%s' already in use"],name))
|
flickerstreak@127
|
305 return nil
|
flickerstreak@127
|
306 end
|
flickerstreak@127
|
307 else
|
flickerstreak@91
|
308 local prefix = L["Bar "]
|
flickerstreak@91
|
309 local i = 1
|
flickerstreak@91
|
310 repeat
|
flickerstreak@91
|
311 name = prefix..i
|
flickerstreak@91
|
312 i = i + 1
|
flickerstreak@91
|
313 until bars[name] == nil
|
flickerstreak@91
|
314 end
|
flickerstreak@91
|
315
|
flickerstreak@91
|
316 if type(config) == "string" then
|
flickerstreak@91
|
317 config = defaultBarConfig[config]
|
flickerstreak@48
|
318 if not config then
|
flickerstreak@91
|
319 error(("ReAction:CreateBar() - unknown bar type '%s'"):format(tostring(select(1,...))))
|
flickerstreak@48
|
320 end
|
flickerstreak@48
|
321 config = DeepCopy(config)
|
flickerstreak@91
|
322 config.btnRows = select(1,...) or config.btnRows or 1
|
flickerstreak@91
|
323 config.btnColumns = select(2,...) or config.btnColumns or 12
|
flickerstreak@91
|
324 config.btnWidth = select(3,...) or config.btnWidth or 36
|
flickerstreak@91
|
325 config.btnHeight = select(3,...) or config.btnHeight or 36
|
flickerstreak@91
|
326 config.spacing = select(4,...) or config.spacing or 3
|
flickerstreak@48
|
327 config.width = config.width or config.btnColumns*(config.btnWidth + config.spacing) + 1
|
flickerstreak@48
|
328 config.height = config.height or config.btnRows*(config.btnHeight + config.spacing) + 1
|
flickerstreak@81
|
329 config.anchor = config.anchor or "UIParent"
|
flickerstreak@81
|
330 config.point = config.point or "BOTTOM"
|
flickerstreak@81
|
331 config.relpoint = config.relpoint or "BOTTOM"
|
flickerstreak@48
|
332 config.y = config.y or 200
|
flickerstreak@48
|
333 config.x = config.x or 0
|
flickerstreak@48
|
334 end
|
flickerstreak@91
|
335 config = config or profile.bars[name] or DeepCopy(profile.defaultBar)
|
flickerstreak@91
|
336
|
flickerstreak@91
|
337 profile.bars[name] = config
|
flickerstreak@91
|
338 local bar = self.Bar:New( name, config ) -- ReAction.Bar defined in Bar.lua
|
flickerstreak@63
|
339 bars[name] = bar
|
flickerstreak@63
|
340 callbacks:Fire("OnCreateBar", bar, name)
|
flickerstreak@63
|
341 if private.configMode then
|
flickerstreak@33
|
342 bar:ShowControls(true)
|
flickerstreak@33
|
343 end
|
flickerstreak@33
|
344
|
flickerstreak@28
|
345 return bar
|
flickerstreak@28
|
346 end
|
flickerstreak@28
|
347
|
flickerstreak@28
|
348 function ReAction:EraseBar(x)
|
flickerstreak@28
|
349 local bar, name = SelectBar(x)
|
flickerstreak@63
|
350 if bar and name then
|
flickerstreak@63
|
351 callbacks:Fire("OnEraseBar", bar, name)
|
flickerstreak@28
|
352 DestroyBar(bar)
|
flickerstreak@28
|
353 self.db.profile.bars[name] = nil
|
flickerstreak@28
|
354 end
|
flickerstreak@28
|
355 end
|
flickerstreak@28
|
356
|
flickerstreak@28
|
357 function ReAction:GetBar(name)
|
flickerstreak@63
|
358 return bars[name]
|
flickerstreak@63
|
359 end
|
flickerstreak@63
|
360
|
flickerstreak@90
|
361 -- returns pairs of name, bar
|
flickerstreak@63
|
362 function ReAction:IterateBars()
|
flickerstreak@63
|
363 return pairs(bars)
|
flickerstreak@28
|
364 end
|
flickerstreak@28
|
365
|
flickerstreak@28
|
366 function ReAction:RenameBar(x, newname)
|
flickerstreak@28
|
367 local bar, name = SelectBar(x)
|
flickerstreak@63
|
368 if type(newname) ~= "string" then
|
flickerstreak@63
|
369 error("ReAction:RenameBar() - second argument must be a string")
|
flickerstreak@63
|
370 end
|
flickerstreak@63
|
371 if bar and name and #newname > 0 then
|
flickerstreak@127
|
372 if newname == name then
|
flickerstreak@127
|
373 return
|
flickerstreak@127
|
374 end
|
flickerstreak@63
|
375 if bars[newname] then
|
flickerstreak@127
|
376 self:UserError(format(L["ReAction: name '%s' already in use"],newname))
|
flickerstreak@47
|
377 else
|
flickerstreak@63
|
378 bars[newname], bars[name] = bars[name], nil
|
flickerstreak@47
|
379 bar:SetName(newname or "")
|
flickerstreak@47
|
380 local cfg = self.db.profile.bars
|
flickerstreak@47
|
381 cfg[newname], cfg[name] = cfg[name], nil
|
flickerstreak@63
|
382 callbacks:Fire("OnRenameBar", bar, name, newname)
|
flickerstreak@28
|
383 end
|
flickerstreak@28
|
384 end
|
flickerstreak@28
|
385 end
|
flickerstreak@28
|
386
|
flickerstreak@63
|
387 function ReAction:RefreshBar(x)
|
flickerstreak@63
|
388 local bar, name = SelectBar(x)
|
flickerstreak@63
|
389 if bar and name then
|
flickerstreak@63
|
390 callbacks:Fire("OnRefreshBar", bar, name)
|
flickerstreak@63
|
391 end
|
flickerstreak@63
|
392 end
|
flickerstreak@63
|
393
|
flickerstreak@53
|
394 function ReAction:RegisterBarType( name, config, isDefaultChoice )
|
flickerstreak@63
|
395 defaultBarConfig[name] = config
|
flickerstreak@48
|
396 if isDefaultChoice then
|
flickerstreak@81
|
397 private.defaultBarConfigChoice = name
|
flickerstreak@48
|
398 end
|
flickerstreak@48
|
399 self:RefreshOptions()
|
flickerstreak@48
|
400 end
|
flickerstreak@48
|
401
|
flickerstreak@53
|
402 function ReAction:UnregisterBarType( name )
|
flickerstreak@63
|
403 defaultBarConfig[name] = nil
|
flickerstreak@63
|
404 if private.defaultBarConfigChoice == name then
|
flickerstreak@63
|
405 private.defaultBarConfigChoice = nil
|
flickerstreak@48
|
406 end
|
flickerstreak@48
|
407 self:RefreshOptions()
|
flickerstreak@48
|
408 end
|
flickerstreak@48
|
409
|
flickerstreak@63
|
410 function ReAction:IterateBarTypes()
|
flickerstreak@63
|
411 return pairs(defaultBarConfig)
|
flickerstreak@63
|
412 end
|
flickerstreak@63
|
413
|
flickerstreak@63
|
414 function ReAction:GetBarTypeConfig(name)
|
flickerstreak@63
|
415 if name then
|
flickerstreak@63
|
416 return defaultBarConfig[name]
|
flickerstreak@63
|
417 end
|
flickerstreak@63
|
418 end
|
flickerstreak@63
|
419
|
flickerstreak@63
|
420 function ReAction:GetBarTypeOptions( fill )
|
flickerstreak@63
|
421 fill = fill or { }
|
flickerstreak@63
|
422 for k in self:IterateBarTypes() do
|
flickerstreak@63
|
423 fill[k] = k
|
flickerstreak@63
|
424 end
|
flickerstreak@63
|
425 return fill
|
flickerstreak@63
|
426 end
|
flickerstreak@63
|
427
|
flickerstreak@63
|
428 function ReAction:GetDefaultBarType()
|
flickerstreak@63
|
429 return private.defaultBarConfigChoice
|
flickerstreak@63
|
430 end
|
flickerstreak@63
|
431
|
flickerstreak@63
|
432 function ReAction:RegisterOptions(module, opts, global)
|
flickerstreak@63
|
433 options.args[global and "global" or "module"].plugins[module:GetName()] = opts
|
flickerstreak@63
|
434 self:RefreshOptions()
|
flickerstreak@30
|
435 end
|
flickerstreak@30
|
436
|
flickerstreak@30
|
437 function ReAction:RefreshOptions()
|
flickerstreak@63
|
438 callbacks:Fire("OnOptionsRefreshed")
|
flickerstreak@63
|
439 end
|
flickerstreak@63
|
440
|
flickerstreak@63
|
441 --
|
flickerstreak@63
|
442 -- In addition to global and general module options, options tables
|
flickerstreak@63
|
443 -- must be generated dynamically for each bar.
|
flickerstreak@63
|
444 --
|
flickerstreak@63
|
445 -- 'func' should be a function or a method string.
|
flickerstreak@63
|
446 -- The function or method will be passed the bar as its parameter.
|
flickerstreak@63
|
447 -- (methods will of course get the module as the first 'self' parameter)
|
flickerstreak@63
|
448 --
|
flickerstreak@63
|
449 -- A generator can be unregistered by passing a nil func.
|
flickerstreak@63
|
450 --
|
flickerstreak@63
|
451 function ReAction:RegisterBarOptionGenerator( module, func )
|
flickerstreak@63
|
452 if not module or type(module) ~= "table" then -- doesn't need to be a proper module, strictly
|
flickerstreak@63
|
453 error("ReAction:RegisterBarOptionGenerator() : Invalid module")
|
flickerstreak@63
|
454 end
|
flickerstreak@63
|
455 if type(func) == "string" then
|
flickerstreak@63
|
456 if not module[func] then
|
flickerstreak@63
|
457 error(("ReAction:RegisterBarOptionGenerator() : Invalid method '%s'"):format(func))
|
flickerstreak@63
|
458 end
|
flickerstreak@63
|
459 elseif func and type(func) ~= "function" then
|
flickerstreak@63
|
460 error("ReAction:RegisterBarOptionGenerator() : Invalid function")
|
flickerstreak@63
|
461 end
|
flickerstreak@63
|
462 barOptionGenerators[module] = func
|
flickerstreak@63
|
463 callbacks:Fire("OnBarOptionGeneratorRegistered", module, func)
|
flickerstreak@63
|
464 end
|
flickerstreak@63
|
465
|
flickerstreak@63
|
466 -- builds a table suitable for use as an AceConfig3 group 'plugins' sub-table
|
flickerstreak@63
|
467 function ReAction:GenerateBarOptionsTable( bar )
|
flickerstreak@63
|
468 local opts = { }
|
flickerstreak@63
|
469 for module, func in pairs(barOptionGenerators) do
|
flickerstreak@63
|
470 local success, r
|
flickerstreak@63
|
471 if type(func) == "string" then
|
flickerstreak@63
|
472 success, r = pcall(module[func], module, bar)
|
flickerstreak@63
|
473 else
|
flickerstreak@63
|
474 success, r = pcall(func, bar)
|
flickerstreak@63
|
475 end
|
flickerstreak@63
|
476 if success then
|
flickerstreak@90
|
477 if r then
|
flickerstreak@90
|
478 opts[module:GetName()] = { [module:GetName()] = r }
|
flickerstreak@90
|
479 end
|
flickerstreak@63
|
480 else
|
flickerstreak@63
|
481 geterrorhandler()(r)
|
flickerstreak@63
|
482 end
|
flickerstreak@63
|
483 end
|
flickerstreak@63
|
484 return opts
|
flickerstreak@30
|
485 end
|
flickerstreak@33
|
486
|
flickerstreak@33
|
487 function ReAction:SetConfigMode( mode )
|
flickerstreak@77
|
488 if mode ~= private.configMode then
|
flickerstreak@77
|
489 private.configMode = mode
|
flickerstreak@77
|
490 callbacks:Fire("OnConfigModeChanged", mode)
|
flickerstreak@77
|
491 end
|
flickerstreak@63
|
492 end
|
flickerstreak@63
|
493
|
flickerstreak@63
|
494 function ReAction:GetConfigMode()
|
flickerstreak@63
|
495 return private.configMode
|
flickerstreak@33
|
496 end
|
flickerstreak@38
|
497
|
flickerstreak@38
|
498 function ReAction:ShowConfig()
|
flickerstreak@63
|
499 CallModuleMethod("ConfigUI","OpenConfig")
|
flickerstreak@38
|
500 end
|
flickerstreak@38
|
501
|
flickerstreak@81
|
502 function ReAction:ShowEditor(bar, ...)
|
flickerstreak@81
|
503 CallModuleMethod("ConfigUI","LaunchBarEditor",bar, ...)
|
flickerstreak@47
|
504 end
|
flickerstreak@88
|
505
|
flickerstreak@88
|
506 function ReAction:SetKeybindMode( mode )
|
flickerstreak@88
|
507 if mode ~= private.kbMode then
|
flickerstreak@88
|
508 if mode then
|
flickerstreak@88
|
509 KB:Activate()
|
flickerstreak@88
|
510 else
|
flickerstreak@88
|
511 KB:Deactivate()
|
flickerstreak@88
|
512 end
|
flickerstreak@88
|
513 private.kbMode = KB:IsShown() or false
|
flickerstreak@88
|
514 end
|
flickerstreak@88
|
515 end
|
flickerstreak@88
|
516
|
flickerstreak@88
|
517 function ReAction:GetKeybindMode( mode )
|
flickerstreak@88
|
518 return private.kbMode
|
flickerstreak@88
|
519 end
|
flickerstreak@88
|
520
|
flickerstreak@116
|
521 function ReAction:PopKeybindWarning()
|
flickerstreak@116
|
522 if not self.db.global.skipKeybindWarning then
|
flickerstreak@116
|
523 StaticPopup_Show("REACTION_KB_WARN")
|
flickerstreak@92
|
524 end
|
flickerstreak@88
|
525 end
|
flickerstreak@122
|
526
|
flickerstreak@122
|
527 -- Export ReAction launcher to LibDataBroker-aware displays
|
flickerstreak@122
|
528 LibStub:GetLibrary("LibDataBroker-1.1"):NewDataObject( "ReAction",
|
flickerstreak@122
|
529 {
|
flickerstreak@122
|
530 type = "launcher",
|
flickerstreak@122
|
531 icon = "Interface\\Icons\\INV_Qiraj_JewelEncased",
|
flickerstreak@122
|
532
|
flickerstreak@122
|
533 OnClick = function( frame, button )
|
flickerstreak@122
|
534 if not InCombatLockdown() then
|
flickerstreak@122
|
535 if IsAltKeyDown() then
|
flickerstreak@122
|
536 ReAction:SetKeybindMode( not ReAction:GetKeybindMode() )
|
flickerstreak@122
|
537 elseif IsShiftKeyDown() then
|
flickerstreak@122
|
538 ReAction:SetConfigMode( not ReAction:GetConfigMode() )
|
flickerstreak@122
|
539 elseif button == "RightButton" then
|
flickerstreak@122
|
540 ReAction:ShowEditor()
|
flickerstreak@122
|
541 else
|
flickerstreak@122
|
542 ReAction:ShowConfig()
|
flickerstreak@122
|
543 end
|
flickerstreak@122
|
544 else
|
flickerstreak@122
|
545 ReAction:UserError(L["ReAction: can't configure in combat"])
|
flickerstreak@122
|
546 end
|
flickerstreak@122
|
547 end,
|
flickerstreak@122
|
548
|
flickerstreak@122
|
549 -- this isn't included in the 'launcher' type LDB spec but it seems all launcher displays use it
|
flickerstreak@122
|
550 OnTooltipShow = function( tooltip )
|
flickerstreak@122
|
551 tooltip:AddLine(format("|cffffffff%s|r %s",L["Click"],L["for global configuration"]))
|
flickerstreak@122
|
552 tooltip:AddLine(format("|cffffd200%s|r %s",L["Right-click"],L["for bar editor dialog"]))
|
flickerstreak@122
|
553 tooltip:AddLine(format("|cff00ff00%s|r %s",L["Shift-click"],L["to unlock bars"]))
|
flickerstreak@122
|
554 tooltip:AddLine(format("|cff00cccc%s|r %s",L["Alt-click"],L["for keybind mode"]))
|
flickerstreak@122
|
555 end,
|
flickerstreak@122
|
556
|
flickerstreak@122
|
557 }
|
flickerstreak@122
|
558 )
|