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