Mercurial > wow > reaction
comparison modules/ReAction_ConfigUI/ReAction_ConfigUI.lua @ 25:bf997ea151ca
yet another attempt to add missing files
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Fri, 07 Mar 2008 22:19:03 +0000 |
parents | |
children | 21bcaf8215ff |
comparison
equal
deleted
inserted
replaced
24:9e1984088124 | 25:bf997ea151ca |
---|---|
1 --[[ | |
2 ReAction Configuration UI module | |
3 | |
4 This modules creates and manages ReAction configuration | |
5 elements, including: | |
6 | |
7 - waterfall config menu system | |
8 - bar dragging and resizing control overlays | |
9 - contextual menus | |
10 | |
11 Individual modules are responsible for populating these | |
12 configuration elements via the following functions: | |
13 | |
14 module:GetGlobalOptions( configModule ) | |
15 module:GetGlobalBarOptions( configModule ) | |
16 module:GetModuleOptions( configModule ) | |
17 module:GetBarConfigOptions( bar, configModule ) | |
18 module:GetBarMenuOptions( bar, configModule ) | |
19 | |
20 the ReAction_ConfigUI module is passed in as a parameter so that | |
21 option handlers can refresh the config UI. | |
22 | |
23 --]] | |
24 | |
25 -- local imports | |
26 local ReAction = ReAction | |
27 local L = ReAction.L | |
28 local _G = _G | |
29 local Waterfall = AceLibrary("Waterfall-1.0") | |
30 local Dewdrop = AceLibrary("Dewdrop-2.0") | |
31 local print = ReAction.print | |
32 local InCombatLockdown = InCombatLockdown | |
33 local BarModule = ReAction:GetModule("Bar") | |
34 | |
35 -- module declaration | |
36 local moduleID = "ConfigUI" | |
37 local module = ReAction:NewModule( moduleID, | |
38 "AceConsole-2.0", -- temp | |
39 "AceEvent-2.0" | |
40 -- mixins go here | |
41 ) | |
42 | |
43 module.globalOptions = { | |
44 type = "group", | |
45 args = { | |
46 unlock = { | |
47 type = "toggle", | |
48 handler = module, | |
49 name = L["unlock"], | |
50 guiName = L["Unlock Bars"], | |
51 desc = L["Unlock bars for dragging and resizing with the mouse"], | |
52 get = function() return module.configMode end, | |
53 set = "SetConfigMode", | |
54 disabled = InCombatLockdown, | |
55 order = 1 | |
56 }, | |
57 config = { | |
58 type = "execute", | |
59 handler = module, | |
60 name = L["config"], | |
61 guiName = L["Configure..."], | |
62 desc = L["Open the configuration dialogue"], | |
63 func = "OpenConfig", | |
64 disabled = InCombatLockdown, | |
65 wfHidden = true, -- don't show this in the waterfall config | |
66 order = 2 | |
67 }, | |
68 } | |
69 } | |
70 | |
71 module.configOptions = { | |
72 type = "group", | |
73 args = { | |
74 global = { | |
75 type = "group", | |
76 name = L["Global Settings"], | |
77 desc = L["Global configuration settings"], | |
78 args = { }, | |
79 order = 1, | |
80 }, | |
81 module = { | |
82 type = "group", | |
83 name = L["Module Settings"], | |
84 desc = L["Configuration settings for each module"], | |
85 args = { }, | |
86 order = 2, | |
87 }, | |
88 bar = { | |
89 type = "group", | |
90 name = L["Bars"], | |
91 desc = L["Configuration settings for bars"], | |
92 args = { }, | |
93 order = 3, | |
94 }, | |
95 } | |
96 } | |
97 | |
98 -- module methods | |
99 function module:OnInitialize() | |
100 self.db = ReAction:AcquireDBNamespace(moduleID) | |
101 ReAction:RegisterDefaults(moduleID,"profile", | |
102 { | |
103 | |
104 } | |
105 ) | |
106 | |
107 -- temp: this will be moved to main ReAction.lua later in a more efficient AceConsole-less implementation | |
108 -- that can load the ConfigUI module on demand | |
109 -- NOTE: this inserts an 'about' command that we don't want | |
110 self:RegisterChatCommand( {L["/reaction"], L["/rxn"]}, self.globalOptions, "REACTION" ) | |
111 end | |
112 | |
113 function module:OnEnable() | |
114 self:RegisterEvent("PLAYER_REGEN_DISABLED") | |
115 Waterfall:Register("ReAction", | |
116 "aceOptions", self.configOptions, | |
117 "treeLevels", nil, -- infinite | |
118 "colorR", 0.8, | |
119 "colorG", 0.65, | |
120 "colorB", 0, | |
121 "defaultPane", "global" ) | |
122 end | |
123 | |
124 function module:OnDisable() | |
125 self:UnregisterEvent("PLAYER_REGEN_DISABLED") | |
126 self:SetConfigMode(false) | |
127 Waterfall:UnRegister("ReAction") | |
128 end | |
129 | |
130 function module:PLAYER_REGEN_DISABLED() | |
131 if self.configMode == true then | |
132 UIErrorsFrame:AddMessage(L["ReAction config mode disabled during combat."]) | |
133 self:SetConfigMode(false) | |
134 Waterfall:Close("ReAction") | |
135 end | |
136 end | |
137 | |
138 function module:SetConfigMode( mode ) | |
139 BarModule:CallMethodOnAllBars("ShowControls",mode) | |
140 ReAction:CallMethodOnAllModules("ApplyConfigMode",mode,BarModule.bars) | |
141 self.configMode = mode | |
142 end | |
143 | |
144 function module:ApplyConfigMode( mode, bars ) | |
145 if not(mode) then | |
146 -- close open dewdrop menu | |
147 local p = Dewdrop:GetOpenedParent() | |
148 if p then | |
149 for _, bar in pairs(bars) do | |
150 if bar then | |
151 if p == bar.controlFrame then | |
152 Dewdrop:Close() | |
153 end | |
154 end | |
155 end | |
156 end | |
157 end | |
158 end | |
159 | |
160 local function refreshWaterfall() | |
161 module:RefreshConfig() | |
162 end | |
163 | |
164 function module:RefreshOptions() | |
165 local opts = self.configOptions.args | |
166 | |
167 for _, m in ReAction:IterateModulesWithMethod("GetGlobalOptions") do | |
168 local o = m:GetGlobalOptions(self) | |
169 if o then | |
170 for k, v in pairs(o) do | |
171 opts.global.args[k] = v | |
172 end | |
173 end | |
174 end | |
175 | |
176 for _, m in ReAction:IterateModulesWithMethod("GetGlobalBarOptions") do | |
177 local o = m:GetGlobalBarOptions(self) | |
178 if o then | |
179 for k, v in pairs(o) do | |
180 opts.bar.args[k] = v | |
181 end | |
182 end | |
183 end | |
184 | |
185 for _, m in ReAction:IterateModulesWithMethod("GetModuleOptions") do | |
186 local o = m:GetModuleOptions(self) | |
187 if o then | |
188 for k, v in pairs(o) do | |
189 opts.module.args[k] = v | |
190 end | |
191 end | |
192 end | |
193 | |
194 local barOpts = opts.bar.args | |
195 for name, bar in pairs(BarModule.bars) do | |
196 if bar then | |
197 if barOpts[name] == nil then | |
198 barOpts[name] = { | |
199 type = "group", | |
200 name = name, | |
201 desc = name, | |
202 handler = bar, | |
203 args = { } | |
204 } | |
205 end | |
206 if bar.modConfigOpts == nil then | |
207 bar.modConfigOpts = { } | |
208 end | |
209 for _, m in ReAction:IterateModulesWithMethod("GetBarConfigOptions") do | |
210 local o = m:GetBarConfigOptions(bar,self) | |
211 if o then | |
212 for k, v in pairs(o) do | |
213 barOpts[name].args[k] = v | |
214 end | |
215 end | |
216 end | |
217 end | |
218 end | |
219 -- remove obsolete bar tables | |
220 for name, opt in pairs(barOpts) do | |
221 if opt.type == "group" and BarModule.bars[name] == nil then | |
222 barOpts[name] = nil | |
223 end | |
224 end | |
225 end | |
226 | |
227 function module:OpenConfig(bar) | |
228 self:RefreshOptions() | |
229 Dewdrop:Close() | |
230 Waterfall:Open("ReAction",bar and "bar."..bar:GetName()) | |
231 end | |
232 | |
233 function module:RefreshConfig() | |
234 self:RefreshOptions() | |
235 Waterfall:Refresh("ReAction") | |
236 end | |
237 | |
238 function module:ApplyToBar(bar) | |
239 if self.configMode then | |
240 bar:ShowControls(true) | |
241 end | |
242 end | |
243 | |
244 function module:RemoveFromBar(bar) | |
245 if bar.controlFrame then | |
246 bar.controlFrame:SetParent(UIParent) | |
247 bar.controlFrame:ClearAllPoints() | |
248 bar.controlFrame:Hide() | |
249 bar.controlFrame = nil | |
250 end | |
251 end | |
252 | |
253 function module:GetGlobalOptions() | |
254 return self.globalOptions.args | |
255 end | |
256 | |
257 | |
258 | |
259 | |
260 | |
261 -- | |
262 -- Bar config overlay | |
263 -- | |
264 -- import some of these for small OnUpdate performance boost | |
265 local Bar = BarModule.BarClass.prototype | |
266 local GetSize = Bar.GetSize | |
267 local GetButtonSize = Bar.GetButtonSize | |
268 local GetButtonGrid = Bar.GetButtonGrid | |
269 local SetSize = Bar.SetSize | |
270 local SetButtonSize = Bar.SetButtonSize | |
271 local SetButtonGrid = Bar.SetButtonGrid | |
272 local ApplyAnchor = Bar.ApplyAnchor | |
273 local floor = math.floor | |
274 local min = math.min | |
275 local format = string.format | |
276 local GameTooltip = GameTooltip | |
277 | |
278 local function StoreExtents(bar) | |
279 local f = bar.frame | |
280 local point, relativeTo, relativePoint, x, y = f:GetPoint(1) | |
281 relativeTo = relativeTo or f:GetParent() | |
282 local anchorTo | |
283 for name, b in pairs(BarModule.bars) do | |
284 if b then | |
285 if b:GetFrame() == relativeTo then | |
286 anchorTo = name | |
287 break | |
288 end | |
289 end | |
290 end | |
291 anchorTo = anchorTo or relativeTo:GetName() | |
292 local c = bar.config | |
293 c.anchor = point | |
294 c.anchorTo = anchorTo | |
295 c.relativePoint = relativePoint | |
296 c.x = x | |
297 c.y = y | |
298 c.width, c.height = f:GetWidth(), f:GetHeight() | |
299 end | |
300 | |
301 local function RecomputeButtonSize(bar) | |
302 local w, h = GetSize(bar) | |
303 local bw, bh = GetButtonSize(bar) | |
304 local r, c, s = GetButtonGrid(bar) | |
305 | |
306 local scaleW = (floor(w/c) - s) / bw | |
307 local scaleH = (floor(h/r) - s) / bh | |
308 local scale = min(scaleW, scaleH) | |
309 | |
310 SetButtonSize(bar, scale * bw, scale * bh, s) | |
311 end | |
312 | |
313 local function RecomputeButtonSpacing(bar) | |
314 local w, h = GetSize(bar) | |
315 local bw, bh = GetButtonSize(bar) | |
316 local r, c, s = GetButtonGrid(bar) | |
317 | |
318 SetButtonGrid(bar,r,c,min(floor(w/c) - bw, floor(h/r) - bh)) | |
319 end | |
320 | |
321 local function RecomputeGrid(bar) | |
322 local w, h = GetSize(bar) | |
323 local bw, bh = GetButtonSize(bar) | |
324 local r, c, s = GetButtonGrid(bar) | |
325 | |
326 SetButtonGrid(bar, floor(h/(bh+s)), floor(w/(bw+s)), s) | |
327 end | |
328 | |
329 local function ClampToButtons(bar) | |
330 local bw, bh = GetButtonSize(bar) | |
331 local r, c, s = GetButtonGrid(bar) | |
332 SetSize(bar, (bw+s)*c, (bh+s)*r ) | |
333 end | |
334 | |
335 local function HideGameTooltip() | |
336 GameTooltip:Hide() | |
337 end | |
338 | |
339 local function CreateControls(bar) | |
340 local f = bar.frame | |
341 | |
342 f:SetMovable(true) | |
343 f:SetResizable(true) | |
344 f:SetClampedToScreen(true) | |
345 | |
346 -- buttons on the bar should be direct children of the bar frame. | |
347 -- The control elements need to float on top of this, which we could | |
348 -- do with SetFrameLevel() or Raise(), but it's more reliable to do it | |
349 -- via frame nesting, hence good old foo's appearance here. | |
350 local foo = CreateFrame("Frame",nil,f) | |
351 foo:SetAllPoints() | |
352 | |
353 local control = CreateFrame("Button", nil, foo) | |
354 control:EnableMouse(true) | |
355 control:SetToplevel(true) | |
356 control:SetPoint("TOPLEFT", -4, 4) | |
357 control:SetPoint("BOTTOMRIGHT", 4, -4) | |
358 control:SetBackdrop({ | |
359 edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", | |
360 tile = true, | |
361 tileSize = 16, | |
362 edgeSize = 16, | |
363 insets = { left = 0, right = 0, top = 0, bottom = 0 }, | |
364 }) | |
365 | |
366 -- textures | |
367 local bgTex = control:CreateTexture(nil,"BACKGROUND") | |
368 bgTex:SetTexture(0.7,0.7,1.0,0.2) | |
369 bgTex:SetPoint("TOPLEFT",4,-4) | |
370 bgTex:SetPoint("BOTTOMRIGHT",-4,4) | |
371 local hTex = control:CreateTexture(nil,"HIGHLIGHT") | |
372 hTex:SetTexture(0.7,0.7,1.0,0.2) | |
373 hTex:SetPoint("TOPLEFT",4,-4) | |
374 hTex:SetPoint("BOTTOMRIGHT",-4,4) | |
375 hTex:SetBlendMode("ADD") | |
376 | |
377 -- label | |
378 local label = control:CreateFontString(nil,"OVERLAY","GameFontNormalLarge") | |
379 label:SetAllPoints() | |
380 label:SetJustifyH("CENTER") | |
381 label:SetShadowColor(0,0,0,1) | |
382 label:SetShadowOffset(2,-2) | |
383 label:SetTextColor(1,1,1,1) | |
384 label:SetText(bar:GetName()) | |
385 label:Show() | |
386 bar.controlLabelString = label -- so that bar:SetName() can update it | |
387 | |
388 local StopResize = function() | |
389 f:StopMovingOrSizing() | |
390 f.isMoving = false | |
391 f:SetScript("OnUpdate",nil) | |
392 StoreExtents(bar) | |
393 ClampToButtons(bar) | |
394 ApplyAnchor(bar) | |
395 end | |
396 | |
397 -- edge drag handles | |
398 for _, point in pairs({"LEFT","TOP","RIGHT","BOTTOM"}) do | |
399 local edge = CreateFrame("Frame",nil,control) | |
400 edge:EnableMouse(true) | |
401 edge:SetWidth(8) | |
402 edge:SetHeight(8) | |
403 if point == "TOP" or point == "BOTTOM" then | |
404 edge:SetPoint(point.."LEFT") | |
405 edge:SetPoint(point.."RIGHT") | |
406 else | |
407 edge:SetPoint("TOP"..point) | |
408 edge:SetPoint("BOTTOM"..point) | |
409 end | |
410 local tex = edge:CreateTexture(nil,"HIGHLIGHT") | |
411 tex:SetTexture(1.0,0.82,0,0.7) | |
412 tex:SetBlendMode("ADD") | |
413 tex:SetAllPoints() | |
414 edge:RegisterForDrag("LeftButton") | |
415 edge:SetScript("OnMouseDown", | |
416 function() | |
417 local bw, bh = GetButtonSize(bar) | |
418 local r, c, s = GetButtonGrid(bar) | |
419 f:SetMinResize( bw+s+1, bh+s+1 ) | |
420 f:StartSizing(point) | |
421 f:SetScript("OnUpdate", | |
422 function() | |
423 RecomputeGrid(bar) | |
424 bar:RefreshLayout() | |
425 end | |
426 ) | |
427 end | |
428 ) | |
429 edge:SetScript("OnMouseUp", StopResize) | |
430 edge:SetScript("OnEnter", | |
431 function() | |
432 GameTooltip:SetOwner(f, "ANCHOR_"..point) | |
433 GameTooltip:AddLine(L["Drag to add/remove buttons"]) | |
434 GameTooltip:Show() | |
435 end | |
436 ) | |
437 edge:SetScript("OnLeave", HideGameTooltip) | |
438 edge:Show() | |
439 end | |
440 | |
441 -- corner drag handles, again nested in an anonymous frame so that they are on top | |
442 local foo2 = CreateFrame("Frame",nil,control) | |
443 foo2:SetAllPoints(true) | |
444 for _, point in pairs({"BOTTOMLEFT","TOPLEFT","BOTTOMRIGHT","TOPRIGHT"}) do | |
445 local corner = CreateFrame("Frame",nil,foo2) | |
446 corner:EnableMouse(true) | |
447 corner:SetWidth(12) | |
448 corner:SetHeight(12) | |
449 corner:SetPoint(point) | |
450 local tex = corner:CreateTexture(nil,"HIGHLIGHT") | |
451 tex:SetTexture(1.0,0.82,0,0.7) | |
452 tex:SetBlendMode("ADD") | |
453 tex:SetAllPoints() | |
454 corner:RegisterForDrag("LeftButton","RightButton") | |
455 local updateTooltip = function() | |
456 local size, size2 = bar:GetButtonSize() | |
457 local rows, cols, spacing = bar:GetButtonGrid() | |
458 size = (size == size2) and tostring(size) or format("%dx%d",size,size2) | |
459 GameTooltipTextRight4:SetText(size) | |
460 GameTooltipTextRight5:SetText(tostring(spacing)) | |
461 end | |
462 corner:SetScript("OnMouseDown", | |
463 function(_,btn) | |
464 local bw, bh = GetButtonSize(bar) | |
465 local r, c, s = GetButtonGrid(bar) | |
466 if btn == "LeftButton" then -- button resize | |
467 f:SetMinResize( (s+12)*c+1, (s+12)*r+1 ) | |
468 f:SetScript("OnUpdate", | |
469 function() | |
470 RecomputeButtonSize(bar) | |
471 bar:RefreshLayout() | |
472 updateTooltip() | |
473 end | |
474 ) | |
475 elseif btn == "RightButton" then -- spacing resize | |
476 f:SetMinResize( bw*c, bh*r ) | |
477 f:SetScript("OnUpdate", | |
478 function() | |
479 RecomputeButtonSpacing(bar) | |
480 bar:RefreshLayout() | |
481 updateTooltip() | |
482 end | |
483 ) | |
484 end | |
485 f:StartSizing(point) | |
486 end | |
487 ) | |
488 corner:SetScript("OnMouseUp",StopResize) | |
489 corner:SetScript("OnEnter", | |
490 function() | |
491 GameTooltip:SetOwner(f, "ANCHOR_"..point) | |
492 GameTooltip:AddLine(L["Drag to resize buttons"]) | |
493 GameTooltip:AddLine(L["Right-click-drag"]) | |
494 GameTooltip:AddLine(L["to change spacing"]) | |
495 local size, size2 = bar:GetButtonSize() | |
496 local rows, cols, spacing = bar:GetButtonGrid() | |
497 size = (size == size2) and tostring(size) or format("%dx%d",size,size2) | |
498 GameTooltip:AddDoubleLine(L["Size:"], size) | |
499 GameTooltip:AddDoubleLine(L["Spacing:"], tostring(spacing)) | |
500 GameTooltip:Show() | |
501 end | |
502 ) | |
503 corner:SetScript("OnLeave", | |
504 function() | |
505 GameTooltip:Hide() | |
506 f:SetScript("OnUpdate",nil) | |
507 end | |
508 ) | |
509 | |
510 end | |
511 | |
512 control:RegisterForDrag("LeftButton") | |
513 control:RegisterForClicks("RightButtonDown") | |
514 | |
515 control:SetScript("OnDragStart", | |
516 function() | |
517 f:StartMoving() | |
518 f.isMoving = true | |
519 -- TODO: snap indicator update install | |
520 end | |
521 ) | |
522 | |
523 control:SetScript("OnDragStop", | |
524 function() | |
525 f:StopMovingOrSizing() | |
526 f.isMoving = false | |
527 f:SetScript("OnUpdate",nil) | |
528 -- TODO: snap frame here | |
529 StoreExtents(bar) | |
530 end | |
531 ) | |
532 | |
533 control:SetScript("OnEnter", | |
534 function() | |
535 -- add bar type and status information to name | |
536 local name = bar.name | |
537 for _, m in ReAction:IterateModulesWithMethod("GetBarNameModifier") do | |
538 local suffix = m:GetBarNameModifier(bar) | |
539 if suffix then | |
540 name = format("%s %s",name,suffix) | |
541 end | |
542 end | |
543 | |
544 GameTooltip:SetOwner(f, "ANCHOR_TOPRIGHT") | |
545 GameTooltip:AddLine(name) | |
546 GameTooltip:AddLine(L["Drag to move"]) | |
547 --GameTooltip:AddLine(L["Shift-drag for sticky mode"]) | |
548 GameTooltip:AddLine(L["Right-click for options"]) | |
549 GameTooltip:Show() | |
550 end | |
551 ) | |
552 | |
553 control:SetScript("OnLeave", HideGameTooltip) | |
554 | |
555 control:SetScript("OnClick", | |
556 function() | |
557 bar:ShowMenu() | |
558 end | |
559 ) | |
560 | |
561 return control | |
562 end | |
563 | |
564 function Bar:ShowControls(show) | |
565 if show then | |
566 if not self.controlFrame then | |
567 self.controlFrame = CreateControls(self) | |
568 end | |
569 self.controlFrame:Show() | |
570 elseif self.controlFrame then | |
571 self.controlFrame:Hide() | |
572 end | |
573 end | |
574 | |
575 function Bar:ShowMenu() | |
576 if not self.menuOpts then | |
577 self.menuOpts = { | |
578 type = "group", | |
579 args = { | |
580 openConfig = { | |
581 type = "execute", | |
582 name = L["Configure..."], | |
583 desc = L["Open the configuration dialogue for this bar"], | |
584 func = function() module:OpenConfig(self) end, | |
585 disabled = InCombatLockdown, | |
586 order = 1 | |
587 } | |
588 } | |
589 } | |
590 end | |
591 if self.modMenuOpts == nil then | |
592 self.modMenuOpts = { } | |
593 end | |
594 for _, m in ReAction:IterateModulesWithMethod("GetBarMenuOptions") do | |
595 for k, v in pairs(m:GetBarMenuOptions(self, module)) do | |
596 self.menuOpts.args[k] = v | |
597 end | |
598 end | |
599 Dewdrop:Open(self.controlFrame, "children", self.menuOpts, "cursorX", true, "cursorY", true) | |
600 end | |
601 | |
602 local Bar_SuperSetName = Bar.SetName | |
603 function Bar:SetName(name) | |
604 Bar_SuperSetName(self,name) | |
605 if self.controlLabelString then | |
606 self.controlLabelString:SetText(self.name) | |
607 end | |
608 end |