Mercurial > wow > reaction
comparison modules/Config.lua @ 109:410d036c43b2
- reorganize modularity file structure (part 1)
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Thu, 08 Jan 2009 00:57:27 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
108:b2fb8f7dc780 | 109:410d036c43b2 |
---|---|
1 --[[ | |
2 ReAction Configuration UI module | |
3 | |
4 Hooks into Blizzard Interface Options AddOns panel | |
5 --]] | |
6 | |
7 -- local imports | |
8 local ReAction = ReAction | |
9 local L = ReAction.L | |
10 local _G = _G | |
11 local AceConfigReg = LibStub("AceConfigRegistry-3.0") | |
12 local AceConfigDialog = LibStub("AceConfigDialog-3.0") | |
13 | |
14 ReAction:UpdateRevision("$Revision$") | |
15 | |
16 -- some constants | |
17 local configName = "ReAction" | |
18 | |
19 -- module declaration | |
20 local moduleID = "ConfigUI" | |
21 local module = ReAction:NewModule( moduleID, | |
22 "AceEvent-3.0" | |
23 ) | |
24 | |
25 -- module methods | |
26 function module:OnInitialize() | |
27 self.db = ReAction.db:RegisterNamespace( moduleID, | |
28 { | |
29 profile = { | |
30 closeOnLaunch = true, | |
31 editorCloseOnLaunch = true, | |
32 } | |
33 } | |
34 ) | |
35 | |
36 self:RegisterEvent("PLAYER_REGEN_DISABLED") | |
37 ReAction.RegisterCallback(self,"OnOptionsRegistered","OnOptionsRefreshed") | |
38 ReAction.RegisterCallback(self,"OnOptionsRefreshed") | |
39 self:InitializeOptions() | |
40 end | |
41 | |
42 function module:OnOptionsRefreshed(evt) | |
43 AceConfigReg:NotifyChange(configName) | |
44 if self.editor then self.editor:Refresh() end | |
45 end | |
46 | |
47 function module:PLAYER_REGEN_DISABLED() | |
48 if self.editor then | |
49 self.editor:Hide() | |
50 end | |
51 end | |
52 | |
53 function module:OpenConfig() | |
54 InterfaceOptionsFrame_OpenToCategory(configName) | |
55 end | |
56 | |
57 function module:InitializeOptions() | |
58 ReAction:RegisterOptions(self, { | |
59 _launchEditor = { | |
60 type = "execute", | |
61 handler = self, | |
62 name = L["Edit Bars..."], | |
63 desc = L["Show the ReAction Bar Editor dialogue"], | |
64 func = function() | |
65 self:LaunchBarEditor() | |
66 -- you can't close a dialog in response to an options click, because the end of the | |
67 -- handler for all the button events calls lib:Open() | |
68 -- So, schedule a close on the next OnUpdate | |
69 if self.db.profile.closeOnLaunch then | |
70 self.editor.closePending = true | |
71 end | |
72 end, | |
73 order = 2, | |
74 }, | |
75 _closeThis = { | |
76 type = "toggle", | |
77 name = L["Close on Launch"], | |
78 desc = L["Close the Interface Options window when launching the ReAction Bar Editor"], | |
79 get = function() return self.db.profile.closeOnLaunch end, | |
80 set = function(info, val) self.db.profile.closeOnLaunch = val end, | |
81 order = 3, | |
82 }, | |
83 _keybind = { | |
84 type = "execute", | |
85 handler = self, | |
86 name = L["Key Bindings"], | |
87 desc = L["Show the keybinding dialogue"], | |
88 func = function() | |
89 ReAction:SetKeybindMode(true) | |
90 end, | |
91 order = 4, | |
92 }, | |
93 }, true) -- global | |
94 | |
95 AceConfigReg:RegisterOptionsTable(configName,ReAction.options) | |
96 self.frame = AceConfigDialog:AddToBlizOptions(configName, configName) | |
97 self.frame.obj:SetCallback("default", | |
98 function() | |
99 ReAction.db:ResetProfile() | |
100 ReAction:RefreshOptions() | |
101 end ) | |
102 end | |
103 | |
104 | |
105 | |
106 | |
107 -- Bar Editor -- | |
108 local function NewEditor() | |
109 -- private variables | |
110 local editorName = "ReAction-Editor" | |
111 local barOptMap = setmetatable({},{__mode="v"}) | |
112 local tmp = { } | |
113 local pointTable = { | |
114 CENTER = L["Center"], | |
115 LEFT = L["Left"], | |
116 RIGHT = L["Right"], | |
117 TOP = L["Top"], | |
118 BOTTOM = L["Bottom"], | |
119 TOPLEFT = L["Top Left"], | |
120 TOPRIGHT = L["Top Right"], | |
121 BOTTOMLEFT = L["Bottom Left"], | |
122 BOTTOMRIGHT = L["Bottom Right"], | |
123 } | |
124 | |
125 | |
126 -- use a local GUI container to work around AceConfigDialog closing | |
127 -- both the bar editor and the global options when interface options is closed | |
128 local editor = LibStub("AceGUI-3.0"):Create("Frame") | |
129 local frame = editor.frame | |
130 frame:SetClampedToScreen(true) | |
131 frame:Hide() | |
132 local old_OnUpdate = frame:GetScript("OnUpdate") | |
133 frame:SetScript("OnUpdate", function(dt) | |
134 if old_OnUpdate then | |
135 old_OnUpdate(dt) | |
136 end | |
137 if editor.closePending then | |
138 InterfaceOptionsFrame:Hide() | |
139 editor.closePending = false | |
140 end | |
141 if editor.selfClosePending then | |
142 editor:Hide() | |
143 AceConfigReg:NotifyChange(configName) | |
144 editor.selfClosePending = false | |
145 end | |
146 end ) | |
147 editor:SetCallback("OnClose", | |
148 function() | |
149 ReAction:SetConfigMode(false) | |
150 end ) | |
151 AceConfigDialog:SetDefaultSize(editorName, 700, 540) | |
152 | |
153 | |
154 local name = ("ReAction - %s"):format(L["Bar Editor"]) | |
155 editor:SetTitle(name) | |
156 local options = { | |
157 type = "group", | |
158 name = name, | |
159 handler = editor, | |
160 childGroups = "tree", | |
161 args = { | |
162 desc = { | |
163 type = "description", | |
164 name = L["Use the mouse to arrange and resize the bars on screen. Tooltips on bars indicate additional functionality."], | |
165 order = 1 | |
166 }, | |
167 launchConfig = { | |
168 type = "execute", | |
169 name = L["Global Config"], | |
170 desc = L["Opens ReAction global configuration settings panel"], | |
171 func = function() | |
172 module:OpenConfig() | |
173 -- you can't close a dialog in response to an options click, because the end of the | |
174 -- handler for all the button events calls lib:Open() | |
175 -- So, schedule a close on the next OnUpdate | |
176 if module.db.profile.editorCloseOnLaunch then | |
177 editor.selfClosePending = true | |
178 end | |
179 end, | |
180 order = 2 | |
181 }, | |
182 closeThis = { | |
183 type = "toggle", | |
184 name = L["Close on Launch"], | |
185 desc = L["Close the Bar Editor when opening the ReAction global Interface Options"], | |
186 get = function() return module.db.profile.editorCloseOnLaunch end, | |
187 set = function(info, val) module.db.profile.editorCloseOnLaunch = val end, | |
188 order = 3, | |
189 }, | |
190 new = { | |
191 type = "group", | |
192 name = L["New Bar..."], | |
193 order = 4, | |
194 args = { | |
195 desc = { | |
196 type = "description", | |
197 name = L["Choose a name, type, and initial grid for your new action bar:"], | |
198 order = 1, | |
199 }, | |
200 name = { | |
201 type = "input", | |
202 name = L["Bar Name"], | |
203 desc = L["Enter a name for your new action bar"], | |
204 get = function() return tmp.barName or "" end, | |
205 set = function(info, val) tmp.barName = val end, | |
206 order = 2, | |
207 }, | |
208 type = { | |
209 type = "select", | |
210 name = L["Button Type"], | |
211 get = function() return tmp.barType or ReAction:GetDefaultBarType() or "" end, | |
212 set = function(info, val) | |
213 local c = ReAction:GetBarTypeConfig(val) | |
214 tmp.barType = val | |
215 tmp.barSize = c.defaultButtonSize or tmp.barSize | |
216 tmp.barRows = c.defaultBarRows or tmp.barRows | |
217 tmp.barCols = c.defaultBarCols or tmp.barCols | |
218 tmp.barSpacing = c.defaultBarSpacing or tmp.barSpacing | |
219 end, | |
220 values = "GetBarTypes", | |
221 order = 3, | |
222 }, | |
223 grid = { | |
224 type = "group", | |
225 name = L["Button Grid"], | |
226 inline = true, | |
227 args = { | |
228 hdr = { | |
229 type = "header", | |
230 name = L["Button Grid"], | |
231 order = 1, | |
232 }, | |
233 rows = { | |
234 type = "range", | |
235 name = L["Rows"], | |
236 get = function() return tmp.barRows or 1 end, | |
237 set = function(info, val) tmp.barRows = val end, | |
238 width = "half", | |
239 min = 1, | |
240 max = 32, | |
241 step = 1, | |
242 order = 2, | |
243 }, | |
244 cols = { | |
245 type = "range", | |
246 name = L["Columns"], | |
247 get = function() return tmp.barCols or 12 end, | |
248 set = function(info, val) tmp.barCols = val end, | |
249 width = "half", | |
250 min = 1, | |
251 max = 32, | |
252 step = 1, | |
253 order = 3, | |
254 }, | |
255 sz = { | |
256 type = "range", | |
257 name = L["Size"], | |
258 get = function() return tmp.barSize or 36 end, | |
259 set = function(info, val) tmp.barSize = val end, | |
260 width = "half", | |
261 min = 10, | |
262 max = 72, | |
263 step = 1, | |
264 order = 4, | |
265 }, | |
266 spacing = { | |
267 type = "range", | |
268 name = L["Spacing"], | |
269 get = function() return tmp.barSpacing or 3 end, | |
270 set = function(info, val) tmp.barSpacing = val end, | |
271 width = "half", | |
272 min = 0, | |
273 max = 24, | |
274 step = 1, | |
275 order = 5, | |
276 } | |
277 }, | |
278 order = 4 | |
279 }, | |
280 spacer = { | |
281 type = "header", | |
282 name = "", | |
283 width = "full", | |
284 order = -2 | |
285 }, | |
286 go = { | |
287 type = "execute", | |
288 name = L["Create Bar"], | |
289 func = "CreateBar", | |
290 order = -1, | |
291 } | |
292 } | |
293 } | |
294 } | |
295 } | |
296 AceConfigReg:RegisterOptionsTable(editorName, options) | |
297 | |
298 function editor:Open(bar, ...) | |
299 if not frame:IsVisible() then | |
300 AceConfigDialog:Open(editorName,self) | |
301 end | |
302 if bar then | |
303 AceConfigDialog:SelectGroup(editorName, barOptMap[bar:GetName()], ...) | |
304 end | |
305 end | |
306 | |
307 function editor:Refresh() | |
308 AceConfigReg:NotifyChange(editorName) | |
309 end | |
310 | |
311 function editor:CreateBarTree(bar) | |
312 local name = bar:GetName() | |
313 -- AceConfig doesn't allow spaces, etc, in arg key names, and they must be | |
314 -- unique strings. So generate a unique key (it can be whatever) for the bar | |
315 local args = options.args | |
316 local key | |
317 local i = 1 | |
318 repeat | |
319 key = ("bar%s"):format(i) | |
320 i = i+1 | |
321 until args[key] == nil | |
322 barOptMap[name] = key | |
323 args[key] = { | |
324 type = "group", | |
325 name = name, | |
326 childGroups = "tab", | |
327 args = { | |
328 general = { | |
329 type = "group", | |
330 name = L["General"], | |
331 order = 1, | |
332 args = { | |
333 name = { | |
334 type = "input", | |
335 name = L["Rename Bar"], | |
336 get = function() return bar:GetName() end, | |
337 set = function(info, value) return ReAction:RenameBar(bar, value) end, | |
338 order = 1, | |
339 }, | |
340 delete = { | |
341 type = "execute", | |
342 name = L["Delete Bar"], | |
343 desc = function() return bar:GetName() end, | |
344 confirm = true, | |
345 func = function() ReAction:EraseBar(bar) end, | |
346 order = 2 | |
347 }, | |
348 anchor = { | |
349 type = "group", | |
350 name = L["Anchor"], | |
351 inline = true, | |
352 args = { | |
353 frame = { | |
354 type = "input", | |
355 name = L["Frame"], | |
356 desc = L["The frame that the bar is anchored to"], | |
357 get = function() local _, f = bar:GetAnchor(); return f end, | |
358 set = function(info, val) bar:SetAnchor(nil,val) end, | |
359 validate = function(info, name) | |
360 if name then | |
361 local f = ReAction:GetBar(name) | |
362 if f then | |
363 return true | |
364 else | |
365 f = _G[name] | |
366 if f and type(f) == "table" and f.IsObjectType and f:IsObjectType("Frame") then | |
367 local _, explicit = f:IsProtected() | |
368 return explicit | |
369 end | |
370 end | |
371 end | |
372 return false | |
373 end, | |
374 width = "double", | |
375 order = 1 | |
376 }, | |
377 point = { | |
378 type = "select", | |
379 name = L["Point"], | |
380 desc = L["Anchor point on the bar frame"], | |
381 style = "dropdown", | |
382 get = function() return bar:GetAnchor() end, | |
383 set = function(info, val) bar:SetAnchor(val) end, | |
384 values = pointTable, | |
385 order = 2, | |
386 }, | |
387 relativePoint = { | |
388 type = "select", | |
389 name = L["Relative Point"], | |
390 desc = L["Anchor point on the target frame"], | |
391 style = "dropdown", | |
392 get = function() local p,f,r = bar:GetAnchor(); return r end, | |
393 set = function(info, val) bar:SetAnchor(nil,nil,val) end, | |
394 values = pointTable, | |
395 order = 3, | |
396 }, | |
397 x = { | |
398 type = "input", | |
399 pattern = "\-?%d+", | |
400 name = L["X offset"], | |
401 get = function() local p,f,r,x = bar:GetAnchor(); return ("%d"):format(x) end, | |
402 set = function(info,val) bar:SetAnchor(nil,nil,nil,val) end, | |
403 order = 4 | |
404 }, | |
405 y = { | |
406 type = "input", | |
407 pattern = "\-?%d+", | |
408 name = L["Y offset"], | |
409 get = function() local p,f,r,x,y = bar:GetAnchor(); return ("%d"):format(y) end, | |
410 set = function(info,val) bar:SetAnchor(nil,nil,nil,nil,val) end, | |
411 order = 5 | |
412 }, | |
413 }, | |
414 order = 3 | |
415 }, | |
416 alpha = { | |
417 type = "range", | |
418 name = L["Transparency"], | |
419 get = function() return bar:GetAlpha() end, | |
420 set = function(info, val) bar:SetAlpha(val) end, | |
421 min = 0, | |
422 max = 1, | |
423 isPercent = true, | |
424 step = 0.01, | |
425 bigStep = 0.05, | |
426 order = 4, | |
427 }, | |
428 }, | |
429 }, | |
430 } | |
431 } | |
432 self:RefreshBarTree(bar) | |
433 end | |
434 | |
435 function editor:RefreshBarTree(bar) | |
436 local key = barOptMap[bar:GetName()] | |
437 if key and options.args[key] then | |
438 options.args[key].plugins = ReAction:GenerateBarOptionsTable(bar) | |
439 AceConfigReg:NotifyChange(editorName) | |
440 end | |
441 end | |
442 | |
443 function editor:OnCreateBar(evt, bar) | |
444 if not tmp.creating then | |
445 -- a bit of hack to work around OnCreateBar event handler ordering | |
446 self:CreateBarTree(bar) | |
447 end | |
448 end | |
449 | |
450 function editor:OnDestroyBar(evt, bar, name) | |
451 local key = barOptMap[name] | |
452 if key then | |
453 options.args[key] = nil | |
454 end | |
455 self:Refresh() | |
456 end | |
457 | |
458 function editor:OnEraseBar(evt, name) | |
459 local key = barOptMap[name] | |
460 barOptMap[name] = nil | |
461 if key then | |
462 options.args[key] = nil | |
463 self:Refresh() | |
464 end | |
465 end | |
466 | |
467 function editor:OnRenameBar(evt, bar, oldname, newname) | |
468 local key = barOptMap[oldname] | |
469 barOptMap[oldname], barOptMap[newname] = nil, key | |
470 if key then | |
471 options.args[key].name = newname | |
472 self:Refresh() | |
473 end | |
474 end | |
475 | |
476 function editor:OnBarOptionGeneratorRegistered(evt) | |
477 for name in pairs(barOptMap) do | |
478 local bar = ReAction:GetBar(name) | |
479 if bar then | |
480 self:RefreshBarTree(bar) | |
481 end | |
482 end | |
483 end | |
484 | |
485 local _scratch = { } | |
486 function editor:GetBarTypes() | |
487 for k,v in pairs(_scratch) do | |
488 _scratch[k] = nil | |
489 end | |
490 return ReAction:GetBarTypeOptions(_scratch) | |
491 end | |
492 | |
493 function editor:CreateBar() | |
494 if tmp.barName and tmp.barName ~= "" then | |
495 tmp.creating = true | |
496 local bar = ReAction:CreateBar(tmp.barName, tmp.barType or ReAction:GetDefaultBarType(), tmp.barRows, tmp.barCols, tmp.barSize, tmp.barSpacing) | |
497 self:CreateBarTree(bar) | |
498 AceConfigDialog:SelectGroup(editorName, barOptMap[tmp.barName]) | |
499 tmp.barName = nil | |
500 tmp.creating = false | |
501 end | |
502 end | |
503 | |
504 ReAction.RegisterCallback(editor,"OnCreateBar") | |
505 ReAction.RegisterCallback(editor,"OnDestroyBar") | |
506 ReAction.RegisterCallback(editor,"OnEraseBar") | |
507 ReAction.RegisterCallback(editor,"OnRenameBar") | |
508 ReAction.RegisterCallback(editor,"OnBarOptionGeneratorRegistered") | |
509 | |
510 for name, bar in ReAction:IterateBars() do | |
511 editor:CreateBarTree(bar) | |
512 end | |
513 | |
514 return editor | |
515 end | |
516 | |
517 | |
518 function module:LaunchBarEditor(bar, ...) | |
519 if InCombatLockdown() then | |
520 ReAction:UserError(L["ReAction config mode disabled during combat."]) | |
521 else | |
522 if not self.editor then | |
523 self.editor = NewEditor() | |
524 end | |
525 self.editor:Open(bar, ...) | |
526 ReAction:SetConfigMode(true) | |
527 end | |
528 end | |
529 |