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