vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 local MAJOR_VERSION = "1.2"
2 local MINOR_VERSION = tonumber(string.sub("$Revision: 1962 $", 12, -3))
3  
4 if FuBarPlugin and FuBarPlugin.versions[MAJOR_VERSION] and FuBarPlugin.versions[MAJOR_VERSION].minor >= MINOR_VERSION and FuBarPlugin.MinimapContainer and FuBarPlugin.MinimapContainer.versions[MAJOR_VERSION] and FuBarPlugin.MinimapContainer.versions[MAJOR_VERSION].minor >= MINOR_VERSION then
5 return
6 end
7  
8 local loc = {
9 ARGUMENT_VISIBLE = "visible",
10 ARGUMENT_COLOR = "color",
11 ARGUMENT_SHOWICON = "showIcon",
12 ARGUMENT_SHOWTEXT = "showText",
13 ARGUMENT_PROFILE = "profile",
14  
15 TEXT_TOGGLE_VISIBILITY = "Toggle Visibility.",
16 TEXT_TOGGLE_WHETHER_TO_SHOW_THE_ICON = "Toggle whether to show the icon.",
17 TEXT_TOGGLE_WHETHER_TO_SHOW_TEXT = "Toggle whether to show text.",
18 TEXT_LIST_PROFILING_INFO = "List profiling information",
19  
20 MENU_SHOW_ICON = "Show icon",
21 MENU_SHOW_TEXT = "Show text",
22 MENU_SHOW_COLORED_TEXT = "Show colored text",
23 MENU_DETACH_TOOLTIP = "Detach tooltip",
24 MENU_LOCK_TOOLTIP = "Lock tooltip",
25 MENU_ON_LEFT_SIDE = "On left side",
26 MENU_IN_CENTER = "In center",
27 MENU_ON_RIGHT_SIDE = "On right side",
28 MENU_HIDE = "Hide",
29 MENU_DISABLE = "Disable",
30 MENU_ABOUT = "About",
31  
32 MAP_ONOFF = {[0]="|cffff0000Off|r",[1]="|cff00ff00On|r"},
33  
34 PATTERN_MERGE_WITH_CHILD = "Merge with %s",
35 PATTERN_SWITCH_TO_CHILD = "Switch to %s",
36 }
37  
38 if GetLocale() == "deDE" then
39 loc.TEXT_TOGGLE_VISIBILITY = "Sichtbarkeit umschalten."
40 loc.TEXT_TOGGLE_WHETHER_TO_SHOW_THE_ICON = "Iconanzeige umschalten."
41 loc.TEXT_TOGGLE_WHETHER_TO_SHOW_TEXT = "Textanzeige umschalten."
42 loc.TEXT_LIST_PROFILING_INFO = "Liste Profilinformationen"
43  
44 loc.MENU_SHOW_ICON = "Zeige Icon"
45 loc.MENU_SHOW_TEXT = "Zeige Text"
46 loc.MENU_SHOW_COLORED_TEXT = "Farbigen Text anzeigen"
47 loc.MENU_DETACH_TOOLTIP = "Tooltip l\195\182sen"
48 loc.MENU_LOCK_TOOLTIP = "Tooltip verankern"
49 loc.MENU_ON_LEFT_SIDE = "Auf linker Seite anzeigen"
50 loc.MENU_IN_CENTER = "In der Mitte anzeigen"
51 loc.MENU_ON_RIGHT_SIDE = "Auf rechter Seite anzeigen"
52 loc.MENU_HIDE = "Ausblenden"
53 loc.MENU_DISABLE = "Deaktivieren"
54 loc.MENU_ABOUT = "\195\156ber"
55  
56 loc.MAP_ONOFF[0] = "|cffff0000Aus|r"
57 loc.MAP_ONOFF[1] = "|cff00ff00An|r"
58  
59 loc.PATTERN_MERGE_WITH_CHILD = "Mit %s verbinden"
60 loc.PATTERN_SWITCH_TO_CHILD = "Zu %s wechseln"
61  
62 elseif GetLocale() == "frFR" then
63 loc.TEXT_TOGGLE_VISIBILITY = "Bascule la visibilite."
64 loc.TEXT_TOGGLE_WHETHER_TO_SHOW_THE_ICON = "Bascule la dissimulation ou l'affichage de l'icone."
65 loc.TEXT_TOGGLE_WHETHER_TO_SHOW_TEXT = "Bascule la dissimulation ou l'affichage du text."
66 -- loc.TEXT_LIST_PROFILING_INFO = "List profiling information" -- CHECK
67  
68 loc.MENU_SHOW_ICON = "Afficher l'icon"
69 loc.MENU_SHOW_TEXT = "Afficher le text"
70 -- loc.MENU_SHOW_COLORED_TEXT = "Show colored text" -- CHECK
71 -- loc.MENU_DETACH_TOOLTIP = "Detach tooltip" -- CHECK
72 -- loc.MENU_LOCK_TOOLTIP = "Lock tooltip" -- CHECK
73 -- loc.MENU_ON_LEFT_SIDE = "On left side" -- CHECK
74 -- loc.MENU_IN_CENTER = "In center" -- CHECK
75 -- loc.MENU_ON_RIGHT_SIDE = "On right side" -- CHECK
76 loc.MENU_HIDE = "Dissimule"
77 loc.MENU_DISABLE = "Desactive"
78 loc.MENU_ABOUT = "A propos"
79  
80 -- loc.MAP_ONOFF[0] = "|cffff0000Off|r" -- CHECK
81 -- loc.MAP_ONOFF[1] = "|cff00ff00On|r" -- CHECK
82  
83 loc.PATTERN_MERGE_WITH_CHILD = "Fusione avec %s"
84 loc.PATTERN_SWITCH_TO_CHILD = "Echange avec %s"
85 end
86  
87 local dewdrop = DewdropLib:GetInstance('1.0')
88 local tablet = TabletLib:GetInstance('1.0')
89  
90 if FUBAR_REVISION and MINOR_VERSION > FUBAR_REVISION then
91 FUBAR_REVISION = MINOR_VERSION
92 end
93  
94 -------------IRIEL'S-STUB-CODE--------------
95 local stub = {};
96  
97 -- Instance replacement method, replace contents of old with that of new
98 function stub:ReplaceInstance(old, new)
99 for k,v in pairs(old) do old[k]=nil; end
100 for k,v in pairs(new) do old[k]=v; end
101 end
102  
103 -- Get a new copy of the stub
104 function stub:NewStub()
105 local newStub = {};
106 self:ReplaceInstance(newStub, self);
107 newStub.lastVersion = '';
108 newStub.versions = {};
109 return newStub;
110 end
111  
112 -- Get instance version
113 function stub:GetInstance(version)
114 if (not version) then version = self.lastVersion; end
115 local versionData = self.versions[version];
116 if (not versionData) then
117 message("Cannot find library instance with version '"
118 .. version .. "'");
119 return;
120 end
121 return versionData.instance;
122 end
123  
124 -- Register new instance
125 function stub:Register(newInstance)
126 local version,minor = newInstance:GetLibraryVersion();
127 self.lastVersion = version;
128 local versionData = self.versions[version];
129 if (not versionData) then
130 -- This one is new!
131 versionData = { instance = newInstance,
132 minor = minor,
133 old = {}
134 };
135 self.versions[version] = versionData;
136 newInstance:LibActivate(self);
137 return newInstance;
138 end
139 if (minor <= versionData.minor) then
140 -- This one is already obsolete
141 if (newInstance.LibDiscard) then
142 newInstance:LibDiscard();
143 end
144 return versionData.instance;
145 end
146 -- This is an update
147 local oldInstance = versionData.instance;
148 local oldList = versionData.old;
149 versionData.instance = newInstance;
150 versionData.minor = minor;
151 local skipCopy = newInstance:LibActivate(self, oldInstance, oldList);
152 table.insert(oldList, oldInstance);
153 if (not skipCopy) then
154 for i, old in ipairs(oldList) do
155 self:ReplaceInstance(old, newInstance);
156 end
157 end
158 return newInstance;
159 end
160  
161 -- Bind stub to global scope if it's not already there
162 if (not FuBarPlugin) then
163 FuBarPlugin = stub:NewStub();
164 end
165 if (not FuBarPlugin.MinimapContainer) then
166 FuBarPlugin.MinimapContainer = stub:NewStub();
167 end
168  
169 -- Nil stub for garbage collection
170 stub = nil;
171 -----------END-IRIEL'S-STUB-CODE------------
172  
173 local RegisterTablet
174 -- FuBarPlugin
175 do
176 local compost
177 if CompostLib then
178 compost = CompostLib:GetInstance('compost-1')
179 end
180  
181 local epsilon = 1e-5
182  
183 local lib = AceAddon:new()
184  
185 local function VersionToNumber(version)
186 if version == nil then
187 return 0
188 elseif type(version) == "number" then
189 return version
190 end
191 local num = 0
192 local place = 1
193 string.gsub(version, "(%d+)", function (w)
194 num = num + tonumber(w) * math.pow(10, place * 2)
195 if place > 0 then
196 place = place - 1
197 else
198 place = place - 2
199 end
200 end)
201 return num
202 end
203  
204 function lib:assert(condition, message)
205 if not condition then
206 local stack = debugstack()
207 local first = string.gsub(stack, "\n.*", "")
208 local file = string.gsub(first, "^(.*\\.*)%.lua:%d+: .*", "%1")
209 local dir = string.gsub(file, "^(.*)\\.*", "%1")
210 if not message then
211 local _,_,second = string.find(stack, "\n(.-)\n")
212 message = "assertion failed! " .. second
213 end
214 if self:GetTitle() then
215 message = self:GetTitle() .. ": " .. message
216 end
217 local i = 1
218 for s in string.gfind(stack, "\n(.-)\n") do
219 i = i + 1
220 if not string.find(s, dir .. "\\.*%.lua:%d+:") then
221 error(message, i)
222 return
223 end
224 end
225 error(message, 2)
226 return
227 end
228 return condition
229 end
230  
231 function lib:GetTitle()
232 local _,_,title = string.find(self.name, "FuBar %- (.+)")
233 if not title then
234 title = self.name
235 end
236 return title
237 end
238  
239 function lib:DisableHideWithoutStandby()
240 self.hideWithoutStandby = false
241 if not self._hideWithoutStandbyEnabled then
242 return
243 end
244 self._hideWithoutStandbyEnabled = false
245 for index, value in self.cmd.options do
246 if value.method == "_ToggleVisible" then
247 table.remove(self.cmd.options, index)
248 break
249 end
250 end
251  
252 self._ToggleVisible = nil
253  
254 self.Report = self._Report
255 self._Report = nil
256  
257 if self.data.hidden then
258 self:DisableAddon()
259 end
260 self.data.hidden = nil
261 end
262  
263 function lib:EnableHideWithoutStandby()
264 self.hideWithoutStandby = true
265 if self._hideWithoutStandbyEnabled then
266 return
267 end
268 self._hideWithoutStandbyEnabled = true
269 table.insert(self.cmd.options, {
270 option = loc.ARGUMENT_VISIBLE,
271 desc = loc.TEXT_TOGGLE_VISIBILITY,
272 method = "_ToggleVisible"
273 })
274  
275 function self:_ToggleVisible()
276 if self.data.hidden then
277 self:Show()
278 else
279 self:Hide()
280 end
281 self.cmd:status(loc.ARGUMENT_VISIBLE, not self.data.hidden and 1 or 0, loc.MAP_ONOFF)
282 end
283  
284 if self.Report then
285 self._Report = self.Report
286 function self:Report()
287 self:_Report()
288 ace:print(" - ", format(ACE_CMD_REPORT_LINE, loc.ARGUMENT_VISIBLE, loc.MAP_ONOFF[not self.data.hidden and 1 or 0]))
289 end
290 else
291 function self:Report()
292 local report = compost and compost:Acquire(
293 compost:AcquireHash(
294 'text', loc.ARGUMENT_VISIBLE,
295 'val', not self.data.hidden and 1 or 0,
296 'map', loc.MAP_ONOFF
297 )
298 ) or {{
299 text = loc.ARGUMENT_VISIBLE,
300 val = not self.data.hidden and 1 or 0,
301 map = loc.MAP_ONOFF
302 }}
303 self.cmd:report(report)
304 if compost then
305 compost:Reclaim(report, 1)
306 end
307 end
308 end
309 end
310  
311 function lib:IsTextColored()
312 if self.data then
313 return not self.data.uncolored
314 else
315 return true
316 end
317 end
318  
319 function lib:ToggleMinimapAttached()
320 if FuBar then
321 local value = self:IsMinimapAttached()
322 if value then
323 self.panel:RemovePlugin(self)
324 FuBar:GetPanel(1):AddPlugin(self, nil, self.defaultPosition)
325 else
326 self.panel:RemovePlugin(self)
327 FuBarPlugin.MinimapContainer:GetInstance(MAJOR_VERSION):AddPlugin(self)
328 end
329 end
330 end
331  
332 function lib:IsMinimapAttached()
333 return self.panel == FuBarPlugin.MinimapContainer:GetInstance(MAJOR_VERSION)
334 end
335  
336 function lib:ToggleTextColored(loud)
337 self.data.uncolored = not self.data.uncolored or nil
338 if loud then
339 self.cmd:status(loc.ARGUMENT_COLOR, not self.data.uncolored and 1 or 0, loc.MAP_ONOFF)
340 end
341 self:UpdateText()
342 return not self.data.uncolored
343 end
344  
345 function lib:Update()
346 self:UpdateData()
347 self:UpdateText()
348 self:UpdateTooltip()
349 end
350  
351 function lib:UpdateDisplay()
352 self:UpdateText()
353 self:UpdateTooltip()
354 end
355  
356 local function inheritDefaults(t, defaults)
357 if not defaults then
358 return
359 end
360 for k,v in pairs(defaults) do
361 if type(v) == "table" then
362 if type(t[k]) ~= "table" then
363 t[k] = {}
364 end
365 inheritDefaults(t[k], v)
366 elseif t[k] == v then
367 t[k] = nil
368 end
369 end
370 for k,v in pairs(t) do
371 if v == 1 and defaults[k] == true then
372 t[k] = nil
373 elseif v == true and defaults[k] == 1 then
374 t[k] = nil
375 end
376 end
377 setmetatable(t, { __index = defaults })
378 end
379  
380 function lib:_OnAceProfileLoaded()
381 if self.db then
382 local t = self.db._table
383 if not t.profiles then
384 t.profiles = {}
385 end
386 if not t.profiles[self.profilePath[2]] then
387 t.profiles[self.profilePath[2]] = {}
388 end
389 if self.data ~= self.db._table.profiles[self.profilePath[2]] then
390 self.data = self.db._table.profiles[self.profilePath[2]]
391 else
392 return
393 end
394 elseif FuBar then
395 if not FuBarDB.pluginDB[self:GetTitle()] then
396 FuBarDB.pluginDB[self:GetTitle()] = {}
397 end
398 if not FuBarDB.pluginDB[self:GetTitle()].profiles then
399 FuBarDB.pluginDB[self:GetTitle()].profiles = {}
400 end
401 if not FuBarDB.pluginDB[self:GetTitle()].profiles[FuBar.profilePath[2]] then
402 FuBarDB.pluginDB[self:GetTitle()].profiles[FuBar.profilePath[2]] = {}
403 end
404 if self.data ~= FuBarDB.pluginDB[self:GetTitle()].profiles[FuBar.profilePath[2]] then
405 self.data = FuBarDB.pluginDB[self:GetTitle()].profiles[FuBar.profilePath[2]]
406 else
407 return
408 end
409 end
410 inheritDefaults(self.data, self.defaults)
411  
412 if type(self.ACE_PROFILE_LOADED) == "function" then
413 self:ACE_PROFILE_LOADED()
414 end
415  
416 self.data.version = self.version
417  
418 self:Update()
419 end
420  
421 function lib:Show(panelId)
422 if self:IsLoadOnDemand() and FuBar then
423 if not FuBar.fullData.loadOnDemand then
424 FuBar.fullData.loadOnDemand = {}
425 end
426 if not FuBar.fullData.loadOnDemand[self.folderName] then
427 FuBar.fullData.loadOnDemand[self.folderName] = {}
428 end
429 FuBar.fullData.loadOnDemand[self.folderName].disabled = nil
430 end
431 if self.disabled then
432 self.panelIdTmp = panelId
433 self:EnableAddon()
434 self.panelIdTmp = nil
435 if not self.db then
436 self.data.disabled = nil
437 end
438 elseif not self.data.hidden then
439 if panelId == 0 or not FuBar then
440 FuBarPlugin.MinimapContainer:GetInstance('1.2'):AddPlugin(self)
441 else
442 FuBar:ShowPlugin(self, panelId or self.panelIdTmp)
443 end
444 self:Update()
445 end
446 end
447  
448 function lib:Hide()
449 if self.hideWithoutStandby then
450 self.data.hidden = true
451 end
452 if not self.hideWithoutStandby then
453 if not self.overrideTooltip and not self.cannotDetachTooltip and self:IsTooltipDetached() and self.data.detachedTooltip.detached then
454 self:ReattachTooltip()
455 self.data.detachedTooltip.detached = true
456 end
457 if not self.db then
458 self.data.disabled = true
459 end
460 self:DisableAddon()
461 if self:IsLoadOnDemand() and FuBar then
462 FuBar.fullData.loadOnDemand[self.folderName].disabled = true
463 end
464 end
465 if self.panel then
466 self.panel:RemovePlugin(self)
467 end
468 self.frame:Hide()
469 if self.minimapFrame then
470 self.minimapFrame:Hide()
471 end
472 end
473  
474 function lib:AddImpliedMenuOptions(level)
475 if self.hasIcon and not self.hasNoText then
476 dewdrop:AddLine(
477 'text', loc.MENU_SHOW_ICON,
478 'func', function()
479 self:ToggleIconShown()
480 end,
481 'checked', self:IsIconShown(),
482 'level', level
483 )
484 end
485  
486 if not self.cannotHideText and self.hasIcon and not self.hasNoText then
487 dewdrop:AddLine(
488 'text', loc.MENU_SHOW_TEXT,
489 'func', function()
490 self:ToggleTextShown()
491 end,
492 'checked', self:IsTextShown(),
493 'leve', level
494 )
495 end
496  
497 if not self.userDefinedFrame and not self.hasNoText and not self.hasNoColor then
498 dewdrop:AddLine(
499 'text', loc.MENU_SHOW_COLORED_TEXT,
500 'arg1', self,
501 'func', "ToggleTextColored",
502 'checked', self:IsTextColored(),
503 'level', level
504 )
505 end
506  
507 if not self.overrideTooltip and not self.cannotDetachTooltip then
508 dewdrop:AddLine(
509 'text', loc.MENU_DETACH_TOOLTIP,
510 'func', function()
511 if self:IsTooltipDetached() then
512 self:ReattachTooltip()
513 else
514 self:DetachTooltip()
515 end
516 end,
517 'checked', self:IsTooltipDetached(),
518 'level', level
519 )
520  
521 dewdrop:AddLine(
522 'text', loc.MENU_LOCK_TOOLTIP,
523 'arg1', tablet,
524 'func', "ToggleLocked",
525 'arg2', self.frame,
526 'checked', tablet:IsLocked(self.frame),
527 'disabled', not self:IsTooltipDetached(),
528 'level', level
529 )
530 end
531  
532 if not self:IsMinimapAttached() then
533 dewdrop:AddLine(
534 'text', loc.MENU_ON_LEFT_SIDE,
535 'arg1', self.panel,
536 'func', self.panel:GetPluginSide(self) ~= "LEFT" and "SetPluginSide",
537 'arg2', self,
538 'arg3', "LEFT",
539 'checked', self.panel:GetPluginSide(self) == "LEFT",
540 'level', level,
541 'closeWhenClicked', self.panel:GetPluginSide(self) ~= "LEFT",
542 'isRadio', true
543 )
544  
545 dewdrop:AddLine(
546 'text', loc.MENU_IN_CENTER,
547 'arg1', self.panel,
548 'func', self.panel:GetPluginSide(self) ~= "CENTER" and "SetPluginSide",
549 'arg2', self,
550 'arg3', "CENTER",
551 'checked', self.panel:GetPluginSide(self) == "CENTER",
552 'level', level,
553 'closeWhenClicked', self.panel:GetPluginSide(self) ~= "CENTER",
554 'isRadio', true
555 )
556  
557 dewdrop:AddLine(
558 'text', loc.MENU_ON_RIGHT_SIDE,
559 'arg1', self.panel,
560 'func', self.panel:GetPluginSide(self) ~= "RIGHT" and "SetPluginSide",
561 'arg2', self,
562 'arg3', "RIGHT",
563 'checked', self.panel:GetPluginSide(self) == "RIGHT",
564 'level', level,
565 'closeWhenClicked', self.panel:GetPluginSide(self) ~= "RIGHT",
566 'isRadio', true
567 )
568 end
569  
570 dewdrop:AddLine(
571 'text', "Attach to minimap",
572 'arg1', self,
573 'func', "ToggleMinimapAttached",
574 'checked', self:IsMinimapAttached(),
575 'level', level,
576 'closeWhenClicked', true
577 )
578  
579 if self.hideWithoutStandby then
580 dewdrop:AddLine(
581 'text', loc.MENU_HIDE,
582 'arg1', self,
583 'func', "Hide",
584 'level', level,
585 'closeWhenClicked', true
586 )
587 end
588  
589 dewdrop:AddLine(
590 'text', loc.MENU_DISABLE,
591 'arg1', self,
592 'func', "DisableAddon",
593 'level', level,
594 'closeWhenClicked', true
595 )
596  
597 dewdrop:AddLine(
598 'level', level
599 )
600  
601 dewdrop:AddLine(
602 'text', loc.MENU_ABOUT,
603 'arg1', self.cmd,
604 'func', "DisplayAddonInfo",
605 'level', level
606 )
607 end
608  
609 function lib:SetIcon(path)
610 self:assert(self.hasIcon, "Cannot set icon unless self.hasIcon is set. (" .. self:GetTitle() .. ")")
611 if not self.iconFrame then
612 return
613 end
614 if type(path) ~= "string" then
615 path = "Interface\\AddOns\\" .. self.folderName .. "\\icon"
616 end
617 if string.sub(path, 1, 16) == "Interface\\Icons\\" then
618 self.iconFrame:SetTexCoord(0.05, 0.95, 0.05, 0.95)
619 else
620 self.iconFrame:SetTexCoord(0, 1, 0, 1)
621 end
622 self.iconFrame:SetTexture(path)
623 if self.minimapIcon then
624 if string.sub(path, 1, 16) == "Interface\\Icons\\" then
625 self.minimapIcon:SetTexCoord(0.05, 0.95, 0.05, 0.95)
626 else
627 self.minimapIcon:SetTexCoord(0, 1, 0, 1)
628 end
629 self.minimapIcon:SetTexture(path)
630 end
631 end
632  
633 function lib:GetIcon()
634 if self.hasIcon then
635 return self.iconFrame:GetTexture()
636 end
637 end
638  
639 function lib:CheckWidth(force)
640 if (self.iconFrame and self.iconFrame:IsShown()) or (self.textFrame and self.textFrame:IsShown()) then
641 if self.data and not self:IsIconShown() then
642 self.iconFrame:SetWidth(epsilon)
643 end
644 local width
645 if not self.hasNoText then
646 self.textFrame:SetHeight(0)
647 self.textFrame:SetWidth(500)
648 width = self.textFrame:GetStringWidth() + 1
649 self.textFrame:SetWidth(width)
650 self.textFrame:SetHeight(self.textFrame:GetHeight())
651 end
652 if self.hasNoText or not self.textFrame:IsShown() then
653 self.frame:SetWidth(self.iconFrame:GetWidth())
654 if self.panel and self.panel:GetPluginSide(self) == "CENTER" then
655 self.panel:UpdateCenteredPosition()
656 end
657 elseif force or not self.textWidth or self.textWidth < width or self.textWidth - 8 > width then
658 self.textWidth = width
659 self.textFrame:SetWidth(width)
660 if self.iconFrame and self.iconFrame:IsShown() then
661 self.frame:SetWidth(width + self.iconFrame:GetWidth())
662 else
663 self.frame:SetWidth(width)
664 end
665 if self.panel and self.panel:GetPluginSide(self) == "CENTER" then
666 self.panel:UpdateCenteredPosition()
667 end
668 end
669 end
670 end
671  
672 function lib:SetText(text)
673 if not self.textFrame then
674 return
675 end
676 -- self:assert(self.textFrame, "Cannot set text without a textFrame (" .. self:GetTitle() .. ")")
677 self:assert(not self.hasNoText, "Cannot set text if self.hasNoText has been set. (" .. self:GetTitle() .. ")")
678 self:assert(text, "You must provide a value for text, even if it is blank. (" .. self:GetTitle() .. ")")
679 if text == "" then
680 if self.hasIcon then
681 self:ShowIcon()
682 else
683 text = self:GetTitle()
684 end
685 end
686 if not self:IsTextColored() then
687 text = string.gsub(text, "|c%x%x%x%x%x%x%x%x(.-)|r", "%1")
688 end
689 self.textFrame:SetText(text)
690 self:CheckWidth()
691 end
692  
693 function lib:GetText()
694 self:assert(self.textFrame, "Cannot get text without a self.textFrame (" .. self:GetTitle() .. ")")
695 if not self.hasNoText then
696 return self.textFrame:GetText() or ""
697 end
698 end
699  
700 function lib:IsIconShown()
701 if not self.hasIcon then
702 return false
703 elseif self.hasNoText then
704 return true
705 elseif not self.data then
706 return true
707 elseif not self.data.showIcon then
708 return true
709 else
710 return (self.data.showIcon == 1 or self.data.showIcon == true) and true or false
711 end
712 end
713  
714 function lib:ToggleIconShown(loud)
715 self:assert(self.iconFrame, "Cannot toggle icon without a self.iconFrame (" .. self:GetTitle() .. ")")
716 self:assert(self.hasIcon, "Cannot show icon unless self.hasIcon is set. (" .. self:GetTitle() .. ")")
717 self:assert(not self.hasNoText, "Cannot hide icon if self.hasNoText is set. (" .. self:GetTitle() .. ")")
718 self:assert(self.textFrame, "Cannot hide icon if self.textFrame is not set. (" .. self:GetTitle() .. ")")
719 self:assert(self.iconFrame, "Cannot hide icon if self.iconFrame is not set. (" .. self:GetTitle() .. ")")
720 local value = not self:IsIconShown()
721 self.data.showIcon = value and 1 or 0
722 if loud then
723 self.cmd:status(loc.ARGUMENT_SHOWICON, value and 1 or 0, loc.MAP_ONOFF)
724 end
725 if value then
726 if self.textFrame:IsShown() and self.textFrame:GetText() == self:GetTitle() then
727 self.textFrame:Hide()
728 self.textFrame:SetText("")
729 end
730 self.iconFrame:Show()
731 self.iconFrame:SetWidth(self.iconFrame:GetHeight())
732 else
733 if not self.textFrame:IsShown() or not self.textFrame:GetText() then
734 self.textFrame:Show()
735 self.textFrame:SetText(self:GetTitle())
736 end
737 self.iconFrame:Hide()
738 self.iconFrame:SetWidth(epsilon)
739 end
740 self:CheckWidth(true)
741 return value
742 end
743  
744 function lib:ShowIcon()
745 if not self:IsIconShown() then
746 self:ToggleIconShown()
747 end
748 end
749  
750 function lib:HideIcon()
751 if self:IsIconShown() then
752 self:ToggleIconShown()
753 end
754 end
755  
756 function lib:IsTextShown()
757 if not self.hasIcon then
758 return false
759 elseif self.hasNoText then
760 return false
761 elseif not self.data then
762 return true
763 elseif not self.data.showText then
764 return true
765 else
766 return (self.data.showText == 1 or self.data.showText == true) and true or false
767 end
768 end
769  
770 function lib:ToggleTextShown(loud)
771 self:assert(not self.cannotHideText, "Cannot hide text unless self.cannotHideText is unset. (" .. self:GetTitle() .. ")")
772 self:assert(self.hasIcon, "Cannot show text unless self.hasIcon is set. (" .. self:GetTitle() .. ")")
773 self:assert(not self.hasNoText, "Cannot hide text if self.hasNoText is set. (" .. self:GetTitle() .. ")")
774 self:assert(self.textFrame, "Cannot hide text if self.textFrame is not set. (" .. self:GetTitle() .. ")")
775 self:assert(self.iconFrame, "Cannot hide text if self.iconFrame is not set. (" .. self:GetTitle() .. ")")
776 local value = not self:IsTextShown()
777 self.data.showText = value and 1 or 0
778 if loud then
779 self.cmd:status(loc.ARGUMENT_SHOWTEXT, value and 1 or 0, loc.MAP_ONOFF)
780 end
781 if value then
782 self.textFrame:Show()
783 self:UpdateText()
784 else
785 self.textFrame:SetText("")
786 self.textFrame:SetWidth(epsilon)
787 self.textFrame:Hide()
788 if not self:IsIconShown() then
789 DropDownList1:Hide()
790 end
791 self:ShowIcon()
792 end
793 self:CheckWidth(true)
794 return value
795 end
796  
797 function lib:ShowText()
798 if not self:IsTextShown() then
799 self:ToggleTextShown()
800 end
801 end
802  
803 function lib:HideText()
804 if self:IsTextShown() then
805 self:ToggleTextShown()
806 end
807 end
808  
809 function lib:OpenChildFrame(child)
810 self:assert(child, "Expected frame, received nil. (" .. self:GetTitle() .. ")")
811 if FuBarPlugin.lastChildFrame then
812 FuBarPlugin.lastChildFrame:Hide()
813 end
814 FuBarPlugin.lastChildFrame = child
815 local frame = self.frame
816 local width, height = GetScreenWidth(), GetScreenHeight()
817 local anchor
818 if frame:GetLeft() <= width/2 then
819 anchor = "LEFT"
820 else
821 anchor = "RIGHT"
822 end
823 child:ClearAllPoints()
824 if frame:GetTop() <= height/2 then
825 child:SetPoint("BOTTOM" .. anchor, frame, "TOP" .. anchor)
826 local left = child:GetLeft()
827 child:ClearAllPoints()
828 child:SetPoint("LEFT", UIParent, "LEFT", left, 0)
829 child:SetPoint("BOTTOM", frame, "TOP")
830 else
831 child:SetPoint("TOP" .. anchor, frame, "BOTTOM" .. anchor)
832 local left = child:GetLeft()
833 child:ClearAllPoints()
834 child:SetPoint("LEFT", UIParent, "LEFT", left, 0)
835 child:SetPoint("TOP", frame, "BOTTOM")
836 end
837 child:Show()
838 end
839  
840 local onClickTypes = {"OnClick", "OnDoubleClick", "OnMouseDown", "OnMouseUp"}
841  
842 function lib:HookIntoPlugin(mother, style)
843 if self.hookedPlugin then
844 ace:print(self:GetTitle() .. ": Cannot hook into a plugin while already hooked into another.")
845 return false
846 end
847 if not mother or type(mother) ~= "table" or getmetatable(self).__index ~= getmetatable(mother).__index then
848 ace:print(self:GetTitle() .. ": Cannot hook into given plugin.")
849 return false
850 end
851 local showTitle = false
852 if style then
853 local a, b = string.find(style, "_TITLE")
854 if a and b then
855 showTitle = true
856 style = string.sub(style, 1, a - 1) .. string.sub(style, b + 1)
857 end
858 end
859 if style ~= "INLINE" and style ~= "SWITCH" and style ~= "SWITCHTEXT" then
860 style = "INLINE"
861 end
862 local child = self
863 local merged = false
864 local current = "MOTHER"
865 local mother__UpdateTooltip = mother._UpdateTooltip
866 local child_UpdateTooltip = child.UpdateTooltip
867 local mother_UpdateText = mother.UpdateText
868 local child_UpdateText = child.UpdateText
869 local child_Show = child.Show
870 local mother_funcs = {}
871 local mother_MenuSettings = mother.MenuSettings
872 local manualStandby = false
873 local motherIcon = mother:GetIcon()
874 local childIcon = child:GetIcon()
875 local merge, unmerge, switch
876 switch = function()
877 if current == "MOTHER" then
878 self.data["switch." .. mother:GetTitle()] = "CHILD"
879 current = "CHILD"
880 getmetatable(mother).__index.SetIcon(mother, childIcon)
881 else
882 self.data["switch." .. mother:GetTitle()] = "MOTHER"
883 current = "MOTHER"
884 getmetatable(mother).__index.SetIcon(mother, motherIcon)
885 end
886 mother:UpdateText()
887 mother:UpdateTooltip()
888 dewdrop:Close()
889 end
890 function self:SwitchPluginHook()
891 switch()
892 end
893 function self:IsCurrentPluginHookSwitch()
894 return current ~= "MOTHER"
895 end
896 merge = function()
897 merged = true
898 self.data["merge." .. mother:GetTitle()] = 1
899 if style == "INLINE" or style == "SWITCHTEXT" then
900 function mother:_UpdateTooltip()
901 mother__UpdateTooltip(mother)
902 if showTitle and not mother:IsTooltipDetached() then
903 tablet:AddCategory(
904 'text', child:GetTitle(),
905 'font', tablet:GetHeaderFontObject(),
906 'justify', "CENTER",
907 'isTitle', true
908 )
909 end
910 child:_UpdateTooltip()
911 end
912 elseif style == "SWITCH" then
913 function mother:_UpdateTooltip()
914 if current == "MOTHER" then
915 mother__UpdateTooltip(mother)
916 else
917 mother.tooltip:SetTitle(child:GetTitle())
918 child.tooltip = mother.tooltip
919 child:_UpdateTooltip()
920 end
921 end
922 end
923 function child:UpdateTooltip()
924 mother:UpdateTooltip()
925 end
926  
927 local text
928 if style == "INLINE" then
929 function mother:SetText(t)
930 text = t
931 end
932 function child:SetText(t)
933 if text == "" or not text then
934 text = t
935 else
936 text = text .. " " .. t
937 end
938 end
939 elseif style == "SWITCH" or style == "SWITCHTEXT" then
940 function mother:SetText(t)
941 if current == "MOTHER" then
942 text = t
943 end
944 end
945 function child:SetText(t)
946 if current ~= "MOTHER" then
947 text = t
948 end
949 end
950 end
951  
952 if style == "INLINE" then
953 function mother:UpdateText()
954 text = ""
955 if mother_UpdateText then
956 mother_UpdateText(mother)
957 end
958 if child_UpdateText then
959 child_UpdateText(child)
960 end
961 getmetatable(mother).__index.SetText(mother, text)
962 text = nil
963 end
964 elseif style == "SWITCH" or style == "SWITCHTEXT" then
965 function mother:UpdateText()
966 text = ""
967 if current == "MOTHER" and mother_UpdateText then
968 mother_UpdateText(mother)
969 end
970 if current ~= "MOTHER" and child_UpdateText then
971 child_UpdateText(child)
972 end
973 getmetatable(mother).__index.SetText(mother, text)
974 text = nil
975 end
976 end
977 child.UpdateText = mother.UpdateText
978  
979 for _,name in onClickTypes do
980 local name = name
981 mother_funcs[name] = mother[name]
982 local child_func = child[name]
983 if style == "INLINE" then
984 if mother_funcs[name] and child_func then
985 mother[name] = function(self, alpha)
986 mother_funcs[name](mother, alpha)
987 child_func(child, alpha)
988 end
989 elseif child_func then
990 mother[name] = child_func
991 end
992 elseif style == "SWITCH" or style == "SWITCHTEXT" then
993 if mother_funcs[name] and child_func then
994 mother[name] = function(self, alpha)
995 if current == "MOTHER" and mother_funcs[name] ~= "nil" then
996 mother_funcs[name](mother, alpha)
997 elseif current ~= "MOTHER" and child_func then
998 child_func(child, alpha)
999 end
1000 end
1001 elseif child_func then
1002 mother[name] = function(self, alpha)
1003 if current ~= "MOTHER" and child_func then
1004 child_func(child, alpha)
1005 end
1006 end
1007 elseif mother_funcs[name] then
1008 mother[name] = function(self, alpha)
1009 if current == "MOTHER" and mother_funcs[name] ~= "nil" then
1010 mother_funcs[name](mother, alpha)
1011 end
1012 end
1013 end
1014 end
1015 if not mother_funcs[name] then
1016 mother_funcs[name] = "nil"
1017 end
1018 end
1019  
1020 if style == "SWITCH" or style == "SWITCHTEXT" then
1021 function mother:SetIcon(path)
1022 motherIcon = path
1023 getmetatable(mother).__index.SetIcon(mother, path)
1024 end
1025 function child:SetIcon(path)
1026 childIcon = path
1027 getmetatable(mother).__index.SetIcon(mother, path)
1028 end
1029 end
1030  
1031 function child:Show(panelId)
1032 if panelId and panelId ~= 0 then
1033 unmerge()
1034 end
1035  
1036 child_Show(self, panelId)
1037 end
1038  
1039 if not child.hideWithoutStandby then
1040 manualStandby = true
1041 child:EnableHideWithoutStandby()
1042 end
1043 child:Hide()
1044  
1045 mother:UpdateText()
1046 mother:UpdateTooltip()
1047 end
1048 unmerge = function()
1049 merged = false
1050 self.data["merge." .. mother:GetTitle()] = 0
1051 mother._UpdateTooltip = mother__UpdateTooltip
1052 child.UpdateTooltip = child_UpdateTooltip
1053 mother.SetText = nil
1054 child.SetText = nil
1055 mother.SetIcon = nil
1056 child.SetIcon = nil
1057 mother.UpdateText = mother_UpdateText
1058 child.UpdateText = child_UpdateText
1059 for name,func in pairs(mother_funcs) do
1060 if func == "nil" then
1061 mother[name] = nil
1062 else
1063 mother[name] = func
1064 end
1065 end
1066 child.Show = child_Show
1067 if manualStandby then
1068 child:DisableHideWithoutStandby()
1069 manualStandby = false
1070 end
1071 mother:SetIcon(motherIcon)
1072 mother:UpdateText()
1073 mother:UpdateTooltip()
1074 child:Show()
1075 end
1076  
1077 function mother:MenuSettings(level, value)
1078 if level == 1 then
1079 dewdrop:AddLine(
1080 'text', format(loc.PATTERN_MERGE_WITH_CHILD, child:GetTitle()),
1081 'func', function()
1082 if merged then
1083 unmerge()
1084 else
1085 if child.disabled then
1086 child:EnableAddon()
1087 end
1088 merge()
1089 end
1090 end,
1091 'checked', merged,
1092 'hasArrow', merged and (style == "SWITCH" or style == "SWITCHTEXT"),
1093 'value', child:GetTitle()
1094 )
1095 elseif level == 2 and value == child:GetTitle() then
1096 dewdrop:AddLine(
1097 'text', format(loc.PATTERN_SWITCH_TO_CHILD, child:GetTitle()),
1098 'func', switch,
1099 'checked', current ~= "MOTHER"
1100 )
1101 end
1102 if merged then
1103 if (style ~= "SWITCH" or (style == "SWITCH" and current == "MOTHER")) and mother_MenuSettings then
1104 if level == 1 then
1105 dewdrop:AddLine()
1106 end
1107 mother_MenuSettings(mother, level, value)
1108 end
1109 if (style ~= "SWITCH" or (style == "SWITCH" and current == "CHILD")) and child.MenuSettings then
1110 if level == 1 then
1111 dewdrop:AddLine()
1112 dewdrop:AddLine(
1113 'text', child:GetTitle(),
1114 'isTitle', true
1115 )
1116 end
1117 child:MenuSettings(level, value)
1118 end
1119 else
1120 if mother_MenuSettings then
1121 if level == 1 then
1122 dewdrop:AddLine()
1123 end
1124 mother_MenuSettings(mother, level, value)
1125 end
1126 end
1127 end
1128 if not self.data["merge." .. mother:GetTitle()] then
1129 self.data["merge." .. mother:GetTitle()] = 1
1130 end
1131 if (style == "SWITCH" or style == "SWITCHTEXT") and not self.data["switch." .. mother:GetTitle()] then
1132 self.data["switch." .. mother:GetTitle()] = "MOTHER"
1133 end
1134 if self.data["merge." .. mother:GetTitle()] == 1 then
1135 merge()
1136 end
1137 if style == "SWITCH" or style == "SWITCHTEXT" then
1138 if self.data["switch." .. mother:GetTitle()] == "MOTHER" then
1139 self.data["switch." .. mother:GetTitle()] = "CHILD"
1140 else
1141 self.data["switch." .. mother:GetTitle()] = "MOTHER"
1142 end
1143 current = self.data["switch." .. mother:GetTitle()]
1144 switch()
1145 end
1146 self.hookedPlugin = mother
1147 return true
1148 end
1149  
1150 function lib:IsTooltipDetached()
1151 if not tablet.registry[self.frame] then
1152 self:UpdateTooltip()
1153 end
1154 return not tablet:IsAttached(self.frame)
1155 end
1156  
1157 function lib:DetachTooltip()
1158 tablet:Detach(self.frame)
1159 end
1160  
1161 function lib:ReattachTooltip()
1162 tablet:Attach(self.frame)
1163 end
1164  
1165 function lib:GetName()
1166 return self.name
1167 end
1168  
1169 function lib:GetCategory()
1170 return self.category
1171 end
1172  
1173 function lib:GetFrame()
1174 return self.frame
1175 end
1176  
1177 function lib:GetPanel()
1178 return self.panel
1179 end
1180  
1181 function lib:GetDefaultPosition()
1182 return self.defaultPosition or "LEFT"
1183 end
1184  
1185 local function IsCorrectPanel(panel)
1186 if type(panel) ~= "table" then
1187 return false
1188 elseif type(panel.AddPlugin) ~= "function" then
1189 return false
1190 elseif type(panel.RemovePlugin) ~= "function" then
1191 return false
1192 elseif type(panel.GetNumPlugins) ~= "function" then
1193 return false
1194 elseif type(panel:GetNumPlugins()) ~= "number" then
1195 return false
1196 elseif type(panel.GetPlugin) ~= "function" then
1197 return false
1198 elseif type(panel.HasPlugin) ~= "function" then
1199 return false
1200 elseif type(panel.GetPluginSide) ~= "function" then
1201 return false
1202 end
1203 return true
1204 end
1205  
1206 function lib:SetPanel(panel)
1207 if panel then
1208 self:assert(IsCorrectPanel(panel), "Panel does not have the correct API.")
1209 end
1210 self.panel = panel
1211 end
1212  
1213 function lib:SetFontSize(size)
1214 self:assert(not self.userDefinedFrame, "You must provide a SetFontSize(size) method if you provide your own frame.")
1215 if self.hasIcon and self.iconFrame then
1216 -- self:assert(self.iconFrame, (self.name and self.name .. ": " or "") .. "No iconFrame found")
1217 self.iconFrame:SetWidth(size + 3)
1218 self.iconFrame:SetHeight(size + 3)
1219 end
1220 if not self.hasNoText and self.textFrame then
1221 -- self:assert(self.textFrame, (self.name and self.name .. ": " or "") .. "No textFrame found")
1222 local font, _, flags = self.textFrame:GetFont()
1223 self.textFrame:SetFont(font, size, flags)
1224 end
1225 self:CheckWidth()
1226 end
1227  
1228 function lib:SetLoadOnDemand(lod)
1229 self._loadOnDemand = lod and true or false
1230 end
1231  
1232 function lib:IsLoadOnDemand()
1233 return self._loadOnDemand
1234 end
1235  
1236 function lib:IsDisabled()
1237 return self.disabled
1238 end
1239  
1240 local function cleanDefaults(t, defaults, notFirst)
1241 if defaults then
1242 for k,v in pairs(defaults) do
1243 if type(v) == "table" then
1244 if type(t[k]) == "table" then
1245 cleanDefaults(t[k], v, true)
1246 if next(t[k]) == nil then
1247 t[k] = nil
1248 end
1249 end
1250 elseif t[k] == v then
1251 t[k] = nil
1252 elseif t[k] == true and v == TRUE then
1253 t[k] = nil
1254 elseif t[k] == TRUE and v == true then
1255 t[k] = nil
1256 end
1257 end
1258 for k,v in pairs(t) do
1259 if v == false and not defaults[k] then
1260 t[k] = nil
1261 end
1262 end
1263 end
1264 if not notFirst then
1265 if next(t) == "version" and next(t, "version") == nil then
1266 t.version = nil
1267 return true
1268 end
1269 end
1270 return false
1271 end
1272  
1273 function RegisterTablet(self)
1274 if not tablet:IsRegistered(self.frame) then
1275 tablet:Register(self.frame,
1276 'children', function()
1277 tablet:SetTitle(self:GetTitle())
1278 self:_UpdateTooltip()
1279 end,
1280 'clickable', self.clickableTooltip,
1281 'data', FuBar and FuBar.data.tooltip or self.data.detachedTooltip,
1282 'detachedData', self.data.detachedTooltip,
1283 'point', function(frame)
1284 if frame:GetTop() > GetScreenHeight() / 2 then
1285 local x = frame:GetCenter()
1286 if x < GetScreenWidth() / 3 then
1287 return "TOPLEFT", "BOTTOMLEFT"
1288 elseif x < GetScreenWidth() * 2 / 3 then
1289 return "TOP", "BOTTOM"
1290 else
1291 return "TOPRIGHT", "BOTTOMRIGHT"
1292 end
1293 else
1294 local x = frame:GetCenter()
1295 if x < GetScreenWidth() / 3 then
1296 return "BOTTOMLEFT", "TOPLEFT"
1297 elseif x < GetScreenWidth() * 2 / 3 then
1298 return "BOTTOM", "TOP"
1299 else
1300 return "BOTTOMRIGHT", "TOPRIGHT"
1301 end
1302 end
1303 end,
1304 'menu', function(level, value, valueN_1, valueN_2, valueN_3, valueN_4)
1305 self:MenuSettings(level, value, true, valueN_1, valueN_2, valueN_3, valueN_4)
1306 end
1307 )
1308 end
1309 end
1310  
1311 function lib:RegisterForLoad()
1312 if not self.defaults then
1313 self.defaults = {}
1314 end
1315 if not self.defaults.detachedTooltip then
1316 self.defaults.detachedTooltip = {}
1317 end
1318  
1319 if not self.cmd then
1320 local title = string.lower(self:GetTitle())
1321 self.cmd = AceChatCmd:new({"/" .. string.gsub(title, " ", "_"), "/" .. string.gsub(title, " ", "")}, {})
1322 end
1323  
1324 _,_,self.folderName = string.find(debugstack(2, 1, 0), "\\AddOns\\(.*)\\")
1325  
1326 self.versionNumber = FuBarUtils and VersionToNumber(self.version)
1327  
1328 if not self.frame then
1329 local name = "FuBarPlugin" .. self:GetTitle() .. "Frame"
1330 local frame = getglobal(name)
1331 if not frame or not getglobal(self.frame:GetName() .. "Text") or not getglobal(self.frame:GetName() .. "Icon") then
1332 frame = getmetatable(self).__index.CreateBasicPluginFrame(self, name)
1333  
1334 local icon = frame:CreateTexture(name .. "Icon", "ARTWORK")
1335 icon:SetWidth(16)
1336 icon:SetHeight(16)
1337 icon:SetPoint("LEFT", frame, "LEFT")
1338  
1339 local text = frame:CreateFontString(name .. "Text", "ARTWORK")
1340 text:SetWidth(134)
1341 text:SetHeight(24)
1342 text:SetPoint("LEFT", icon, "RIGHT", 0, 1)
1343 text:SetFontObject(GameFontNormal)
1344 end
1345 self.frame = frame
1346 self.textFrame = getglobal(self.frame:GetName() .. "Text")
1347 self.iconFrame = getglobal(self.frame:GetName() .. "Icon")
1348 else
1349 self.userDefinedFrame = true
1350 end
1351  
1352 self.frame.plugin = self
1353 self.frame:SetParent(UIParent)
1354 self.frame:SetPoint("RIGHT", UIParent, "LEFT", -5, 0)
1355 self.frame:Hide()
1356  
1357 if not self.UpdateData then
1358 self.UpdateData = function(self) end
1359 end
1360 if not self.UpdateText then
1361 if self.hasNoText then
1362 self.UpdateText = function(self) end
1363 else
1364 self.UpdateText = function(self)
1365 self:SetText(self:GetTitle())
1366 end
1367 end
1368 end
1369 if not self.UpdateTooltip then
1370 self.UpdateTooltip = function(self) end
1371 end
1372  
1373 if self.hasIcon then
1374 self:SetIcon(self.hasIcon)
1375  
1376 if not self.cmd.options then
1377 self.cmd.options = {}
1378 end
1379  
1380 table.insert(self.cmd.options, {
1381 option = loc.ARGUMENT_SHOWICON,
1382 desc = loc.TEXT_TOGGLE_WHETHER_TO_SHOW_THE_ICON,
1383 method = "ToggleIconShown"
1384 })
1385  
1386 local old_Enable = self.Enable
1387 function self:Enable()
1388 if old_Enable then
1389 old_Enable(self)
1390 end
1391 if self:IsIconShown() then
1392 self.iconFrame:Show()
1393 else
1394 self.iconFrame:Hide()
1395 end
1396 self:CheckWidth(true)
1397 end
1398  
1399 local old_Report = self.Report
1400 if old_Report then
1401 function self:Report()
1402 old_Report(self)
1403 ace:print(" - ", format(ACE_CMD_REPORT_LINE, loc.ARGUMENT_SHOWICON, loc.MAP_ONOFF[self:IsIconShown() and 1 or 0]))
1404 end
1405 else
1406 function self:Report()
1407 local report = compost and compost:Acquire(
1408 compost:AcquireHash(
1409 'text', loc.ARGUMENT_SHOWICON,
1410 'val', self:IsIconShown() and 1 or 0,
1411 'map', loc.MAP_ONOFF
1412 )
1413 ) or {{
1414 text = loc.ARGUMENT_SHOWICON,
1415 val = self:IsIconShown() and 1 or 0,
1416 map = loc.MAP_ONOFF
1417 }}
1418 self.cmd:report(report)
1419 if compost then
1420 compost:Reclaim(report, 1)
1421 end
1422 end
1423 end
1424 end
1425  
1426 if not self.textFrame or not self.hasIcon then
1427 self.cannotHideText = true
1428 end
1429 if not self.cannotHideText then
1430 table.insert(self.cmd.options, {
1431 option = loc.ARGUMENT_SHOWTEXT,
1432 desc = loc.TEXT_TOGGLE_WHETHER_TO_SHOW_TEXT,
1433 method = "ToggleTextShown"
1434 })
1435  
1436 local old_Enable = self.Enable
1437 function self:Enable()
1438 if old_Enable then
1439 old_Enable(self)
1440 end
1441 if self:IsTextShown() then
1442 self.textFrame:Show()
1443 else
1444 self.textFrame:Hide()
1445 end
1446 self:CheckWidth(true)
1447 end
1448  
1449 local old_Report = self.Report
1450 if old_Report then
1451 function self:Report()
1452 old_Report(self)
1453 ace:print(" - ", format(ACE_CMD_REPORT_LINE, loc.ARGUMENT_SHOWTEXT, loc.MAP_ONOFF[self:IsTextShown() and 1 or 0]))
1454 end
1455 else
1456 function self:Report()
1457 local report = compost and compost:Acquire(
1458 compost:AcquireHash(
1459 'text', loc.ARGUMENT_SHOWTEXT,
1460 'val', self:IsTextShown() and 1 or 0,
1461 'map', loc.MAP_ONOFF
1462 )
1463 ) or {{
1464 text = loc.ARGUMENT_SHOWTEXT,
1465 val = self:IsTextShown() and 1 or 0,
1466 map = loc.MAP_ONOFF
1467 }}
1468 self.cmd:report(report)
1469 compost:Reclaim(report, 1)
1470 end
1471 end
1472 end
1473  
1474 if self.hideWithoutStandby then
1475 self:EnableHideWithoutStandby()
1476 end
1477  
1478 local old_Enable = self.Enable
1479 function self:Enable()
1480 if old_Enable then
1481 old_Enable(self)
1482 end
1483 if not self.hideWithoutStandby or not self.data.hidden then
1484 self:Show()
1485 end
1486 self:RegisterEvent("ACE_PROFILE_LOADED", "_OnAceProfileLoaded")
1487  
1488 if not self.overrideTooltip and not self.cannotDetachTooltip and self.data.detachedTooltip and self.data.detachedTooltip.detached then
1489 self:DetachTooltip()
1490 end
1491 end
1492  
1493 if self.db then
1494 local old_Initialize = self.Initialize
1495 function self:Initialize()
1496 local t = self.db._table
1497 if not t.profiles then
1498 t.profiles = {}
1499 end
1500 if not t.profiles[self.profilePath[2]] then
1501 t.profiles[self.profilePath[2]] = {}
1502 end
1503  
1504 if not t.realms then
1505 t.realms = {}
1506 end
1507 if not t.realms[GetRealmName() .. UnitFactionGroup("player")] then
1508 t.realms[GetRealmName() .. UnitFactionGroup("player")] = {}
1509 end
1510 if type(self.chardb) ~= "string" then
1511 if not t.chars then
1512 t.chars = {}
1513 end
1514 if not t.chars[GetRealmName() .. UnitName("player")] then
1515 t.chars[GetRealmName() .. UnitName("player")] = {}
1516 end
1517 self.charData = t.chars[GetRealmName() .. UnitName("player")]
1518 else
1519 local c = getglobal(self.chardb)
1520 if type(c) ~= "table" then
1521 setglobal(self.chardb, {})
1522 c = getglobal(self.chardb)
1523 end
1524 self.charData = c
1525 end
1526 if not t.classes then
1527 t.classes = {}
1528 end
1529 if not t.classes[UnitClass("player")] then
1530 t.classes[UnitClass("player")] = {}
1531 end
1532 if not t.full then
1533 t.full = {}
1534 end
1535 self.data = t.profiles[self.profilePath[2]]
1536 inheritDefaults(self.data, self.defaults)
1537 self.realmData = t.realms[GetRealmName() .. UnitFactionGroup("player")]
1538 inheritDefaults(self.realmData, self.realmDefaults)
1539 inheritDefaults(self.charData, self.charDefaults)
1540 self.classData = t.classes[UnitClass("player")]
1541 inheritDefaults(self.classData, self.classDefaults)
1542 self.fullData = t.full
1543 inheritDefaults(self.fullData, self.fullDefaults)
1544  
1545 self.data.version = VersionToNumber(self.data.version)
1546 self.charData.version = VersionToNumber(self.charData.version)
1547 self.classData.version = VersionToNumber(self.classData.version)
1548 self.realmData.version = VersionToNumber(self.realmData.version)
1549 self.fullData.version = VersionToNumber(self.fullData.version)
1550 if self.data.version >= 500 then
1551 self.data.version = self.data.version / 100
1552 self.charData.version = self.charData.version / 100
1553 self.classData.version = self.classData.version / 100
1554 self.realmData.version = self.realmData.version / 100
1555 self.fullData.version = self.fullData.version / 100
1556 end
1557  
1558 if old_Initialize then
1559 old_Initialize(self)
1560 end
1561  
1562 self.data.version = VersionToNumber(self.version)
1563 self.charData.version = VersionToNumber(self.version)
1564 self.classData.version = VersionToNumber(self.version)
1565 self.realmData.version = VersionToNumber(self.version)
1566 self.fullData.version = VersionToNumber(self.version)
1567 end
1568 elseif FuBar then
1569 local old_Initialize = self.Initialize
1570 function self:Initialize()
1571 if not FuBarDB.pluginDB then
1572 FuBarDB.pluginDB = {}
1573 end
1574  
1575 if not FuBarDB.pluginDB[self:GetTitle()] then
1576 FuBarDB.pluginDB[self:GetTitle()] = {}
1577 end
1578  
1579 local t = FuBarDB.pluginDB[self:GetTitle()]
1580  
1581 if not t.profiles then
1582 t.profiles = {}
1583 end
1584 if not t.profiles[FuBar.profilePath[2]] then
1585 t.profiles[FuBar.profilePath[2]] = {}
1586 end
1587 if not t.realms then
1588 t.realms = {}
1589 end
1590 if not t.realms[GetRealmName() .. UnitFactionGroup("player")] then
1591 t.realms[GetRealmName() .. UnitFactionGroup("player")] = {}
1592 end
1593 if type(self.chardb) ~= "string" then
1594 if not t.chars then
1595 t.chars = {}
1596 end
1597 if not t.chars[GetRealmName() .. UnitName("player")] then
1598 t.chars[GetRealmName() .. UnitName("player")] = {}
1599 end
1600 self.charData = t.chars[GetRealmName() .. UnitName("player")]
1601 else
1602 local c = getglobal(self.chardb)
1603 if type(c) ~= "table" then
1604 setglobal(self.chardb, {})
1605 c = getglobal(self.chardb)
1606 end
1607 self.charData = c
1608 end
1609 if not t.classes then
1610 t.classes = {}
1611 end
1612 if not t.classes[UnitClass("player")] then
1613 t.classes[UnitClass("player")] = {}
1614 end
1615 if not t.full then
1616 t.full = {}
1617 end
1618 self.data = t.profiles[FuBar.profilePath[2]]
1619 inheritDefaults(self.data, self.defaults)
1620 self.realmData = t.realms[GetRealmName() .. UnitFactionGroup("player")]
1621 inheritDefaults(self.realmData, self.realmDefaults)
1622 inheritDefaults(self.charData, self.charDefaults)
1623 self.classData = t.classes[UnitClass("player")]
1624 inheritDefaults(self.classData, self.classDefaults)
1625 self.fullData = t.full
1626 inheritDefaults(self.fullData, self.fullDefaults)
1627  
1628 if old_Initialize then
1629 old_Initialize(self)
1630 end
1631  
1632 self.data.version = VersionToNumber(self.version)
1633 self.charData.version = VersionToNumber(self.version)
1634 self.classData.version = VersionToNumber(self.version)
1635 self.realmData.version = VersionToNumber(self.version)
1636 self.fullData.version = VersionToNumber(self.version)
1637  
1638 if self.data.disabled then
1639 self:DisableAddon()
1640 end
1641 end
1642 else
1643 local old_Initialize = self.Initialize
1644 function self:Initialize()
1645 self.data = {}
1646 self.charData = {}
1647 self.classData = {}
1648 self.realmData = {}
1649 self.fullData = {}
1650  
1651 if old_Initialize then
1652 old_Initialize(self)
1653 end
1654  
1655 self.data.version = VersionToNumber(self.version)
1656 self.charData.version = VersionToNumber(self.version)
1657 self.classData.version = VersionToNumber(self.version)
1658 self.realmData.version = VersionToNumber(self.version)
1659 self.fullData.version = VersionToNumber(self.version)
1660 end
1661 end
1662  
1663 local old_Disable = self.Disable
1664 function self:Disable()
1665 if old_Disable then
1666 old_Disable(self)
1667 end
1668 self:Hide()
1669 end
1670  
1671 if not self.overrideTooltip then
1672 self._UpdateTooltip = self.UpdateTooltip
1673 function self:UpdateTooltip()
1674 RegisterTablet(self)
1675 tablet:Refresh(self.frame)
1676 end
1677 end
1678  
1679 local self_Initialize = self.Initialize
1680 function self:Initialize()
1681 self_Initialize(self)
1682  
1683 local profilePlugin = FuBar and FuBar:GetPluginProfiling()
1684  
1685 if self == profilePlugin then
1686 local start = GetTime()
1687 local tree = {}
1688 local treeMemories = {}
1689 local treeTimes = {}
1690 local memories = {}
1691 local times = {}
1692 local aname = self.name
1693 for name,value in pairs(self) do
1694 if type(value) == "function" and name ~= "Initialize" then
1695 local oldFunction = value
1696 local name = name
1697 local rName = name
1698 if name == "UpdateTooltip" then
1699 name = "tablet:Refresh"
1700 elseif name == "_UpdateTooltip" then
1701 name = "UpdateTooltip"
1702 end
1703 if strsub(name, 1, 1) ~= "_" then
1704 memories[name] = 0
1705 times[name] = 0
1706 self[rName] = function(self, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
1707 local pos = table.getn(tree)
1708 table.insert(tree, name)
1709 table.insert(treeMemories, 0)
1710 table.insert(treeTimes, 0)
1711 local t, mem = GetTime(), gcinfo()
1712 local r1, r2, r3, r4, r5, r6, r7, r8 = oldFunction(self, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
1713 mem, t = gcinfo() - mem, GetTime() - t
1714 if pos > 0 then
1715 treeMemories[pos] = treeMemories[pos] + mem
1716 treeTimes[pos] = treeTimes[pos] + t
1717 end
1718 local otherMem = table.remove(treeMemories)
1719 if mem - otherMem > 0 then
1720 memories[name] = memories[name] + mem - otherMem
1721 end
1722 times[name] = times[name] + t - table.remove(treeTimes)
1723 table.remove(tree)
1724 return r1, r2, r3, r4, r5, r6, r7, r8
1725 end
1726 end
1727 end
1728 end
1729  
1730 if not self.cmd.options then
1731 self.cmd.options = {}
1732 end
1733  
1734 table.insert(self.cmd.options, {
1735 option = loc.ARGUMENT_PROFILE,
1736 desc = loc.TEXT_LIST_PROFILING_INFO,
1737 method = "_ListProfileInfo"
1738 })
1739  
1740 function self:_ListProfileInfo()
1741 local duration = GetTime() - start
1742 for name in pairs(memories) do
1743 local mem = memories[name]
1744 local time = times[name]
1745 DEFAULT_CHAT_FRAME:AddMessage(string.format("%.3fs / %.3fs (%.3f%%) || %s (%d KiB)", times[name], duration, times[name] / duration * 100, name, memories[name]))
1746 end
1747 end
1748  
1749 function self:GetProfileInfo()
1750 return GetTime() - start, times, memories
1751 end
1752 end
1753 end
1754  
1755 if self.defaultPosition ~= "LEFT" and self.defaultPosition ~= "CENTER" and self.defaultPosition ~= "RIGHT" and self.defaultPosition ~= "MINIMAP" then
1756 self.defaultPosition = "LEFT"
1757 end
1758 if type(self.defaultMinimapPosition) ~= "number" then
1759 self.defaultMinimapPosition = math.random(1, 360)
1760 end
1761  
1762 self.frame:RegisterEvent("PLAYER_LOGOUT")
1763 local OnEvent = self.frame:GetScript("OnEvent")
1764 self.frame:SetScript("OnEvent", function()
1765 if OnEvent then
1766 OnEvent()
1767 end
1768 if event == "PLAYER_LOGOUT" then
1769 local t
1770 if self.db then
1771 t = self.db._table
1772 elseif FuBar then
1773 t = FuBarDB.pluginDB[self:GetTitle()]
1774 else
1775 return
1776 end
1777 if cleanDefaults(self.data, self.defaults) then
1778 if self.db then
1779 t.profiles[self.profilePath[2]] = nil
1780 else
1781 t.profiles[FuBar.profilePath[2]] = nil
1782 end
1783 if not next(t.profiles) then
1784 t.profiles = nil
1785 end
1786 end
1787 if cleanDefaults(self.charData, self.charDefaults) then
1788 if type(self.chardb) ~= "string" then
1789 t.chars[ace.char.realm .. ace.char.name] = nil
1790 if not next(t.chars) then
1791 t.chars = nil
1792 end
1793 else
1794 setglobal(self.chardb, nil)
1795 end
1796 end
1797 if cleanDefaults(self.fullData, self.fullDefaults) then
1798 t.full = nil
1799 end
1800 if cleanDefaults(self.realmData, self.realmDefaults) then
1801 t.realms[ace.char.realm .. ace.char.faction] = nil
1802 if not next(t.realms) then
1803 t.realms = nil
1804 end
1805 end
1806 if cleanDefaults(self.classData, self.classDefaults) then
1807 t.classes[ace.char.class] = nil
1808 if not next(t.classes) then
1809 t.classes = nil
1810 end
1811 end
1812 if not next(t) then
1813 if self.db then
1814 setglobal(self.db.name, nil)
1815 else
1816 FuBarDB.pluginDB[self:GetTitle()] = nil
1817 end
1818 end
1819 end
1820 end)
1821  
1822 AceAddon.RegisterForLoad(self)
1823 if FuBar then
1824 FuBar:RegisterPlugin(self)
1825 end
1826 end
1827  
1828 function lib:GetLibraryVersion()
1829 return MAJOR_VERSION, MINOR_VERSION
1830 end
1831  
1832 function lib:LibActivate(stub, oldLib, oldList)
1833 end
1834  
1835 function lib:LibDeactivate()
1836 end
1837  
1838 function lib:new(o)
1839 local mt = { __index = self }
1840 if type(o) ~= "table" then
1841 o = {}
1842 end
1843 return setmetatable(o, mt)
1844 end
1845  
1846 function lib:CreateBasicPluginFrame(name)
1847 local frame = CreateFrame("Button", name, UIParent)
1848 frame:SetFrameStrata("HIGH")
1849 frame:EnableMouse(true)
1850 frame:EnableMouseWheel(true)
1851 frame:SetMovable(true)
1852 frame:SetWidth(150)
1853 frame:SetHeight(24)
1854 frame:SetPoint("CENTER", UIParent, "CENTER")
1855  
1856 frame:SetScript("OnClick", function()
1857 if type(self.OnClick) == "function" then
1858 self:OnClick()
1859 end
1860 end)
1861 frame:SetScript("OnDoubleClick", function()
1862 if type(self.OnDoubleClick) == "function" then
1863 self:OnDoubleClick()
1864 end
1865 end)
1866 frame:SetScript("OnMouseDown", function()
1867 if arg1 == "RightButton" and not IsShiftKeyDown() and not IsControlKeyDown() and not IsAltKeyDown() then
1868 self:OpenMenu()
1869 return
1870 else
1871 HideDropDownMenu(1)
1872 if type(self.OnMouseDown) == "function" then
1873 self:OnMouseDown(arg1)
1874 end
1875 end
1876 end)
1877 frame:SetScript("OnMouseUp", function()
1878 if type(self.OnMouseUp) == "function" then
1879 self:OnMouseUp(arg1)
1880 end
1881 end)
1882 return frame
1883 end
1884  
1885 function lib:CreatePluginChildFrame(frameType, name, parent)
1886 assert(self.frame, "You must have self.frame declared in order to add child frames")
1887 local child = CreateFrame(frameType, name, parent)
1888 if parent then
1889 child:SetFrameLevel(parent:GetFrameLevel() + 2)
1890 end
1891 child:SetScript("OnEnter", function()
1892 if self.frame:GetScript("OnEnter") then
1893 self.frame:GetScript("OnEnter")()
1894 end
1895 end)
1896 child:SetScript("OnLeave", function()
1897 if self.frame:GetScript("OnLeave") then
1898 self.frame:GetScript("OnLeave")()
1899 end
1900 end)
1901 if child:HasScript("OnClick") then
1902 child:SetScript("OnClick", function()
1903 if self.frame:HasScript("OnClick") and self.frame:GetScript("OnClick") then
1904 self.frame:GetScript("OnClick")()
1905 end
1906 end)
1907 end
1908 if child:HasScript("OnDoubleClick") then
1909 child:SetScript("OnDoubleClick", function()
1910 if self.frame:HasScript("OnDoubleClick") and self.frame:GetScript("OnDoubleClick") then
1911 self.frame:GetScript("OnDoubleClick")()
1912 end
1913 end)
1914 end
1915 child:SetScript("OnMouseDown", function()
1916 if self.frame:GetScript("OnMouseDown") then
1917 self.frame:GetScript("OnMouseDown")()
1918 end
1919 end)
1920 child:SetScript("OnMouseUp", function()
1921 if self.frame:GetScript("OnMouseUp") then
1922 self.frame:GetScript("OnMouseUp")()
1923 end
1924 end)
1925 return child
1926 end
1927  
1928 function lib:OpenMenu(frame)
1929 if not frame then
1930 frame = self:GetFrame()
1931 end
1932 if dewdrop:IsOpen(frame) then
1933 dewdrop:Close()
1934 return
1935 end
1936 tablet:Close()
1937  
1938 if not dewdrop:IsRegistered(self:GetFrame()) then
1939 dewdrop:Register(self:GetFrame(),
1940 'children', function(level, value, valueN_1, valueN_2, valueN_3, valueN_4)
1941 if level == 1 then
1942 dewdrop:AddLine(
1943 'text', self:GetTitle(),
1944 'isTitle', true
1945 )
1946 end
1947  
1948 if self.MenuSettings then
1949 self:MenuSettings(level, value, false, valueN_1, valueN_2, valueN_3, valueN_4)
1950 end
1951  
1952 if level == 1 and not self.overrideMenu then
1953 if self.MenuSettings then
1954 dewdrop:AddLine()
1955 end
1956 self:AddImpliedMenuOptions()
1957 end
1958 if level == 1 then
1959 dewdrop:AddLine(
1960 'text', CLOSE,
1961 'func', dewdrop.Close,
1962 'arg1', dewdrop
1963 )
1964 end
1965 end,
1966 'point', function(frame)
1967 local x, y = frame:GetCenter()
1968 local leftRight
1969 if x < GetScreenWidth() / 2 then
1970 leftRight = "LEFT"
1971 else
1972 leftRight = "RIGHT"
1973 end
1974 if y < GetScreenHeight() / 2 then
1975 return "BOTTOM" .. leftRight, "TOP" .. leftRight
1976 else
1977 return "TOP" .. leftRight, "BOTTOM" .. leftRight
1978 end
1979 end,
1980 'dontHook', true
1981 )
1982 end
1983 if frame == self:GetFrame() then
1984 dewdrop:Open(self:GetFrame())
1985 else
1986 dewdrop:Open(frame, self:GetFrame())
1987 end
1988 end
1989  
1990 FuBarPlugin:Register(lib)
1991 lib = nil
1992  
1993 if not FuBarPlugin.new then
1994 function FuBarPlugin:new(o)
1995 FuBarPlugin:GetInstance(MAJOR_VERSION):assert(type(o) == "table", "You must provide a table to register")
1996 local name
1997 if o.name then
1998 name = o.name .. ": "
1999 else
2000 name = ""
2001 end
2002 FuBarPlugin:GetInstance(MAJOR_VERSION):assert(o.fuCompatible, name .. "You must provide a fuCompatible field.")
2003 local compatNumber = VersionToNumber(o.fuCompatible)
2004 if compatNumber >= 500 then
2005 compatNumber = compatNumber / 100
2006 end
2007 if compatNumber < 101 then
2008 return FuBarPlugin:GetInstance("1.0"):new(o)
2009 elseif compatNumber < 103 then
2010 return FuBarPlugin:GetInstance("1.2"):new(o)
2011 end
2012 end
2013 end
2014 end
2015  
2016 -- MinimapContainer
2017 do
2018 local lib = {}
2019  
2020 local initialized = false
2021 function lib:Initialize()
2022 if initialized then
2023 return
2024 end
2025 initialized = true
2026  
2027 self.plugins = {}
2028 end
2029  
2030 function lib:AddPlugin(plugin)
2031 if FuBar and FuBar:IsChangingProfile() then
2032 return
2033 end
2034 self:Initialize()
2035 if plugin.panel ~= nil then
2036 plugin.panel:RemovePlugin(plugin)
2037 end
2038 plugin.panel = self
2039 if not plugin.minimapFrame then
2040 local frame = CreateFrame("Button", plugin.frame:GetName() .. "MinimapButton", Minimap)
2041 plugin.minimapFrame = frame
2042 RegisterTablet(plugin)
2043 tablet:Register(frame, plugin.frame)
2044 frame.plugin = plugin
2045 frame:SetWidth(31)
2046 frame:SetHeight(31)
2047 frame:SetFrameStrata("HIGH")
2048 frame:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight")
2049 local icon = frame:CreateTexture(frame:GetName() .. "Icon", "BACKGROUND")
2050 plugin.minimapIcon = icon
2051 local path = plugin:GetIcon() or (plugin.iconFrame and plugin.iconFrame:GetTexture()) or "Interface\\Icons\\INV_Misc_QuestionMark"
2052 icon:SetTexture(path)
2053 if string.sub(path, 1, 16) == "Interface\\Icons\\" then
2054 icon:SetTexCoord(0.05, 0.95, 0.05, 0.95)
2055 else
2056 icon:SetTexCoord(0, 1, 0, 1)
2057 end
2058 icon:SetWidth(20)
2059 icon:SetHeight(20)
2060 icon:SetPoint("TOPLEFT", frame, "TOPLEFT", 7, -5)
2061 local overlay = frame:CreateTexture(frame:GetName() .. "Overlay","OVERLAY")
2062 overlay:SetTexture("Interface\\Minimap\\MiniMap-TrackingBorder")
2063 overlay:SetWidth(53)
2064 overlay:SetHeight(53)
2065 overlay:SetPoint("TOPLEFT",frame,"TOPLEFT")
2066 frame:EnableMouse(true)
2067 frame:RegisterForClicks("LeftButtonUp")
2068 frame.plugin = plugin
2069 if type(plugin.OnClick) == "function" then
2070 frame:SetScript("OnClick", function()
2071 if not this.dragged then
2072 plugin:OnClick(arg1)
2073 end
2074 end)
2075 end
2076 if type(plugin.OnDoubleClick) == "function" then
2077 frame:SetScript("OnDoubleClick", function()
2078 plugin:OnDoubleClick(arg1)
2079 end)
2080 end
2081 frame:SetScript("OnMouseDown", function()
2082 this.dragged = false
2083 if arg1 == "LeftButton" and not IsShiftKeyDown() and not IsControlKeyDown() and not IsAltKeyDown() then
2084 HideDropDownMenu(1)
2085 if type(plugin.OnMouseDown) == "function" then
2086 plugin:OnMouseDown(arg1)
2087 end
2088 elseif arg1 == "RightButton" and not IsShiftKeyDown() and not IsControlKeyDown() and not IsAltKeyDown() then
2089 plugin:OpenMenu(frame)
2090 else
2091 HideDropDownMenu(1)
2092 if type(plugin.OnMouseDown) == "function" then
2093 plugin:OnMouseDown(arg1)
2094 end
2095 end
2096 if plugin.OnClick or plugin.OnMouseDown or plugin.OnMouseUp or plugin.OnDoubleClick then
2097 if string.sub(this.plugin.minimapIcon:GetTexture(), 1, 16) == "Interface\\Icons\\" then
2098 plugin.minimapIcon:SetTexCoord(0.14, 0.86, 0.14, 0.86)
2099 else
2100 plugin.minimapIcon:SetTexCoord(0.1, 0.9, 0.1, 0.9)
2101 end
2102 end
2103 end)
2104 frame:SetScript("OnMouseUp", function()
2105 if not this.dragged and type(plugin.OnMouseUp) == "function" then
2106 plugin:OnMouseUp(arg1)
2107 end
2108 if string.sub(this.plugin.minimapIcon:GetTexture(), 1, 16) == "Interface\\Icons\\" then
2109 plugin.minimapIcon:SetTexCoord(0.05, 0.95, 0.05, 0.95)
2110 else
2111 plugin.minimapIcon:SetTexCoord(0, 1, 0, 1)
2112 end
2113 end)
2114 frame:RegisterForDrag("LeftButton")
2115 frame:SetScript("OnDragStart", self.OnDragStart)
2116 frame:SetScript("OnDragStop", self.OnDragStop)
2117 end
2118 plugin.frame:Hide()
2119 plugin.minimapFrame:Show()
2120 self:ReadjustLocation(plugin)
2121 table.insert(self.plugins, plugin)
2122 local exists = false
2123 return true
2124 end
2125  
2126 function lib:RemovePlugin(index)
2127 if FuBar and FuBar:IsChangingProfile() then
2128 return
2129 end
2130 self:Initialize()
2131 if type(index) == "table" then
2132 index = self:IndexOfPlugin(index)
2133 if not index then
2134 return
2135 end
2136 end
2137 local t = self.plugins
2138 local plugin = t[index]
2139 assert(plugin.panel == self, "Plugin has improper panel field")
2140 plugin:SetPanel(nil)
2141 table.remove(t, index)
2142 return true
2143 end
2144  
2145 function lib:ReadjustLocation(plugin)
2146 local frame = plugin.minimapFrame
2147 local position = plugin.data.minimapPosition or plugin.defaultMinimapPosition or math.random(1, 360)
2148 local angle = math.rad(position or 0)
2149 local x = math.cos(angle) * 80
2150 local y = math.sin(angle) * 80
2151 frame:SetPoint("CENTER", Minimap, "CENTER", x, y)
2152 end
2153  
2154 function lib:GetPlugin(index)
2155 return self.plugins[index]
2156 end
2157  
2158 function lib:GetNumPlugins()
2159 return table.getn(self.plugins)
2160 end
2161  
2162 function lib:IndexOfPlugin(plugin)
2163 for i,p in ipairs(self.plugins) do
2164 if p == plugin then
2165 return i, "MINIMAP"
2166 end
2167 end
2168 end
2169  
2170 function lib:HasPlugin(plugin)
2171 return self:IndexOfPlugin(plugin) ~= nil
2172 end
2173  
2174 function lib:GetPluginSide(plugin)
2175 local index = self:IndexOfPlugin(plugin)
2176 assert(index, "Plugin not in panel")
2177 return "MINIMAP"
2178 end
2179  
2180 function lib.OnDragStart()
2181 this.dragged = true
2182 this:LockHighlight()
2183 this:SetScript("OnUpdate", FuBarPlugin.MinimapContainer:GetInstance(MAJOR_VERSION).OnUpdate)
2184 if string.sub(this.plugin.minimapIcon:GetTexture(), 1, 16) == "Interface\\Icons\\" then
2185 this.plugin.minimapIcon:SetTexCoord(0.05, 0.95, 0.05, 0.95)
2186 else
2187 this.plugin.minimapIcon:SetTexCoord(0, 1, 0, 1)
2188 end
2189 end
2190  
2191 function lib.OnDragStop()
2192 this:SetScript("OnUpdate", nil)
2193 this:UnlockHighlight()
2194 end
2195  
2196 function lib.OnUpdate()
2197 local mx, my = Minimap:GetCenter()
2198 local px, py = GetCursorPosition()
2199 local scale = GetScreenHeight() / 768
2200 px, py = px * scale, py * scale
2201 local lastPosition = this.plugin.data.minimapPosition
2202 local position = math.deg(math.atan2(py - my, px - mx))
2203 if position <= 0 then
2204 position = position + 360
2205 elseif position > 360 then
2206 position = position - 360
2207 end
2208 this.plugin.data.minimapPosition = position
2209 FuBarPlugin.MinimapContainer:GetInstance(MAJOR_VERSION):ReadjustLocation(this.plugin)
2210 end
2211  
2212 function lib:GetLibraryVersion()
2213 return MAJOR_VERSION, MINOR_VERSION
2214 end
2215  
2216 function lib:LibActivate(stub, oldLib, oldList)
2217 end
2218  
2219 function lib:LibDeactivate()
2220 end
2221  
2222 FuBarPlugin.MinimapContainer:Register(lib)
2223 lib = nil
2224 end