vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 local MAJOR_VERSION = "1.0"
2 local MINOR_VERSION = tonumber(string.sub("$Revision: 2431 $", 12, -3))
3 local DEBUG = false
4 if TabletLib and TabletLib.versions[MAJOR_VERSION] and TabletLib.versions[MAJOR_VERSION].minor >= MINOR_VERSION then
5 return
6 end
7  
8 local SCROLL_UP, SCROLL_DOWN, HINT, DETACH, SIZE, CLOSE_MENU
9 if GetLocale() == "deDE" then
10 SCROLL_UP = "Hochscrolle"
11 SCROLL_DOWN = "Herunterscrolle"
12 HINT = "Hinweis"
13 DETACH = "L\195\182sen"
14 SIZE = "Größe"
15 CLOSE_MENU = "Menü schließen"
16 else
17 SCROLL_UP = "Scroll up"
18 SCROLL_DOWN = "Scroll down"
19 HINT = "Hint"
20 DETACH = "Detach"
21 SIZE = "Size"
22 CLOSE_MENU = "Close menu"
23 end
24  
25 -------------IRIEL'S-STUB-CODE--------------
26 local stub = {};
27  
28 -- Instance replacement method, replace contents of old with that of new
29 function stub:ReplaceInstance(old, new)
30 for k,v in pairs(old) do old[k]=nil; end
31 for k,v in pairs(new) do old[k]=v; end
32 end
33  
34 -- Get a new copy of the stub
35 function stub:NewStub()
36 local newStub = {};
37 self:ReplaceInstance(newStub, self);
38 newStub.lastVersion = '';
39 newStub.versions = {};
40 return newStub;
41 end
42  
43 -- Get instance version
44 function stub:GetInstance(version)
45 if (not version) then version = self.lastVersion; end
46 local versionData = self.versions[version];
47 if (not versionData) then
48 message("Cannot find library instance with version '"
49 .. version .. "'");
50 return;
51 end
52 return versionData.instance;
53 end
54  
55 -- Register new instance
56 function stub:Register(newInstance)
57 local version,minor = newInstance:GetLibraryVersion();
58 self.lastVersion = version;
59 local versionData = self.versions[version];
60 if (not versionData) then
61 -- This one is new!
62 versionData = { instance = newInstance,
63 minor = minor,
64 old = {}
65 };
66 self.versions[version] = versionData;
67 newInstance:LibActivate(self);
68 return newInstance;
69 end
70 if (minor <= versionData.minor) then
71 -- This one is already obsolete
72 if (newInstance.LibDiscard) then
73 newInstance:LibDiscard();
74 end
75 return versionData.instance;
76 end
77 -- This is an update
78 local oldInstance = versionData.instance;
79 local oldList = versionData.old;
80 versionData.instance = newInstance;
81 versionData.minor = minor;
82 local skipCopy = newInstance:LibActivate(self, oldInstance, oldList);
83 table.insert(oldList, oldInstance);
84 if (not skipCopy) then
85 for i, old in ipairs(oldList) do
86 self:ReplaceInstance(old, newInstance);
87 end
88 end
89 return newInstance;
90 end
91  
92 -- Bind stub to global scope if it's not already there
93 if (not TabletLib) then
94 TabletLib = stub:NewStub();
95 end
96  
97 -- Nil stub for garbage collection
98 stub = nil;
99 -----------END-IRIEL'S-STUB-CODE------------
100  
101 local function assert(condition, message)
102 if not condition then
103 local stack = debugstack()
104 local first = string.gsub(stack, "\n.*", "")
105 local file = string.gsub(first, "^(.*\\.*).lua:%d+: .*", "%1")
106 file = string.gsub(file, "([%(%)%.%*%+%-%[%]%?%^%$%%])", "%%%1")
107 if not message then
108 local _,_,second = string.find(stack, "\n(.-)\n")
109 message = "assertion failed! " .. second
110 end
111 message = "TabletLib: " .. message
112 local i = 1
113 for s in string.gfind(stack, "\n([^\n]*)") do
114 i = i + 1
115 if not string.find(s, file .. "%.lua:%d+:") then
116 error(message, i)
117 return
118 end
119 end
120 error(message, 2)
121 return
122 end
123 return condition
124 end
125  
126 local function argCheck(arg, num, kind, kind2, kind3, kind4)
127 if tostring(type(arg)) ~= kind then
128 if kind2 then
129 if tostring(type(arg)) ~= kind2 then
130 if kind3 then
131 if tostring(type(arg)) ~= kind3 then
132 if kind4 then
133 if tostring(type(arg)) ~= kind4 then
134 local _,_,func = string.find(debugstack(), "\n.-`(.-)'\n")
135 assert(false, format("Bad argument #%d to `%s' (%s, %s, %s, or %s expected, got %s)", num, func, kind, kind2, kind3, kind4, type(arg)))
136 end
137 else
138 local _,_,func = string.find(debugstack(), "\n.-`(.-)'\n")
139 assert(false, format("Bad argument #%d to `%s' (%s, %s, or %s expected, got %s)", num, func, kind, kind2, kind3, type(arg)))
140 end
141 end
142 else
143 local _,_,func = string.find(debugstack(), "\n.-`(.-)'\n")
144 assert(false, format("Bad argument #%d to `%s' (%s or %s expected, got %s)", num, func, kind, kind2, type(arg)))
145 end
146 end
147 else
148 local _,_,func = string.find(debugstack(), "\n.-`(.-)'\n")
149 assert(false, format("Bad argument #%d to `%s' (%s expected, got %s)", num, func, kind, type(arg)))
150 end
151 end
152 end
153  
154 local start = GetTime()
155 local wrap
156 local GetProfileInfo
157 if DEBUG then
158 local tree = {}
159 local treeMemories = {}
160 local treeTimes = {}
161 local memories = {}
162 local times = {}
163 function wrap(value, name)
164 if type(value) == "function" then
165 local oldFunction = value
166 memories[name] = 0
167 times[name] = 0
168 return function(self, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, a50, a51, a52, a53, a54, a55, a56, a57, a58, a59, a60)
169 local pos = table.getn(tree)
170 table.insert(tree, name)
171 table.insert(treeMemories, 0)
172 table.insert(treeTimes, 0)
173 local t, mem = GetTime(), gcinfo()
174 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, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, a50, a51, a52, a53, a54, a55, a56, a57, a58, a59, a60)
175 mem, t = gcinfo() - mem, GetTime() - t
176 if pos > 0 then
177 treeMemories[pos] = treeMemories[pos] + mem
178 treeTimes[pos] = treeTimes[pos] + t
179 end
180 local otherMem = table.remove(treeMemories)
181 if mem - otherMem > 0 then
182 memories[name] = memories[name] + mem - otherMem
183 end
184 times[name] = times[name] + t - table.remove(treeTimes)
185 table.remove(tree)
186 return r1, r2, r3, r4, r5, r6, r7, r8
187 end
188 end
189 end
190  
191 function GetProfileInfo()
192 return GetTime() - start, times, memories
193 end
194 else
195 function wrap(value)
196 return value
197 end
198 end
199  
200 local MIN_TOOLTIP_SIZE = 200
201 local lib = {}
202 local ipairs = ipairs
203 local tinsert = table.insert
204 local tremove = table.remove
205 local tgetn = table.getn
206 local function getsecond(_, value)
207 return value
208 end
209 local dewdrop
210 local sekeys
211 local CleanCategoryPool
212 local pool = {}
213 local function del(t)
214 if t then
215 if DEBUG and t[".poolprint"] then
216 print(t[".poolprint"])
217 end
218 for k in pairs(t) do
219 t[k] = nil
220 end
221 setmetatable(t, nil)
222 table.setn(t, 0)
223 table.insert(pool, t)
224 end
225 end
226  
227 local new
228  
229 local function copy(parent)
230 local t
231 if table.getn(pool) > 0 then
232 t = table.remove(pool)
233 else
234 t = {}
235 end
236 if parent then
237 for k,v in pairs(parent) do
238 t[k] = v
239 end
240 table.setn(t, table.getn(parent))
241 setmetatable(t, getmetatable(parent))
242 end
243 return t
244 end
245  
246 function new(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10, k11, v11, k12, v12, k13, v13, k14, v14, k15, v15, k16, v16, k17, v17, k18, v18, k19, v19, k20, v20, k21, v21, k22, v22, k23, v23, k24, v24, k25, v25, k26, v26, k27, v27, k28, v28, k29, v29, k30, v30)
247 local t
248 if table.getn(pool) > 0 then
249 t = table.remove(pool)
250 else
251 t = {}
252 end
253 if k1 then t[k1] = v1
254 if k2 then t[k2] = v2
255 if k3 then t[k3] = v3
256 if k4 then t[k4] = v4
257 if k5 then t[k5] = v5
258 if k6 then t[k6] = v6
259 if k7 then t[k7] = v7
260 if k8 then t[k8] = v8
261 if k9 then t[k9] = v9
262 if k10 then t[k10] = v10
263 if k11 then t[k11] = v11
264 if k12 then t[k12] = v12
265 if k13 then t[k13] = v13
266 if k14 then t[k14] = v14
267 if k15 then t[k15] = v15
268 if k16 then t[k16] = v16
269 if k17 then t[k17] = v17
270 if k18 then t[k18] = v18
271 if k19 then t[k19] = v19
272 if k20 then t[k20] = v20
273 if k21 then t[k21] = v21
274 if k22 then t[k22] = v22
275 if k23 then t[k23] = v23
276 if k24 then t[k24] = v24
277 if k25 then t[k25] = v25
278 if k26 then t[k26] = v26
279 if k27 then t[k27] = v27
280 if k28 then t[k28] = v28
281 if k29 then t[k29] = v29
282 if k30 then t[k30] = v30
283 end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end
284 return t
285 end
286 local tmp
287 tmp = setmetatable({}, {__index = function(self, key)
288 local t = {}
289 tmp[key] = function(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10, k11, v11, k12, v12, k13, v13, k14, v14, k15, v15, k16, v16, k17, v17, k18, v18, k19, v19, k20, v20, k21, v21, k22, v22, k23, v23, k24, v24, k25, v25, k26, v26, k27, v27, k28, v28, k29, v29, k30, v30)
290 for k in pairs(t) do
291 t[k] = nil
292 end
293 if k1 then t[k1] = v1
294 if k2 then t[k2] = v2
295 if k3 then t[k3] = v3
296 if k4 then t[k4] = v4
297 if k5 then t[k5] = v5
298 if k6 then t[k6] = v6
299 if k7 then t[k7] = v7
300 if k8 then t[k8] = v8
301 if k9 then t[k9] = v9
302 if k10 then t[k10] = v10
303 if k11 then t[k11] = v11
304 if k12 then t[k12] = v12
305 if k13 then t[k13] = v13
306 if k14 then t[k14] = v14
307 if k15 then t[k15] = v15
308 if k16 then t[k16] = v16
309 if k17 then t[k17] = v17
310 if k18 then t[k18] = v18
311 if k19 then t[k19] = v19
312 if k20 then t[k20] = v20
313 if k21 then t[k21] = v21
314 if k22 then t[k22] = v22
315 if k23 then t[k23] = v23
316 if k24 then t[k24] = v24
317 if k25 then t[k25] = v25
318 if k26 then t[k26] = v26
319 if k27 then t[k27] = v27
320 if k28 then t[k28] = v28
321 if k29 then t[k29] = v29
322 if k30 then t[k30] = v30
323 end end end end end end end end end end end end end end end end end end end end end end end end end end end end end end
324 return t
325 end
326 return tmp[key]
327 end})
328  
329 function lib:GetLibraryVersion()
330 return MAJOR_VERSION, MINOR_VERSION
331 end
332  
333 function lib:LibActivate(stub, oldLib, oldList)
334 if oldLib then
335 self.registry = oldLib.registry
336 self.onceRegistered = oldLib.onceRegistered
337 else
338 self.registry = {}
339 self.onceRegistered = {}
340 end
341 end
342  
343 function lib:LibDeactivate(stub)
344 end
345  
346 local _,headerSize = GameTooltipHeaderText:GetFont()
347 local _,normalSize = GameTooltipText:GetFont()
348 local tooltip
349 local testString
350 local TabletData = {}
351 local Category = {}
352 local Line = {}
353 do
354 local TabletData_mt = { __index = TabletData }
355 function TabletData:new(tablet)
356 if not testString then
357 testString = UIParent:CreateFontString()
358 testString:Hide()
359 end
360 local self = new()
361 self.categories = new()
362 self.id = 0
363 self.width = 0--(MIN_TOOLTIP_SIZE - 20)*tablet.fontSizePercent
364 self.tablet = tablet
365 self.title = "Title"
366 setmetatable(self, TabletData_mt)
367 return self
368 end
369  
370 function TabletData:del()
371 for k, v in ipairs(self.categories) do
372 v:del()
373 end
374 del(self.categories)
375 del(self)
376 end
377  
378 function TabletData:print(id)
379 printFull(id, self)
380 end
381  
382 function TabletData:Display()
383 if self.tablet == tooltip then
384 local info = new(
385 'hideBlankLine', true,
386 'text', self.title,
387 'justify', "CENTER",
388 'font', GameTooltipHeaderText,
389 'isTitle', true
390 )
391 self:AddCategory(info, 1)
392 del(info)
393 if self.hint then
394 self:AddCategory(nil):AddLine(
395 'text', HINT .. ": " .. self.hint,
396 'textR', 0,
397 'textG', 1,
398 'textB', 0,
399 'wrap', true
400 )
401 end
402 end
403  
404 local tabletData = self.tabletData
405 local width
406 for k, v in ipairs(self.categories) do
407 if v.columns <= 2 then
408 width = v.x1
409 else
410 width = v.x1 + v.x2 + v.x3 + v.x4 + v.x5 + v.x6 + (v.columns - 1) * 20
411 end
412 if self.width < width then
413 self.width = width
414 end
415 end
416  
417 local good = false
418 local lastTitle = true
419 for k, v in ipairs(self.categories) do
420 if lastTitle then
421 v.hideBlankLine = true
422 lastTitle = false
423 end
424 if v:Display(self.tablet) then
425 good = true
426 end
427 if v.isTitle then
428 lastTitle = true
429 end
430 end
431 if not good then
432 local width
433 local info = new(
434 'hideBlankLine', true,
435 'text', self.title,
436 'justify', "CENTER",
437 'font', GameTooltipHeaderText,
438 'isTitle', true
439 )
440 local cat = self:AddCategory(info)
441 del(info)
442 self.width = self.categories[table.getn(self.categories)].x1
443 cat:Display(self.tablet)
444 end
445 end
446  
447 function TabletData:AddCategory(info, index)
448 local made = false
449 if not info then
450 made = true
451 info = new()
452 end
453 local cat = Category:new(self, info)
454 if index then
455 table.insert(self.categories, index, cat)
456 else
457 table.insert(self.categories, cat)
458 end
459 if made then
460 del(info)
461 end
462 return cat
463 end
464  
465 function TabletData:SetHint(hint)
466 self.hint = hint
467 end
468  
469 function TabletData:SetTitle(title)
470 self.title = title or "Title"
471 end
472 end
473 do
474 local Category_mt = { __index = Category }
475 function Category:new(tabletData, info, superCategory)
476 local self = copy(info)
477 if superCategory and not self.noInherit then
478 self.superCategory = superCategory.superCategory
479 for k, v in pairs(superCategory) do
480 if string.find(k, "^child_") then
481 local k = strsub(k, 7)
482 if self[k] == nil then
483 self[k] = v
484 end
485 end
486 end
487 self.columns = superCategory.columns
488 else
489 self.superCategory = self
490 end
491 self.tabletData = tabletData
492 self.lines = new()
493 if not self.columns then
494 self.columns = 1
495 end
496 self.x1 = 0
497 self.x2 = 0
498 self.x3 = 0
499 self.x4 = 0
500 self.x5 = 0
501 self.x6 = 0
502 setmetatable(self, Category_mt)
503 self.lastWasTitle = nil
504 if self.text or self.text2 or self.text3 or self.text4 or self.text5 or self.text6 then
505 local x = new(
506 'category', category,
507 'text', self.text,
508 'textR', self.textR or 1,
509 'textG', self.textG or 1,
510 'textB', self.textB or 1,
511 'fakeChild', true,
512 'func', self.func,
513 'arg1', info.arg1,
514 'arg2', self.arg2,
515 'arg3', self.arg3,
516 'hasCheck', self.hasCheck,
517 'checked', self.checked,
518 'checkIcon', self.checkIcon,
519 'isRadio', self.isRadio,
520 'font', self.font,
521 'size', self.size,
522 'wrap', self.wrap,
523 'catStart', true,
524 'indentation', self.indentation,
525 'noInherit', true,
526 'justify', self.justify,
527 'justify2', self.justify2,
528 'justify3', self.justify3,
529 'justify4', self.justify4,
530 'justify5', self.justify5,
531 'justify6', self.justify6
532 )
533 if self.isTitle then
534 x.textR = self.textR or 1
535 x.textG = self.textG or 0.823529
536 x.textB = self.textB or 0
537 else
538 x.textR = self.textR or 1
539 x.textG = self.textG or 1
540 x.textB = self.textB or 1
541 end
542 x.text2 = self.text2
543 x.text3 = self.text3
544 x.text4 = self.text4
545 x.text5 = self.text5
546 x.text6 = self.text6
547 x.text2R = self.text2R or self.textR2 or 1
548 x.text2G = self.text2G or self.textG2 or 1
549 x.text2B = self.text2B or self.textB2 or 1
550 x.text3R = self.text3R or self.textR3 or 1
551 x.text3G = self.text3G or self.textG3 or 1
552 x.text3B = self.text3B or self.textB3 or 1
553 x.text4R = self.text4R or self.textR4 or 1
554 x.text4G = self.text4G or self.textG4 or 1
555 x.text4B = self.text4B or self.textB4 or 1
556 x.text5R = self.text5R or self.textR5 or 1
557 x.text5G = self.text5G or self.textG5 or 1
558 x.text5B = self.text5B or self.textB5 or 1
559 x.text6R = self.text6R or self.textR6 or 1
560 x.text6G = self.text6G or self.textG6 or 1
561 x.text6B = self.text6B or self.textB6 or 1
562 x.font2 = self.font2
563 x.font3 = self.font3
564 x.font4 = self.font4
565 x.font5 = self.font5
566 x.font6 = self.font6
567 x.size2 = self.size2
568 x.size3 = self.size3
569 x.size4 = self.size4
570 x.size5 = self.size5
571 x.size6 = self.size6
572 self:AddLine(x)
573 del(x)
574 self.lastWasTitle = true
575 end
576 return self
577 end
578  
579 function Category:del()
580 local prev = garbageLine
581 for k, v in pairs(self.lines) do
582 v:del()
583 end
584 del(self.lines)
585 del(self)
586 end
587  
588 function Category:AddLine(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10, k11, v11, k12, v12, k13, v13, k14, v14, k15, v15, k16, v16, k17, v17, k18, v18, k19, v19, k20, v20, k21, v21, k22, v22, k23, v23, k24, v24, k25, v25, k26, v26, k27, v27, k28, v28, k29, v29, k30, v30)
589 self.lastWasTitle = nil
590 local line
591 if type(k1) == "table" then
592 Line:new(self, k1, v1)
593 else
594 local info = new(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10, k11, v11, k12, v12, k13, v13, k14, v14, k15, v15, k16, v16, k17, v17, k18, v18, k19, v19, k20, v20, k21, v21, k22, v22, k23, v23, k24, v24, k25, v25, k26, v26, k27, v27, k28, v28, k29, v29, k30, v30)
595 Line:new(self, info)
596 del(info)
597 end
598 end
599  
600 function Category:AddCategory(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10, k11, v11, k12, v12, k13, v13, k14, v14, k15, v15, k16, v16, k17, v17, k18, v18, k19, v19, k20, v20, k21, v21, k22, v22, k23, v23, k24, v24, k25, v25, k26, v26, k27, v27, k28, v28, k29, v29, k30, v30)
601 local lastWasTitle = self.lastWasTitle
602 self.lastWasTitle = nil
603 local info
604 if type(k1) == "table" then
605 info = k1
606 else
607 info = new(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10, k11, v11, k12, v12, k13, v13, k14, v14, k15, v15, k16, v16, k17, v17, k18, v18, k19, v19, k20, v20, k21, v21, k22, v22, k23, v23, k24, v24, k25, v25, k26, v26, k27, v27, k28, v28, k29, v29, k30, v30)
608 end
609 if lastWasTitle or table.getn(self.lines) == 0 then
610 info.hideBlankLine = true
611 end
612 local cat = Category:new(self.tabletData, info, self)
613 table.insert(self.lines, cat)
614 return cat
615 end
616  
617 function Category:HasChildren()
618 local hasChildren = false
619 for k, v in ipairs(self.lines) do
620 if v.HasChildren then
621 if v:HasChildren() then
622 return true
623 end
624 end
625 if not v.fakeChild then
626 return true
627 end
628 end
629 return false
630 end
631  
632 local lastWasTitle = false
633 function Category:Display(tablet)
634 if not self.isTitle and not self.showWithoutChildren and not self:HasChildren() then
635 return false
636 end
637 if not self.hideBlankLine and not lastWasTitle then
638 local info = new(
639 'blank', true,
640 'fakeChild', true
641 )
642 self:AddLine(info, 1)
643 del(info)
644 end
645 local good = false
646 if table.getn(self.lines) > 0 then
647 self.tabletData.id = self.tabletData.id + 1
648 self.id = self.tabletData.id
649 for k, v in ipairs(self.lines) do
650 if v:Display(tablet) then
651 good = true
652 end
653 end
654 end
655 lastWasTitle = self.isTitle
656 return good
657 end
658 end
659 do
660 local Line_mt = { __index = Line }
661 function Line:new(category, info, position)
662 local self = copy(info)
663 if not info.noInherit then
664 for k, v in pairs(category) do
665 if string.find(k, "^child_") then
666 local k = strsub(k, 7)
667 if self[k] == nil then
668 self[k] = v
669 end
670 end
671 end
672 end
673 self.category = category
674 if position then
675 table.insert(category.lines, position, self)
676 else
677 table.insert(category.lines, self)
678 end
679 setmetatable(self, Line_mt)
680 local columns = category.columns
681 if columns == 1 then
682 if not self.justify then
683 self.justify = "LEFT"
684 end
685 elseif columns == 2 then
686 self.justify = "LEFT"
687 self.justify2 = "RIGHT"
688 if self.wrap then
689 self.wrap2 = false
690 end
691 elseif columns == 3 then
692 if not self.justify then
693 self.justify = "LEFT"
694 end
695 if not self.justify2 then
696 self.justify2 = "CENTER"
697 end
698 if not self.justify3 then
699 self.justify3 = "RIGHT"
700 end
701 if self.wrap then
702 self.wrap2 = false
703 self.wrap3 = false
704 elseif self.wrap2 then
705 self.wrap3 = false
706 end
707 elseif columns == 4 then
708 if not self.justify then
709 self.justify = "LEFT"
710 end
711 if not self.justify2 then
712 self.justify2 = "CENTER"
713 end
714 if not self.justify3 then
715 self.justify3 = "CENTER"
716 end
717 if not self.justify4 then
718 self.justify4 = "RIGHT"
719 end
720 if self.wrap then
721 self.wrap2 = false
722 self.wrap3 = false
723 self.wrap4 = false
724 elseif self.wrap2 then
725 self.wrap3 = false
726 self.wrap4 = false
727 elseif self.wrap3 then
728 self.wrap4 = false
729 end
730 elseif columns == 5 then
731 if not self.justify then
732 self.justify = "LEFT"
733 end
734 if not self.justify2 then
735 self.justify2 = "CENTER"
736 end
737 if not self.justify3 then
738 self.justify3 = "CENTER"
739 end
740 if not self.justify4 then
741 self.justify4 = "CENTER"
742 end
743 if not self.justify5 then
744 self.justify5 = "RIGHT"
745 end
746 if self.wrap then
747 self.wrap2 = false
748 self.wrap3 = false
749 self.wrap4 = false
750 self.wrap5 = false
751 elseif self.wrap2 then
752 self.wrap3 = false
753 self.wrap4 = false
754 self.wrap5 = false
755 elseif self.wrap3 then
756 self.wrap4 = false
757 self.wrap5 = false
758 elseif self.wrap4 then
759 self.wrap5 = false
760 end
761 elseif columns == 6 then
762 if not self.justify then
763 self.justify = "LEFT"
764 end
765 if not self.justify2 then
766 self.justify2 = "CENTER"
767 end
768 if not self.justify3 then
769 self.justify3 = "CENTER"
770 end
771 if not self.justify4 then
772 self.justify4 = "CENTER"
773 end
774 if not self.justify5 then
775 self.justify5 = "CENTER"
776 end
777 if not self.justify6 then
778 self.justify6 = "RIGHT"
779 end
780 if self.wrap then
781 self.wrap2 = false
782 self.wrap3 = false
783 self.wrap4 = false
784 self.wrap5 = false
785 self.wrap6 = false
786 elseif self.wrap2 then
787 self.wrap3 = false
788 self.wrap4 = false
789 self.wrap5 = false
790 self.wrap6 = false
791 elseif self.wrap3 then
792 self.wrap4 = false
793 self.wrap5 = false
794 self.wrap6 = false
795 elseif self.wrap4 then
796 self.wrap5 = false
797 self.wrap6 = false
798 elseif self.wrap5 then
799 self.wrap6 = false
800 end
801 end
802 if self.textR2 then
803 self.text2R, self.textR2 = self.text2R or self.textR2
804 self.text2G, self.textG2 = self.text2G or self.textG2
805 self.text2B, self.textB2 = self.text2B or self.textB2
806 if self.textR3 then
807 self.text3R, self.textR3 = self.text3R or self.textR3
808 self.text3G, self.textG3 = self.text3G or self.textG3
809 self.text3B, self.textB3 = self.text3B or self.textB3
810 if self.textR4 then
811 self.text4R, self.textR4 = self.text4R or self.textR4
812 self.text4G, self.textG4 = self.text4G or self.textG4
813 self.text4B, self.textB4 = self.text4B or self.textB4
814 if self.textR5 then
815 self.text5R, self.textR5 = self.text5R or self.textR5
816 self.text5G, self.textG5 = self.text5G or self.textG5
817 self.text5B, self.textB5 = self.text5B or self.textB5
818 if self.textR5 then
819 self.text6R, self.textR6 = self.text6R or self.textR6
820 self.text6G, self.textG6 = self.text6G or self.textG6
821 self.text6B, self.textB6 = self.text6B or self.textB6
822 end
823 end
824 end
825 end
826 end
827 if not self.indentation or self.indentation < 0 then
828 self.indentation = 0
829 end
830 if not self.font then
831 self.font = GameTooltipText
832 end
833 if not self.font2 then
834 self.font2 = self.font
835 end
836 if not self.font3 then
837 self.font3 = self.font
838 end
839 if not self.font4 then
840 self.font4 = self.font
841 end
842 if not self.font5 then
843 self.font5 = self.font
844 end
845 if not self.font6 then
846 self.font6 = self.font
847 end
848 if not self.size then
849 _,self.size = self.font:GetFont()
850 end
851 if not self.size2 then
852 _,self.size2 = self.font2:GetFont()
853 end
854 if not self.size3 then
855 _,self.size3 = self.font3:GetFont()
856 end
857 if not self.size4 then
858 _,self.size4 = self.font4:GetFont()
859 end
860 if not self.size5 then
861 _,self.size5 = self.font5:GetFont()
862 end
863 if not self.size6 then
864 _,self.size6 = self.font6:GetFont()
865 end
866  
867 local fontSizePercent = category.tabletData.tablet.fontSizePercent
868 local w = 0
869 if self.text then
870 if not self.wrap then
871 testString:SetWidth(0)
872 testString:SetFontObject(self.font)
873 local font,_,flags = testString:GetFont()
874 testString:SetFont(font, self.size * fontSizePercent, flags)
875 testString:SetText(self.text)
876 local checkWidth = self.hasCheck and self.size * fontSizePercent or 0
877 w = testString:GetWidth() + self.indentation * fontSizePercent
878 if self.hasCheck then
879 w = w + self.size
880 end
881 if category.superCategory.x1 < w then
882 category.superCategory.x1 = w
883 end
884 else
885 if columns == 1 then
886 testString:SetWidth(0)
887 testString:SetFontObject(self.font)
888 local font,_,flags = testString:GetFont()
889 testString:SetFont(font, self.size * fontSizePercent, flags)
890 testString:SetText(self.text)
891 local checkWidth = self.hasCheck and self.size * fontSizePercent or 0
892 w = testString:GetWidth() + self.indentation * fontSizePercent
893 if self.hasCheck then
894 w = w + self.size
895 end
896 if w > (MIN_TOOLTIP_SIZE - 20) * fontSizePercent then
897 w = (MIN_TOOLTIP_SIZE - 20) * fontSizePercent
898 end
899 else
900 w = MIN_TOOLTIP_SIZE * fontSizePercent / 2
901 end
902 if category.superCategory.x1 < w then
903 category.superCategory.x1 = w
904 end
905 end
906 end
907 if columns == 2 and self.text2 then
908 if not self.wrap2 then
909 testString:SetWidth(0)
910 testString:SetFontObject(self.font2)
911 local font,_,flags = testString:GetFont()
912 testString:SetFont(font, self.size2 * fontSizePercent, flags)
913 testString:SetText(self.text2)
914 w = w + 40 * fontSizePercent + testString:GetWidth()
915 if category.superCategory.x1 < w then
916 category.superCategory.x1 = w
917 end
918 else
919 w = w + 40 * fontSizePercent + MIN_TOOLTIP_SIZE * fontSizePercent / 2
920 if category.superCategory.x1 < w then
921 category.superCategory.x1 = w
922 end
923 end
924 elseif columns >= 3 then
925 if self.text2 then
926 if not self.wrap2 then
927 testString:SetWidth(0)
928 testString:SetFontObject(self.font2)
929 local font,_,flags = testString:GetFont()
930 testString:SetFont(font, self.size2 * fontSizePercent, flags)
931 testString:SetText(self.text2)
932 local w = testString:GetWidth()
933 if category.superCategory.x2 < w then
934 category.superCategory.x2 = w
935 end
936 else
937 local w = MIN_TOOLTIP_SIZE / 2
938 if category.superCategory.x2 < w then
939 category.superCategory.x2 = w
940 end
941 end
942 end
943 if self.text3 then
944 if not self.wrap3 then
945 testString:SetWidth(0)
946 testString:SetFontObject(self.font3)
947 local font,_,flags = testString:GetFont()
948 testString:SetFont(font, self.size3 * fontSizePercent, flags)
949 testString:SetText(self.text3)
950 local w = testString:GetWidth()
951 if category.superCategory.x3 < w then
952 category.superCategory.x3 = w
953 end
954 else
955 local w = MIN_TOOLTIP_SIZE / 2
956 if category.superCategory.x3 < w then
957 category.superCategory.x3 = w
958 end
959 end
960 end
961 if columns >= 4 then
962 if self.text4 then
963 if not self.wrap4 then
964 testString:SetWidth(0)
965 testString:SetFontObject(self.font4)
966 local font,_,flags = testString:GetFont()
967 testString:SetFont(font, self.size4 * fontSizePercent, flags)
968 testString:SetText(self.text4)
969 w = testString:GetWidth()
970 if category.superCategory.x4 < w then
971 category.superCategory.x4 = w
972 end
973 else
974 local w = MIN_TOOLTIP_SIZE / 2
975 if category.superCategory.x4 < w then
976 category.superCategory.x4 = w
977 end
978 end
979 end
980 if columns >= 5 then
981 if self.text5 then
982 if not self.wrap5 then
983 testString:SetWidth(0)
984 testString:SetFontObject(self.font5)
985 local font,_,flags = testString:GetFont()
986 testString:SetFont(font, self.size5 * fontSizePercent, flags)
987 testString:SetText(self.text5)
988 w = testString:GetWidth()
989 if category.superCategory.x5 < w then
990 category.superCategory.x5 = w
991 end
992 else
993 local w = MIN_TOOLTIP_SIZE / 2
994 if category.superCategory.x5 < w then
995 category.superCategory.x5 = w
996 end
997 end
998 end
999 if columns >= 6 then
1000 if self.text6 then
1001 if not self.wrap6 then
1002 testString:SetWidth(0)
1003 testString:SetFontObject(self.font6)
1004 local font,_,flags = testString:GetFont()
1005 testString:SetFont(font, self.size6 * fontSizePercent, flags)
1006 testString:SetText(self.text6)
1007 w = testString:GetWidth()
1008 if category.superCategory.x6 < w then
1009 category.superCategory.x6 = w
1010 end
1011 else
1012 local w = MIN_TOOLTIP_SIZE / 2
1013 if category.superCategory.x6 < w then
1014 category.superCategory.x6 = w
1015 end
1016 end
1017 end
1018 end
1019 end
1020 end
1021 end
1022 return self
1023 end
1024  
1025 function Line:del()
1026 del(self)
1027 end
1028  
1029 function Line:Display(tablet)
1030 tablet:AddLine(self)
1031 return true
1032 end
1033 end
1034  
1035 local function button_OnEnter()
1036 if this.self:GetScript("OnEnter") then
1037 this.self:GetScript("OnEnter")()
1038 end
1039 this.highlight:Show()
1040 end
1041  
1042 local function button_OnLeave()
1043 if this.self:GetScript("OnLeave") then
1044 this.self:GetScript("OnLeave")()
1045 end
1046 this.highlight:Hide()
1047 end
1048  
1049 local function NewLine(self)
1050 if self.maxLines <= self.numLines then
1051 self.maxLines = self.maxLines + 1
1052 local button = CreateFrame("Button", nil, self)
1053 button.indentation = 0
1054 local check = button:CreateTexture(nil, "ARTWORK")
1055 local left = button:CreateFontString(nil, "ARTWORK")
1056 local right = button:CreateFontString(nil, "ARTWORK")
1057 local third = button:CreateFontString(nil, "ARTWORK")
1058 local fourth = button:CreateFontString(nil, "ARTWORK")
1059 local fifth = button:CreateFontString(nil, "ARTWORK")
1060 local sixth = button:CreateFontString(nil, "ARTWORK")
1061 local highlight = button:CreateTexture(nil, "BACKGROUND")
1062 highlight:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
1063 button.highlight = highlight
1064 highlight:SetBlendMode("ADD")
1065 highlight:SetAllPoints(button)
1066 highlight:Hide()
1067 table.insert(self.buttons, button)
1068 table.insert(self.checks, check)
1069 table.insert(self.lefts, left)
1070 table.insert(self.rights, right)
1071 table.insert(self.thirds, third)
1072 table.insert(self.fourths, fourth)
1073 table.insert(self.fifths, fifth)
1074 table.insert(self.sixths, sixth)
1075 left:SetWidth(0)
1076 if self.maxLines == 1 then
1077 left:SetFontObject(GameTooltipHeaderText)
1078 right:SetFontObject(GameTooltipHeaderText)
1079 third:SetFontObject(GameTooltipHeaderText)
1080 fourth:SetFontObject(GameTooltipHeaderText)
1081 fifth:SetFontObject(GameTooltipHeaderText)
1082 sixth:SetFontObject(GameTooltipHeaderText)
1083 left:SetJustifyH("CENTER")
1084 button:SetPoint("TOPLEFT", self, "TOPLEFT", 8, -10)
1085 else
1086 left:SetFontObject(GameTooltipText)
1087 right:SetFontObject(GameTooltipText)
1088 third:SetFontObject(GameTooltipText)
1089 fourth:SetFontObject(GameTooltipText)
1090 fifth:SetFontObject(GameTooltipText)
1091 sixth:SetFontObject(GameTooltipText)
1092 button:SetPoint("TOPLEFT", self.buttons[self.maxLines - 1], "BOTTOMLEFT", 0, -2)
1093 end
1094 button:SetScript("OnEnter", button_OnEnter)
1095 button:SetScript("OnLeave", button_OnLeave)
1096 button.check = check
1097 button.self = self
1098 button:SetPoint("RIGHT", self, "RIGHT", -12, 0)
1099 check.shown = false
1100 check:SetPoint("TOPLEFT", button, "TOPLEFT")
1101 left:SetPoint("TOPLEFT", check, "TOPLEFT")
1102 right:SetPoint("TOPLEFT", left, "TOPRIGHT", 40 * self.fontSizePercent, 0)
1103 third:SetPoint("TOPLEFT", right, "TOPRIGHT", 20 * self.fontSizePercent, 0)
1104 fourth:SetPoint("TOPLEFT", third, "TOPRIGHT", 20 * self.fontSizePercent, 0)
1105 fifth:SetPoint("TOPLEFT", fourth, "TOPRIGHT", 20 * self.fontSizePercent, 0)
1106 sixth:SetPoint("TOPLEFT", fifth, "TOPRIGHT", 20 * self.fontSizePercent, 0)
1107 right:SetJustifyH("RIGHT")
1108 local _,size = GameTooltipText:GetFont()
1109 check:SetHeight(size * 1.5)
1110 check:SetWidth(size * 1.5)
1111 check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
1112 check:SetAlpha(0)
1113 if not button.clicked then
1114 button:SetScript("OnMouseWheel", self:GetScript("OnMouseWheel"))
1115 button:EnableMouseWheel(true)
1116 button:Hide()
1117 end
1118 check:Show()
1119 left:Hide()
1120 right:Hide()
1121 third:Hide()
1122 fourth:Hide()
1123 fifth:Hide()
1124 sixth:Hide()
1125 end
1126 end
1127 NewLine = wrap(NewLine, "NewLine")
1128  
1129 local function GetMaxLinesPerScreen(self)
1130 if self == tooltip then
1131 return floor(50 / self.fontSizePercent)
1132 else
1133 return floor(30 / self.fontSizePercent)
1134 end
1135 end
1136 GetMaxLinesPerScreen = wrap(GetMaxLinesPerScreen, "GetMaxLinesPerScreen")
1137  
1138 local detachedTooltips = {}
1139 local AcquireDetachedFrame, ReleaseDetachedFrame
1140 local function AcquireFrame(self, registration, data, detachedData)
1141 if not detachedData then
1142 detachedData = data
1143 end
1144 if tooltip then
1145 tooltip.data = data
1146 tooltip.detachedData = detachedData
1147 local fontSizePercent = tooltip.data and tooltip.data.fontSizePercent or 1
1148 local transparency = tooltip.data and tooltip.data.transparency or 0.75
1149 local r = tooltip.data and tooltip.data.r or 0
1150 local g = tooltip.data and tooltip.data.g or 0
1151 local b = tooltip.data and tooltip.data.b or 0
1152 tooltip:SetFontSizePercent(fontSizePercent)
1153 tooltip:SetTransparency(transparency)
1154 tooltip:SetColor(r, g, b)
1155 else
1156 tooltip = CreateFrame("Frame", "TabletLibFrame", UIParent)
1157 tooltip.data = data
1158 tooltip.detachedData = detachedData
1159 tooltip:EnableMouse(true)
1160 tooltip:EnableMouseWheel(true)
1161 tooltip:SetFrameStrata("TOOLTIP")
1162 tooltip:SetFrameLevel(10)
1163 local backdrop = new(
1164 'bgFile', "Interface\\Buttons\\WHITE8X8",
1165 'edgeFile', "Interface\\Tooltips\\UI-Tooltip-Border",
1166 'tile', true,
1167 'tileSize', 16,
1168 'edgeSize', 16,
1169 'insets', new(
1170 'left', 5,
1171 'right', 5,
1172 'top', 5,
1173 'bottom', 5
1174 )
1175 )
1176 tooltip:SetBackdrop(backdrop)
1177 del(backdrop.insets)
1178 del(backdrop)
1179 tooltip:SetBackdropColor(0, 0, 0, 1)
1180  
1181 tooltip.numLines = 0
1182 tooltip.owner = nil
1183 tooltip.fontSizePercent = tooltip.data and tooltip.data.fontSizePercent or 1
1184 tooltip.maxLines = 0
1185 tooltip.buttons = {}
1186 tooltip.checks = {}
1187 tooltip.lefts = {}
1188 tooltip.rights = {}
1189 tooltip.thirds = {}
1190 tooltip.fourths = {}
1191 tooltip.fifths = {}
1192 tooltip.sixths = {}
1193 tooltip.transparency = tooltip.data and tooltip.data.transparency or 0.75
1194 tooltip:SetBackdropColor(0, 0, 0, tooltip.transparency)
1195 tooltip:SetBackdropBorderColor(1, 1, 1, tooltip.transparency)
1196 tooltip.scroll = 0
1197  
1198 tooltip:SetScript("OnUpdate", function()
1199 if not tooltip.updating and not tooltip.enteredFrame then
1200 tooltip.scroll = 0
1201 tooltip:Hide()
1202 tooltip.registration.tooltip = nil
1203 tooltip.registration = nil
1204 end
1205 end)
1206  
1207 tooltip:SetScript("OnEnter", function()
1208 if tooltip.clickable then
1209 tooltip.enteredFrame = true
1210 end
1211 end)
1212  
1213 tooltip:SetScript("OnLeave", function()
1214 if not tooltip.updating then
1215 tooltip.enteredFrame = false
1216 end
1217 end)
1218  
1219 tooltip:SetScript("OnMouseWheel", function()
1220 tooltip.updating = true
1221 tooltip:Scroll(arg1 < 0)
1222 tooltip.updating = false
1223 end)
1224  
1225 NewLine(tooltip)
1226  
1227 tooltip.scrollUp = tooltip:CreateFontString(nil, "ARTWORK")
1228 tooltip.scrollUp:SetPoint("TOPLEFT", tooltip.buttons[1], "BOTTOMLEFT", 0, -2)
1229 tooltip.scrollUp:SetPoint("RIGHT", tooltip, "RIGHT", 0, -10)
1230 tooltip.scrollUp:SetFontObject(GameTooltipText)
1231 tooltip.scrollUp:Hide()
1232 local font,_,flags = tooltip.scrollUp:GetFont()
1233 tooltip.scrollUp:SetFont(font, normalSize * tooltip.fontSizePercent, flags)
1234 tooltip.scrollUp:SetJustifyH("CENTER")
1235 tooltip.scrollUp:SetTextColor(1, 0.823529, 0)
1236 tooltip.scrollUp:SetText(" ")
1237  
1238 tooltip.scrollDown = tooltip:CreateFontString(nil, "ARTWORK")
1239 tooltip.scrollDown:SetPoint("TOPLEFT", tooltip.buttons[1], "BOTTOMLEFT", 0, -2)
1240 tooltip.scrollDown:SetPoint("RIGHT", tooltip, "RIGHT", 0, -10)
1241 tooltip.scrollDown:SetFontObject(GameTooltipText)
1242 tooltip.scrollDown:Hide()
1243 local font,_,flags = tooltip.scrollUp:GetFont()
1244 tooltip.scrollDown:SetFont(font, normalSize * tooltip.fontSizePercent, flags)
1245 tooltip.scrollDown:SetJustifyH("CENTER")
1246 tooltip.scrollDown:SetTextColor(1, 0.823529, 0)
1247 tooltip.scrollDown:SetText(" ")
1248  
1249 function tooltip:SetOwner(o)
1250 self:Hide(o)
1251 self.owner = o
1252 end
1253 tooltip.SetOwner = wrap(tooltip.SetOwner, "tooltip:SetOwner")
1254  
1255 function tooltip:IsOwned(o)
1256 return self.owner == o
1257 end
1258 tooltip.IsOwned = wrap(tooltip.IsOwned, "tooltip:IsOwned")
1259  
1260 function tooltip:ClearLines(hide)
1261 CleanCategoryPool(self)
1262 for i = 1, self.numLines do
1263 local button = self.buttons[i]
1264 local check = self.checks[i]
1265 if not button.clicked or hide then
1266 button:Hide()
1267 end
1268 check.shown = false
1269 check:SetAlpha(0)
1270 end
1271 self.numLines = 0
1272 end
1273 tooltip.ClearLines = wrap(tooltip.ClearLines, "tooltip:ClearLines")
1274  
1275 function tooltip:NumLines()
1276 return self.numLines
1277 end
1278  
1279 local lastWidth
1280 local old_tooltip_Hide = tooltip.Hide
1281 function tooltip:Hide(newOwner)
1282 if self == tooltip or newOwner == nil then
1283 old_tooltip_Hide(self)
1284 end
1285 self:ClearLines(true)
1286 self.owner = nil
1287 self.lastWidth = nil
1288 end
1289 tooltip.Hide = wrap(tooltip.Hide, "tooltip:Hide")
1290  
1291 local old_tooltip_Show = tooltip.Show
1292 function tooltip:Show(tabletData)
1293 if self.owner == nil or self.notInUse then
1294 return
1295 end
1296 old_tooltip_Show(self)
1297  
1298 local maxWidth = tabletData and tabletData.width or self:GetWidth() - 20
1299 local hasWrap = false
1300 local screenWidth = GetScreenWidth()
1301 local scrollMax = self.numLines
1302 if scrollMax > GetMaxLinesPerScreen(self) + self.scroll then
1303 scrollMax = GetMaxLinesPerScreen(self) + self.scroll
1304 end
1305 local numColumns
1306  
1307 local height = 20
1308 if scrollMax ~= self.numLines then
1309 self.scrollDown:SetWidth(maxWidth)
1310 height = height + self.scrollDown:GetHeight() + 2
1311 end
1312 if self.scroll ~= 0 then
1313 self.scrollUp:SetWidth(maxWidth)
1314 height = height + self.scrollUp:GetHeight() + 2
1315 end
1316 self:SetWidth(maxWidth + 20)
1317  
1318 local tmp = self.scroll + 1
1319 if tmp ~= 1 then
1320 tmp = tmp + 1
1321 end
1322 for i = 1, self.numLines do
1323 if i < tmp or i > scrollMax then
1324 self.buttons[i]:ClearAllPoints()
1325 self.buttons[i]:Hide()
1326 else
1327 if i ~= scrollMax or i == self.numLines then
1328 local button = self.buttons[i]
1329 local left = self.lefts[i]
1330 local right = self.rights[i]
1331 local check = self.checks[i]
1332 button:SetWidth(maxWidth)
1333 button:SetHeight(math.max(left:GetHeight(), right:GetHeight()))
1334 height = height + button:GetHeight() + 2
1335 if i == self.scroll + 1 then
1336 button:SetPoint("TOPLEFT", self, "TOPLEFT", 10, -10)
1337 else
1338 button:SetPoint("TOPLEFT", self.buttons[i - 1], "BOTTOMLEFT", 0, -2)
1339 end
1340 if button.clicked then
1341 check:SetPoint("TOPLEFT", button, "TOPLEFT", button.indentation * self.fontSizePercent + (check.width - check:GetWidth()) / 2 + 1, -1)
1342 else
1343 check:SetPoint("TOPLEFT", button, "TOPLEFT", button.indentation * self.fontSizePercent + (check.width - check:GetWidth()) / 2, 0)
1344 end
1345 button:Show()
1346 end
1347 end
1348 end
1349 if self.scroll ~= 0 then
1350 self.scrollUp:SetPoint("TOPLEFT", self, "TOPLEFT", 10, -10)
1351 self.buttons[self.scroll + 2]:SetPoint("TOPLEFT", self.scrollUp, "BOTTOMLEFT", 0, -2)
1352 self.scrollUp:SetText(SCROLL_UP .. " (" .. self.scroll + 2 .. " / " .. self.numLines .. ")")
1353 self.scrollUp:Show()
1354 else
1355 self.scrollUp:Hide()
1356 end
1357 if scrollMax ~= self.numLines and self.buttons[scrollMax - 1] then
1358 self.scrollDown:SetPoint("TOPLEFT", self.buttons[scrollMax - 1], "BOTTOMLEFT", 0, -2)
1359 self.scrollDown:SetText(SCROLL_DOWN .. " (" .. scrollMax - 1 .. " / " .. self.numLines .. ")")
1360 self.scrollDown:Show()
1361 else
1362 self.scrollDown:Hide()
1363 end
1364 self:SetHeight(height)
1365 end
1366 tooltip.Show = wrap(tooltip.Show, "tooltip:Show")
1367  
1368 local lastMouseDown
1369 local function button_OnClick()
1370 if this.self:HasScript("OnClick") and this.self:GetScript("OnClick") then
1371 this.self:GetScript("OnClick")()
1372 end
1373 if arg1 == "RightButton" then
1374 if this.self:HasScript("OnClick") and this.self:GetScript("OnClick") then
1375 this.self:GetScript("OnClick")()
1376 end
1377 elseif arg1 == "LeftButton" then
1378 if this.self.preventClick == nil or GetTime() > this.self.preventClick and GetTime() < lastMouseDown + 0.5 then
1379 this.self.preventClick = nil
1380 this.self.updating = true
1381 this.self.preventRefresh = true
1382 this.func(this.a1, this.a2, this.a3)
1383 this.self.preventRefresh = false
1384 this.self:children()
1385 this.self.updating = false
1386 end
1387 end
1388 end
1389 local function button_OnMouseUp()
1390 if this.self:HasScript("OnMouseUp") and this.self:GetScript("OnMouseUp") then
1391 this.self:GetScript("OnMouseUp")()
1392 end
1393 if arg1 ~= "RightButton" then
1394 if this.clicked then
1395 local a,b,c,d,e = this.check:GetPoint(1)
1396 this.check:SetPoint(a,b,c,d-1,e+1)
1397 this.clicked = false
1398 end
1399 end
1400 end
1401 local function button_OnMouseDown()
1402 if this.self:HasScript("OnMouseDown") and this.self:GetScript("OnMouseDown") then
1403 this.self:GetScript("OnMouseDown")()
1404 end
1405 lastMouseDown = GetTime()
1406 if arg1 ~= "RightButton" then
1407 local a,b,c,d,e = this.check:GetPoint(1)
1408 this.check:SetPoint(a,b,c,d+1,e-1)
1409 this.clicked = true
1410 end
1411 end
1412 function tooltip:AddLine(info)
1413 local category = info.category.superCategory
1414 local maxWidth = category.tabletData.width
1415 local text = info.blank and "\n" or info.text
1416 local id = info.id
1417 local func = info.func
1418 local checked = info.checked
1419 local isRadio = info.isRadio
1420 local checkTexture = info.checkTexture
1421 local fontSizePercent = self.fontSizePercent
1422 if not info.font then
1423 info.font = GameTooltipText
1424 end
1425 if not info.size then
1426 _,info.size = info.font:GetFont()
1427 end
1428 local catStart = false
1429 local columns = category and category.columns or 1
1430 local x1, x2, x3, x4, x5, x6
1431 if category then
1432 x1, x2, x3, x4, x5, x6 = category.x1, category.x2, category.x3, category.x4, category.x5, category.x6
1433 else
1434 x1, x2, x3, x4, x5, x6 = 0, 0, 0, 0, 0, 0
1435 end
1436 if info.isTitle then
1437 justAddedTitle = true
1438 end
1439  
1440 self.numLines = self.numLines + 1
1441 NewLine(self)
1442 self.lefts[self.numLines]:Show()
1443 self.buttons[self.numLines]:Show()
1444 num = self.numLines
1445  
1446 local button = self.buttons[num]
1447 button.indentation = info.indentation
1448 local left = self.lefts[num]
1449 local right = self.rights[num]
1450 local third = self.thirds[num]
1451 local fourth = self.fourths[num]
1452 local fifth = self.fifths[num]
1453 local sixth = self.sixths[num]
1454 local check = self.checks[num]
1455 do -- if columns >= 1 then
1456 left:SetFontObject(info.font)
1457 left:SetText(text)
1458 left:Show()
1459 if info.textR and info.textG and info.textB then
1460 left:SetTextColor(info.textR, info.textG, info.textB)
1461 else
1462 left:SetTextColor(1, 0.823529, 0)
1463 end
1464 local a,_,b = left:GetFont()
1465 left:SetFont(a, info.size * fontSizePercent, b)
1466 left:SetJustifyH(info.justify)
1467 if columns < 2 then
1468 right:SetText(nil)
1469 right:Hide()
1470 right:SetPoint("TOPLEFT", left, "TOPRIGHT", 40 * fontSizePercent, 0)
1471 right:SetPoint("TOPRIGHT", button, "TOPRIGHT", -5, 0)
1472 third:SetText(nil)
1473 third:Hide()
1474 fourth:SetText(nil)
1475 fourth:Hide()
1476 fifth:SetText(nil)
1477 fifth:Hide()
1478 sixth:SetText(nil)
1479 sixth:Hide()
1480 else
1481 right:SetFontObject(info.font2)
1482 right:SetText(info.text2)
1483 right:Show()
1484 if info.text2R and info.text2G and info.text2B then
1485 right:SetTextColor(info.text2R, info.text2G, info.text2B)
1486 else
1487 right:SetTextColor(1, 0.823529, 0)
1488 end
1489 local a,_,b = right:GetFont()
1490 right:SetFont(a, info.size2 * fontSizePercent, b)
1491 right:SetJustifyH(info.justify2)
1492 if columns < 3 then
1493 right:SetPoint("TOPLEFT", left, "TOPRIGHT", 40 * fontSizePercent, 0)
1494 right:SetPoint("TOPRIGHT", button, "TOPRIGHT", -5, 0)
1495 third:SetText(nil)
1496 third:Hide()
1497 fourth:SetText(nil)
1498 fourth:Hide()
1499 fifth:SetText(nil)
1500 fifth:Hide()
1501 sixth:SetText(nil)
1502 sixth:Hide()
1503 else
1504 third:SetFontObject(info.font3)
1505 third:SetText(info.text3)
1506 third:Show()
1507 if info.text3R and info.text3G and info.text3B then
1508 third:SetTextColor(info.text3R, info.text3G, info.text3B)
1509 else
1510 third:SetTextColor(1, 0.823529, 0)
1511 end
1512 local a,_,b = third:GetFont()
1513 third:SetFont(a, info.size3 * fontSizePercent, b)
1514 right:ClearAllPoints()
1515 right:SetPoint("TOPLEFT", left, "TOPRIGHT", 20 * fontSizePercent, 0)
1516 third:SetJustifyH(info.justify3)
1517 if columns < 4 then
1518 fourth:SetText(nil)
1519 fourth:Hide()
1520 fifth:SetText(nil)
1521 fifth:Hide()
1522 sixth:SetText(nil)
1523 sixth:Hide()
1524 else
1525 fourth:SetFontObject(info.font4)
1526 fourth:SetText(info.text4)
1527 fourth:Show()
1528 if info.text4R and info.text4G and info.text4B then
1529 fourth:SetTextColor(info.text4R, info.text4G, info.text4B)
1530 else
1531 fourth:SetTextColor(1, 0.823529, 0)
1532 end
1533 local a,_,b = fourth:GetFont()
1534 fourth:SetFont(a, info.size4 * fontSizePercent, b)
1535 fourth:SetJustifyH(info.justify4)
1536 if columns < 5 then
1537 fifth:SetText(nil)
1538 fifth:Hide()
1539 sixth:SetText(nil)
1540 sixth:Hide()
1541 else
1542 fifth:SetFontObject(info.font5)
1543 fifth:SetText(info.text5)
1544 fifth:Show()
1545 if info.text5R and info.text5G and info.text5B then
1546 fifth:SetTextColor(info.text5R, info.text5G, info.text5B)
1547 else
1548 fifth:SetTextColor(1, 0.823529, 0)
1549 end
1550 local a,_,b = fourth:GetFont()
1551 fifth:SetFont(a, info.size5 * fontSizePercent, b)
1552 fifth:SetJustifyH(info.justify5)
1553 if columns < 6 then
1554 sixth:SetText(nil)
1555 sixth:Hide()
1556 else
1557 sixth:SetFontObject(info.font6)
1558 sixth:SetText(info.text6)
1559 sixth:Show()
1560 if info.text5R and info.text6G and info.text6B then
1561 sixth:SetTextColor(info.text6R, info.text6G, info.text6B)
1562 else
1563 sixth:SetTextColor(1, 0.823529, 0)
1564 end
1565 local a,_,b = fourth:GetFont()
1566 sixth:SetFont(a, info.size6 * fontSizePercent, b)
1567 sixth:SetJustifyH(info.justify6)
1568 end
1569 end
1570 end
1571 end
1572 end
1573 end
1574  
1575 check:SetWidth(info.size)
1576 check:SetHeight(info.size)
1577 check.width = info.size
1578 if info.hasCheck then
1579 check.shown = true
1580 check:Show()
1581 if isRadio then
1582 check:SetTexture(info.checkIcon or "Interface\\Buttons\\UI-RadioButton")
1583 if info.checked then
1584 check:SetAlpha(1)
1585 check:SetTexCoord(0.25, 0.5, 0, 1)
1586 else
1587 check:SetAlpha(self.transparency)
1588 check:SetTexCoord(0, 0.25, 0, 1)
1589 end
1590 else
1591 if info.checkIcon then
1592 check:SetTexture(info.checkIcon)
1593 if string.sub(info.checkIcon, 1, 16) == "Interface\\Icons\\" then
1594 check:SetTexCoord(0.05, 0.95, 0.05, 0.95)
1595 else
1596 check:SetTexCoord(0, 1, 0, 1)
1597 end
1598 else
1599 check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
1600 check:SetWidth(info.size * 1.5)
1601 check:SetHeight(info.size * 1.5)
1602 check.width = info.size * 1.2
1603 check:SetTexCoord(0, 1, 0, 1)
1604 end
1605 check:SetAlpha(info.checked and 1 or 0)
1606 end
1607 left:SetPoint("TOPLEFT", check, "TOPLEFT", check.width, 0)
1608 else
1609 left:SetPoint("TOPLEFT", check, "TOPLEFT")
1610 end
1611 if columns == 1 then
1612 left:SetWidth(maxWidth)
1613 elseif columns == 2 then
1614 left:SetWidth(0)
1615 right:SetWidth(0)
1616 if info.wrap then
1617 left:SetWidth(maxWidth - right:GetWidth() - 40 * fontSizePercent)
1618 elseif info.wrap2 then
1619 right:SetWidth(maxWidth - left:GetWidth() - 40 * fontSizePercent)
1620 end
1621 right:ClearAllPoints()
1622 right:SetPoint("TOPRIGHT", button, "TOPRIGHT", 0, 0)
1623 if not info.text2 then
1624 left:SetJustifyH(info.justify or "LEFT")
1625 end
1626 elseif columns == 3 then
1627 left:SetWidth(x1)
1628 right:SetWidth(x2)
1629 third:SetWidth(x3)
1630 right:ClearAllPoints()
1631 local num = (category.tabletData.width - x1 - x2 - x3) / 2
1632 right:SetPoint("TOPLEFT", left, "TOPRIGHT", num, 0)
1633 third:SetPoint("TOPLEFT", right, "TOPRIGHT", num, 0)
1634 elseif columns == 4 then
1635 left:SetWidth(x1)
1636 right:SetWidth(x2)
1637 third:SetWidth(x3)
1638 fourth:SetWidth(x4)
1639 local num = (category.tabletData.width - x1 - x2 - x3 - x4) / 3
1640 right:SetPoint("TOPLEFT", left, "TOPRIGHT", num, 0)
1641 third:SetPoint("TOPLEFT", right, "TOPRIGHT", num, 0)
1642 fourth:SetPoint("TOPLEFT", third, "TOPRIGHT", num, 0)
1643 elseif columns == 5 then
1644 left:SetWidth(x1)
1645 right:SetWidth(x2)
1646 third:SetWidth(x3)
1647 fourth:SetWidth(x4)
1648 fifth:SetWidth(x5)
1649 local num = (category.tabletData.width - x1 - x2 - x3 - x4 - x5) / 4
1650 right:SetPoint("TOPLEFT", left, "TOPRIGHT", num, 0)
1651 third:SetPoint("TOPLEFT", right, "TOPRIGHT", num, 0)
1652 fourth:SetPoint("TOPLEFT", third, "TOPRIGHT", num, 0)
1653 fifth:SetPoint("TOPLEFT", fourth, "TOPRIGHT", num, 0)
1654 elseif columns == 6 then
1655 left:SetWidth(x1)
1656 right:SetWidth(x2)
1657 third:SetWidth(x3)
1658 fourth:SetWidth(x4)
1659 fifth:SetWidth(x5)
1660 sixth:SetWidth(x6)
1661 local num = (category.tabletData.width - x1 - x2 - x3 - x4 - x5 - x6) / 5
1662 right:SetPoint("TOPLEFT", left, "TOPRIGHT", num, 0)
1663 third:SetPoint("TOPLEFT", right, "TOPRIGHT", num, 0)
1664 fourth:SetPoint("TOPLEFT", third, "TOPRIGHT", num, 0)
1665 fifth:SetPoint("TOPLEFT", fourth, "TOPRIGHT", num, 0)
1666 sixth:SetPoint("TOPLEFT", fifth, "TOPRIGHT", num, 0)
1667 end
1668 if not self.locked or (sekeys and IsAltKeyDown()) then
1669 local func = info.func
1670 if func then
1671 if type(func) == "string" then
1672 assert(type(info.arg1) == "table", "Cannot call method " .. info.func .. " on a non-table")
1673 func = info.arg1[func]
1674 assert(type(func) == "function", "Method " .. info.func .. " nonexistant")
1675 end
1676 assert(type(func) == "function", "func must be a function or method")
1677 button.func = func
1678 button.a1 = info.arg1
1679 button.a2 = info.arg2
1680 button.a3 = info.arg3
1681 button.self = self
1682 button:SetScript("OnMouseUp", button_OnMouseUp)
1683 button:SetScript("OnMouseDown", button_OnMouseDown)
1684 button:SetScript("OnClick", button_OnClick)
1685 if button.clicked then
1686 button:SetButtonState("PUSHED")
1687 end
1688 button:EnableMouse(true)
1689 else
1690 button:SetScript("OnMouseDown", nil)
1691 button:SetScript("OnMouseUp", nil)
1692 button:SetScript("OnClick", nil)
1693 button:EnableMouse(false)
1694 end
1695 else
1696 button:SetScript("OnMouseDown", nil)
1697 button:SetScript("OnMouseUp", nil)
1698 button:SetScript("OnClick", nil)
1699 button:EnableMouse(false)
1700 end
1701 end
1702 tooltip.AddLine = wrap(tooltip.AddLine, "tooltip:AddLine")
1703  
1704 function tooltip:SetFontSizePercent(percent)
1705 local data, detachedData = self.data, self.detachedData
1706 if detachedData and detachedData.detached then
1707 data = detachedData
1708 end
1709 local lastSize = self.fontSizePercent
1710 percent = tonumber(percent) or 1
1711 if percent < 0.25 then
1712 percent = 0.25
1713 elseif percent > 4 then
1714 percent = 4
1715 end
1716 self.fontSizePercent = percent
1717 if data then
1718 data.fontSizePercent = percent ~= 1 and percent or nil
1719 end
1720 self.scrollUp:SetFont(font, normalSize * self.fontSizePercent, flags)
1721 self.scrollDown:SetFont(font, normalSize * self.fontSizePercent, flags)
1722 local ratio = self.fontSizePercent / lastSize
1723 for i = 1, self.numLines do
1724 local left = self.lefts[i]
1725 local right = self.rights[i]
1726 local third = self.thirds[i]
1727 local fourth = self.fourths[i]
1728 local fifth = self.fifths[i]
1729 local sixth = self.sixths[i]
1730 local check = self.checks[i]
1731 local font, size, flags = left:GetFont()
1732 left:SetFont(font, size * ratio, flags)
1733 font, size, flags = right:GetFont()
1734 right:SetFont(font, size * ratio, flags)
1735 font, size, flags = third:GetFont()
1736 third:SetFont(font, size * ratio, flags)
1737 font, size, flags = fourth:GetFont()
1738 fourth:SetFont(font, size * ratio, flags)
1739 font, size, flags = fifth:GetFont()
1740 fifth:SetFont(font, size * ratio, flags)
1741 font, size, flags = sixth:GetFont()
1742 sixth:SetFont(font, size * ratio, flags)
1743 check.width = check.width * ratio
1744 check:SetWidth(check:GetWidth() * ratio)
1745 check:SetHeight(check:GetHeight() * ratio)
1746 end
1747 self:SetWidth((self:GetWidth() - 51) * ratio + 51)
1748 self:SetHeight((self:GetHeight() - 51) * ratio + 51)
1749 if self:IsShown() and self.children then
1750 self:Show()
1751 end
1752 end
1753 tooltip.SetFontSizePercent = wrap(tooltip.SetFontSizePercent, "tooltip:SetFontSizePercent")
1754  
1755 function tooltip:GetFontSizePercent()
1756 return self.fontSizePercent
1757 end
1758  
1759 function tooltip:SetTransparency(alpha)
1760 local data, detachedData = self.data, self.detachedData
1761 if detachedData and detachedData.detached then
1762 data = detachedData
1763 end
1764 self.transparency = alpha
1765 if data then
1766 data.transparency = alpha ~= 0.75 and alpha or nil
1767 end
1768 self:SetBackdropColor(self.r or 0, self.g or 0, self.b or 0, alpha)
1769 self:SetBackdropBorderColor(1, 1, 1, alpha)
1770 end
1771 tooltip.SetTransparency = wrap(tooltip.SetTransparency, "tooltip:SetTransparency")
1772  
1773 function tooltip:GetTransparency()
1774 return self.transparency
1775 end
1776  
1777 function tooltip:SetColor(r, g, b)
1778 local data, detachedData = self.data, self.detachedData
1779 if detachedData and detachedData.detached then
1780 data = detachedData
1781 end
1782 self.r = r
1783 self.g = g
1784 self.b = b
1785 if data then
1786 data.r = r ~= 0 and r or nil
1787 data.g = g ~= 0 and g or nil
1788 data.b = b ~= 0 and b or nil
1789 end
1790 self:SetBackdropColor(r or 0, g or 0, b or 0, self.transparency)
1791 self:SetBackdropBorderColor(1, 1, 1, self.transparency)
1792 end
1793 tooltip.SetColor = wrap(tooltip.SetColor, "tooltip:SetColor")
1794  
1795 function tooltip:GetColor()
1796 return self.r, self.g, self.b
1797 end
1798  
1799 function tooltip:Scroll(down)
1800 if down then
1801 if IsShiftKeyDown() then
1802 self.scroll = self.numLines - GetMaxLinesPerScreen(self)
1803 else
1804 self.scroll = self.scroll + 3
1805 end
1806 else
1807 if IsShiftKeyDown() then
1808 self.scroll = 0
1809 else
1810 self.scroll = self.scroll - 3
1811 end
1812 end
1813 if self.scroll > self.numLines - GetMaxLinesPerScreen(self) then
1814 self.scroll = self.numLines - GetMaxLinesPerScreen(self)
1815 end
1816 if self.scroll < 0 then
1817 self.scroll = 0
1818 end
1819 if self:IsShown() then
1820 self:Show()
1821 end
1822 end
1823 tooltip.Scroll = wrap(tooltip.Scroll, "tooltip:Scroll")
1824  
1825 function tooltip.Detach(tooltip)
1826 local owner = tooltip.owner
1827 tooltip:Hide()
1828 assert(tooltip.detachedData, "You cannot detach if detachedData is not present")
1829 tooltip.detachedData.detached = true
1830 local detached = AcquireDetachedFrame(self, tooltip.registration, tooltip.data, tooltip.detachedData)
1831  
1832 detached.menu, tooltip.menu = tooltip.menu, nil
1833 detached.children = tooltip.children
1834 tooltip.children = nil
1835 detached:SetOwner(owner)
1836 detached:children()
1837 detached:Show()
1838 end
1839 tooltip.Detach = wrap(tooltip.Detach, "tooltip:Detach")
1840 end
1841  
1842 tooltip.registration = registration
1843 registration.tooltip = tooltip
1844 return tooltip
1845 end
1846 AcquireFrame = wrap(AcquireFrame, "AcquireFrame")
1847  
1848 function ReleaseDetachedFrame(self, data, detachedData)
1849 if not detachedData then
1850 detachedData = data
1851 end
1852 for _, detached in ipairs(detachedTooltips) do
1853 if detached.detachedData == detachedData then
1854 detached.notInUse = true
1855 detached:Hide()
1856 detached.registration.tooltip = nil
1857 detached.registration = nil
1858 end
1859 end
1860 end
1861 ReleaseDetachedFrame = wrap(ReleaseDetachedFrame, "ReleaseDetachedFrame")
1862  
1863 function AcquireDetachedFrame(self, registration, data, detachedData)
1864 if not detachedData then
1865 detachedData = data
1866 end
1867 for _, detached in ipairs(detachedTooltips) do
1868 if detached.notInUse then
1869 detached.data = data
1870 detached.detachedData = detachedData
1871 detached.notInUse = nil
1872 local fontSizePercent = detachedData.fontSizePercent or 1
1873 local transparency = detachedData.transparency or 0.75
1874 local r = detachedData.r or 0
1875 local g = detachedData.g or 0
1876 local b = detachedData.b or 0
1877 detached:SetFontSizePercent(fontSizePercent)
1878 detached:SetTransparency(transparency)
1879 detached:SetColor(r, g, b)
1880 detached:ClearAllPoints()
1881 detached:SetPoint(detachedData.anchor or "CENTER", UIParent, detachedData.anchor or "CENTER", detachedData.offsetx or 0, detachedData.offsety or 0)
1882 detached.registration = registration
1883 registration.tooltip = detached
1884 return detached
1885 end
1886 end
1887  
1888 if not dewdrop and DewdropLib then
1889 dewdrop = DewdropLib:GetInstance('1.0')
1890 end
1891 if not sekeys and SpecialEventsEmbed and SpecialEventsEmbed.versions["Keys 1"] then
1892 sekeys = SpecialEventsEmbed:GetInstance("Keys 1")
1893 sekeys:RegisterEvent(self, "SPECIAL_ALTKEY_DOWN")
1894 sekeys:RegisterEvent(self, "SPECIAL_ALTKEY_UP")
1895  
1896 function self:SPECIAL_ALTKEY_DOWN()
1897 for _, detached in ipairs(detachedTooltips) do
1898 if detached:IsShown() and detached.locked then
1899 detached:EnableMouse(IsAltKeyDown())
1900 detached:children()
1901 end
1902 end
1903 end
1904  
1905 self.SPECIAL_ALTKEY_UP = self.SPECIAL_ALTKEY_DOWN
1906 end
1907 if not tooltip then
1908 AcquireFrame(self, {})
1909 end
1910 local detached = CreateFrame("Frame", "TabletLibDetachedFrame" .. (table.getn(detachedTooltips) + 1), UIParent)
1911 table.insert(detachedTooltips, detached)
1912 detached.notInUse = true
1913 detached:EnableMouse(not data.locked)
1914 detached:EnableMouseWheel(true)
1915 detached:SetMovable(true)
1916 detached:SetPoint(data.anchor or "CENTER", UIParent, data.anchor or "CENTER", data.offsetx or 0, data.offsety or 0)
1917  
1918 detached.numLines = 0
1919 detached.owner = nil
1920 detached.fontSizePercent = 1
1921 detached.maxLines = 0
1922 detached.buttons = {}
1923 detached.checks = {}
1924 detached.lefts = {}
1925 detached.rights = {}
1926 detached.thirds = {}
1927 detached.fourths = {}
1928 detached.fifths = {}
1929 detached.sixths = {}
1930 detached.transparency = 0.75
1931 detached.r = 0
1932 detached.g = 0
1933 detached.b = 0
1934 detached:SetFrameStrata("BACKGROUND")
1935 detached:SetBackdrop(tmp.a(
1936 'bgFile', "Interface\\Buttons\\WHITE8X8",
1937 'edgeFile', "Interface\\Tooltips\\UI-Tooltip-Border",
1938 'tile', true,
1939 'tileSize', 16,
1940 'edgeSize', 16,
1941 'insets', tmp.b(
1942 'left', 5,
1943 'right', 5,
1944 'top', 5,
1945 'bottom', 5
1946 )
1947 ))
1948 detached.locked = detachedData.locked
1949 detached.scroll = 0
1950 detached:EnableMouse(not detached.locked)
1951  
1952 local width = GetScreenWidth()
1953 local height = GetScreenHeight()
1954 detached:SetScript("OnMouseDown", function()
1955 if arg1 == "LeftButton" then
1956 if not detached.locked then
1957 detached:StartMoving()
1958 end
1959 end
1960 end)
1961  
1962 detached:SetScript("OnMouseUp", function()
1963 if arg1 == "LeftButton" then
1964 if not detached.locked then
1965 detached:StopMovingOrSizing()
1966 local anchor
1967 local offsetx
1968 local offsety
1969 if detached:GetTop() + detached:GetBottom() < height then
1970 anchor = "BOTTOM"
1971 offsety = detached:GetBottom()
1972 if offsety < 0 then
1973 offsety = 0
1974 end
1975 if offsety < MainMenuBar:GetTop() and MainMenuBar:IsVisible() then
1976 offsety = MainMenuBar:GetTop()
1977 end
1978 local top = 0
1979 if FuBar then
1980 for i = 1, FuBar:GetNumPanels() do
1981 local panel = FuBar:GetPanel(i)
1982 if panel:GetAttachPoint() == "BOTTOM" then
1983 if panel.frame:GetTop() > top then
1984 top = panel.frame:GetTop()
1985 break
1986 end
1987 end
1988 end
1989 end
1990 if offsety < top then
1991 offsety = top
1992 end
1993 else
1994 anchor = "TOP"
1995 offsety = detached:GetTop() - height
1996 if offsety > 0 then
1997 offsety = 0
1998 end
1999 local bottom = GetScreenHeight()
2000 if FuBar then
2001 for i = 1, FuBar:GetNumPanels() do
2002 local panel = FuBar:GetPanel(i)
2003 if panel:GetAttachPoint() == "TOP" then
2004 if panel.frame:GetBottom() < bottom then
2005 bottom = panel.frame:GetBottom()
2006 break
2007 end
2008 end
2009 end
2010 end
2011 bottom = bottom - GetScreenHeight()
2012 if offsety > bottom then
2013 offsety = bottom
2014 end
2015 end
2016 if detached:GetLeft() + detached:GetRight() < width * 2 / 3 then
2017 anchor = anchor .. "LEFT"
2018 offsetx = detached:GetLeft()
2019 if offsetx < 0 then
2020 offsetx = 0
2021 end
2022 elseif detached:GetLeft() + detached:GetRight() < width * 4 / 3 then
2023 if anchor == "" then
2024 anchor = "CENTER"
2025 end
2026 offsetx = (detached:GetLeft() + detached:GetRight() - GetScreenWidth()) / 2
2027 else
2028 anchor = anchor .. "RIGHT"
2029 offsetx = detached:GetRight() - width
2030 if offsetx > 0 then
2031 offsetx = 0
2032 end
2033 end
2034 detached:ClearAllPoints()
2035 detached:SetPoint(anchor, UIParent, anchor, offsetx, offsety)
2036 local t = detached.detachedData
2037 if t.anchor ~= anchor or math.abs(t.offsetx - offsetx) > 8 or math.abs(t.offsety - offsety) > 8 then
2038 detached.preventClick = GetTime() + 0.05
2039 end
2040 t.anchor = anchor
2041 t.offsetx = offsetx
2042 t.offsety = offsety
2043 detached:Show()
2044 end
2045 end
2046 end)
2047  
2048 dewdrop:Register(detached,
2049 'children', function(level, value)
2050 if detached.menu then
2051 detached.menu(level, value)
2052 if level == 1 then
2053 dewdrop:AddLine()
2054 end
2055 end
2056 if level == 1 then
2057 if not detached.registration.cantAttach then
2058 dewdrop:AddLine(
2059 'text', DETACH,
2060 'checked', true,
2061 'arg1', detached,
2062 'func', "Attach",
2063 'closeWhenClicked', true
2064 )
2065 end
2066 dewdrop:AddLine(
2067 'text', LOCK,
2068 'checked', detached:IsLocked(),
2069 'arg1', detached,
2070 'func', "Lock",
2071 'closeWhenClicked', not detached:IsLocked()
2072 )
2073 dewdrop:AddLine(
2074 'text', COLOR,
2075 'hasColorSwatch', true,
2076 'r', detached.r,
2077 'g', detached.g,
2078 'b', detached.b,
2079 'swatchFunc', function(r, g, b)
2080 detached:SetColor(r, g, b)
2081 end,
2082 'hasOpacity', true,
2083 'opacity', detached.transparency,
2084 'opacityFunc', function(alpha)
2085 detached:SetTransparency(alpha)
2086 end,
2087 'cancelFunc', function(r, g, b, a)
2088 detached:SetColor(r, g, b)
2089 detached:SetTransparency(a)
2090 end
2091 )
2092 local value = detached:GetFontSizePercent()
2093 if value < 1 then
2094 value = value - 0.5
2095 else
2096 value = value / 2
2097 end
2098 dewdrop:AddLine(
2099 'text', SIZE,
2100 'hasArrow', true,
2101 'hasSlider', true,
2102 'sliderFunc', function(value)
2103 if value > 0.5 then
2104 value = value * 2
2105 else
2106 value = value + 0.5
2107 end
2108 detached:SetFontSizePercent(value)
2109 return format("%d%%", value * 100)
2110 end,
2111 'sliderTop', "200%",
2112 'sliderBottom', "50%",
2113 'sliderValue', value
2114 )
2115 dewdrop:AddLine()
2116 dewdrop:AddLine(
2117 'text', CLOSE_MENU,
2118 'func', function()
2119 dewdrop:Close()
2120 end
2121 )
2122 end
2123 end,
2124 'point', function()
2125 local x, y = detached:GetCenter()
2126 if x < GetScreenWidth() / 2 then
2127 if y < GetScreenHeight() / 2 then
2128 return "BOTTOMLEFT", "BOTTOMRIGHT"
2129 else
2130 return "TOPLEFT", "TOPRIGHT"
2131 end
2132 else
2133 if y < GetScreenHeight() / 2 then
2134 return "BOTTOMRIGHT", "BOTTOMLEFT"
2135 else
2136 return "TOPRIGHT", "TOPLEFT"
2137 end
2138 end
2139 end
2140 )
2141  
2142 NewLine(detached)
2143  
2144 detached.scrollUp = detached:CreateFontString(nil, "ARTWORK")
2145 detached.scrollUp:SetPoint("TOPLEFT", detached.buttons[1], "BOTTOMLEFT", 0, -2)
2146 detached.scrollUp:SetPoint("RIGHT", detached, "RIGHT", 0, -10)
2147 detached.scrollUp:SetFontObject(GameTooltipText)
2148 detached.scrollUp:Hide()
2149 local font,_,flags = detached.scrollUp:GetFont()
2150 detached.scrollUp:SetFont(font, normalSize * detached.fontSizePercent, flags)
2151 detached.scrollUp:SetJustifyH("CENTER")
2152 detached.scrollUp:SetTextColor(1, 0.823529, 0)
2153 detached.scrollUp:SetText(" ")
2154  
2155 detached.scrollDown = detached:CreateFontString(nil, "ARTWORK")
2156 detached.scrollDown:SetPoint("TOPLEFT", detached.buttons[1], "BOTTOMLEFT", 0, -2)
2157 detached.scrollDown:SetPoint("RIGHT", detached, "RIGHT", 0, -10)
2158 detached.scrollDown:SetFontObject(GameTooltipText)
2159 detached.scrollDown:Hide()
2160 local font,_,flags = detached.scrollUp:GetFont()
2161 detached.scrollDown:SetFont(font, normalSize * detached.fontSizePercent, flags)
2162 detached.scrollDown:SetJustifyH("CENTER")
2163 detached.scrollDown:SetTextColor(1, 0.823529, 0)
2164 detached.scrollDown:SetText(" ")
2165  
2166 detached:SetScript("OnMouseWheel", function()
2167 detached:Scroll(arg1 < 0)
2168 end)
2169  
2170 detached.SetTransparency = tooltip.SetTransparency
2171 detached.GetTransparency = tooltip.GetTransparency
2172 detached.SetColor = tooltip.SetColor
2173 detached.GetColor = tooltip.GetColor
2174 detached.SetFontSizePercent = tooltip.SetFontSizePercent
2175 detached.GetFontSizePercent = tooltip.GetFontSizePercent
2176 detached.SetOwner = tooltip.SetOwner
2177 detached.IsOwned = tooltip.IsOwned
2178 detached.ClearLines = tooltip.ClearLines
2179 detached.NumLines = tooltip.NumLines
2180 detached.Hide = tooltip.Hide
2181 detached.Show = tooltip.Show
2182 detached.AddLine = tooltip.AddLine
2183 detached.Scroll = tooltip.Scroll
2184 function detached:IsLocked()
2185 return self.locked
2186 end
2187 function detached:Lock()
2188 self:EnableMouse(self.locked)
2189 self.locked = not self.locked
2190 self.detachedData.locked = self.locked or nil
2191 self:children()
2192 end
2193  
2194 function detached.Attach(detached)
2195 assert(detached, "Detached tooltip not given.")
2196 assert(detached.AddLine, "detached argument not a Tooltip.")
2197 assert(detached.owner, "Detached tooltip has no owner.")
2198 assert(not detached.notInUse, "Detached tooltip not in use.")
2199 detached.menu = nil
2200 detached.detachedData.detached = nil
2201 detached:SetOwner(nil)
2202 detached.notInUse = TRUE
2203 end
2204  
2205 return AcquireDetachedFrame(self, registration, data, detachedData)
2206 end
2207 AcquireDetachedFrame = wrap(AcquireDetachedFrame, "AcquireDetachedFrame")
2208  
2209 function lib:Close(parent)
2210 if not parent then
2211 if tooltip and tooltip:IsShown() then
2212 tooltip:Hide()
2213 tooltip.registration.tooltip = nil
2214 tooltip.registration = nil
2215 end
2216 return
2217 else
2218 argCheck(parent, 2, "table", "string")
2219 end
2220 local info = self.registry[parent]
2221 assert(info, "You cannot close a tablet with an unregistered parent frame.")
2222 local data = info.data
2223 local detachedData = info.detachedData
2224 if detachedData and detachedData.detached then
2225 ReleaseDetachedFrame(self, data, detachedData)
2226 elseif tooltip.data == data then
2227 tooltip:Hide()
2228 tooltip.registration.tooltip = nil
2229 tooltip.registration = nil
2230 end
2231 end
2232 lib.Close = wrap(lib.Close, "lib:Close")
2233  
2234 local currentFrame
2235 local currentTabletData
2236  
2237 function lib:Open(parent)
2238 argCheck(parent, 2, "table", "string")
2239 local info = self.registry[parent]
2240 assert(info, "You cannot open a tablet with an unregistered parent frame.")
2241 self:Close()
2242 local data = info.data
2243 local detachedData = info.detachedData
2244 local children = info.children
2245 if not children then
2246 return
2247 end
2248 local frame = AcquireFrame(self, info, data, detachedData)
2249 frame.clickable = info.clickable
2250 frame.menu = info.menu
2251 local children = info.children
2252 function frame:children()
2253 if not self.preventRefresh then
2254 currentFrame = self
2255 currentTabletData = TabletData:new(self)
2256 self:ClearLines()
2257 if children then
2258 children()
2259 end
2260 currentTabletData:Display(currentFrame)
2261 self:Show(currentTabletData)
2262 currentTabletData:del()
2263 currentTabletData = nil
2264 currentFrame = nil
2265 end
2266 end
2267 frame:SetOwner(parent)
2268 frame:children()
2269 local point = info.point
2270 local relativePoint = info.point
2271 if type(point) == "function" then
2272 local b
2273 point, b = point(parent)
2274 if b then
2275 relativePoint = b
2276 end
2277 end
2278 if type(relativePoint) == "function" then
2279 relativePoint = relativePoint(parent)
2280 end
2281 if not point then
2282 point = "CENTER"
2283 end
2284 if not relativePoint then
2285 relativePoint = point
2286 end
2287 frame:ClearAllPoints()
2288 if type(parent) ~= "string" then
2289 frame:SetPoint(point, parent, relativePoint)
2290 end
2291 local offsetx = 0
2292 local offsety = 0
2293 if frame:GetBottom() and frame:GetLeft() then
2294 if frame:GetRight() > GetScreenWidth() then
2295 offsetx = frame:GetRight() - GetScreenWidth()
2296 elseif frame:GetLeft() < 0 then
2297 offsetx = -frame:GetLeft()
2298 end
2299 local ratio = GetScreenWidth() / GetScreenHeight()
2300 if ratio >= 2.4 and frame:GetRight() > GetScreenWidth() / 2 and frame:GetLeft() < GetScreenWidth() / 2 then
2301 if frame:GetCenter() < GetScreenWidth() / 2 then
2302 offsetx = frame:GetRight() - GetScreenWidth() / 2
2303 else
2304 offsetx = frame:GetLeft() - GetScreenWidth() / 2
2305 end
2306 end
2307 if frame:GetBottom() < 0 then
2308 offsety = frame:GetBottom()
2309 elseif frame:GetTop() and frame:GetTop() > GetScreenHeight() then
2310 offsety = frame:GetTop() - GetScreenHeight()
2311 end
2312 if MainMenuBar:IsVisible() and frame:GetBottom() < MainMenuBar:GetTop() and offsety < frame:GetBottom() - MainMenuBar:GetTop() then
2313 offsety = frame:GetBottom() - MainMenuBar:GetTop()
2314 end
2315  
2316 if FuBar then
2317 local top = 0
2318 if FuBar then
2319 for i = 1, FuBar:GetNumPanels() do
2320 local panel = FuBar:GetPanel(i)
2321 if panel:GetAttachPoint() == "BOTTOM" then
2322 if panel.frame:GetTop() and panel.frame:GetTop() > top then
2323 top = panel.frame:GetTop()
2324 break
2325 end
2326 end
2327 end
2328 end
2329 if frame:GetBottom() < top and offsety < frame:GetBottom() - top then
2330 offsety = frame:GetBottom() - top
2331 end
2332 local bottom = GetScreenHeight()
2333 if FuBar then
2334 for i = 1, FuBar:GetNumPanels() do
2335 local panel = FuBar:GetPanel(i)
2336 if panel:GetAttachPoint() == "TOP" then
2337 if panel.frame:GetBottom() and panel.frame:GetBottom() < bottom then
2338 bottom = panel.frame:GetBottom()
2339 break
2340 end
2341 end
2342 end
2343 end
2344 if frame:GetTop() > bottom and offsety < frame:GetTop() - bottom then
2345 offsety = frame:GetTop() - bottom
2346 end
2347 end
2348 end
2349 if type(parent) ~= "string" then
2350 frame:SetPoint(point, parent, relativePoint, -offsetx, -offsety)
2351 end
2352  
2353 if detachedData and (info.cantAttach or detachedData.detached) and frame == tooltip then
2354 detachedData.detached = false
2355 frame:Detach()
2356 end
2357 end
2358 lib.Open = wrap(lib.Open, "lib:Open")
2359  
2360 function lib:Register(parent, k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10, k11, v11, k12, v12, k13, v13, k14, v14, k15, v15, k16, v16, k17, v17, k18, v18, k19, v19, k20, v20, k21, v21, k22, v22, k23, v23, k24, v24, k25, v25, k26, v26, k27, v27, k28, v28, k29, v29, k30, v30)
2361 argCheck(parent, 2, "table", "string")
2362 if self.registry[parent] then
2363 self:Unregister(parent)
2364 end
2365 local info
2366 if type(k1) == "table" and k1[0] then
2367 assert(type(self.registry[k1]) == "table", "Other parent not registered")
2368 info = copy(self.registry[k1])
2369 if type(v1) == "function" then
2370 info.point = v1
2371 info.relativePoint = nil
2372 end
2373 else
2374 info = new(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10, k11, v11, k12, v12, k13, v13, k14, v14, k15, v15, k16, v16, k17, v17, k18, v18, k19, v19, k20, v20, k21, v21, k22, v22, k23, v23, k24, v24, k25, v25, k26, v26, k27, v27, k28, v28, k29, v29, k30, v30)
2375 end
2376 self.registry[parent] = info
2377 info.data = info.data or info.detachedData
2378 info.detachedData = info.detachedData or info.data
2379 local data = info.data
2380 local detachedData = info.detachedData
2381 if not self.onceRegistered[parent] and type(parent) == "table" and type(parent.SetScript) == "function" and not info.dontHook then
2382 if not dewdrop then
2383 dewdrop = DewdropLib:GetInstance('1.0')
2384 end
2385 local script = parent:GetScript("OnEnter")
2386 parent:SetScript("OnEnter", function()
2387 if script then
2388 script()
2389 end
2390 if self.registry[parent] then
2391 if (not data or not detachedData.detached) and not dewdrop:IsOpen(parent) then
2392 self:Open(parent)
2393 tooltip.enteredFrame = true
2394 end
2395 end
2396 end)
2397 local script = parent:GetScript("OnLeave")
2398 parent:SetScript("OnLeave", function()
2399 if script then
2400 script()
2401 end
2402 if self.registry[parent] then
2403 if tooltip and (not data or not detachedData or not detachedData.detached) then
2404 tooltip.enteredFrame = false
2405 end
2406 end
2407 end)
2408 if parent:HasScript("OnMouseDown") then
2409 local script = parent:GetScript("OnMouseDown")
2410 parent:SetScript("OnMouseDown", function()
2411 if script then
2412 script()
2413 end
2414 if self.registry[parent] and self.registry[parent].tooltip and self.registry[parent].tooltip == tooltip then
2415 tooltip:Hide()
2416 end
2417 end)
2418 end
2419 if parent:HasScript("OnMouseWheel") then
2420 local script = parent:GetScript("OnMouseWheel")
2421 parent:SetScript("OnMouseWheel", function()
2422 if script then
2423 script()
2424 end
2425 if self.registry[parent] and self.registry[parent].tooltip then
2426 self.registry[parent].tooltip:Scroll(arg1 < 0)
2427 end
2428 end)
2429 end
2430 end
2431 self.onceRegistered[parent] = true
2432 if GetMouseFocus() == parent then
2433 self:Open(parent)
2434 end
2435 end
2436 lib.Register = wrap(lib.Register, "lib:Register")
2437  
2438 function lib:Unregister(parent)
2439 argCheck(parent, 2, "table", "string")
2440 assert(self.registry[parent], "You cannot unregister a parent frame if it has not been registered already.")
2441 self.registry[parent] = nil
2442 end
2443 lib.Unregister = wrap(lib.Unregister, "lib:Unregister")
2444  
2445 function lib:IsRegistered(parent)
2446 argCheck(parent, 2, "table", "string")
2447 return self.registry[parent] and true
2448 end
2449 lib.IsRegistered = wrap(lib.IsRegistered, "lib:IsRegistered")
2450  
2451 local _id = 0
2452 local addedCategory
2453 local currentCategoryInfo
2454 local depth = 0
2455 local categoryPool = {}
2456 function CleanCategoryPool(self)
2457 for k,v in pairs(categoryPool) do
2458 del(v)
2459 categoryPool[k] = nil
2460 end
2461 _id = 0
2462 end
2463  
2464 function lib:AddCategory(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10, k11, v11, k12, v12, k13, v13, k14, v14, k15, v15, k16, v16, k17, v17, k18, v18, k19, v19, k20, v20, k21, v21, k22, v22, k23, v23, k24, v24, k25, v25, k26, v26, k27, v27, k28, v28, k29, v29, k30, v30)
2465 assert(currentFrame, "You must add categories in within a registration.")
2466 local info = new(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5, k6, v6, k7, v7, k8, v8, k9, v9, k10, v10, k11, v11, k12, v12, k13, v13, k14, v14, k15, v15, k16, v16, k17, v17, k18, v18, k19, v19, k20, v20, k21, v21, k22, v22, k23, v23, k24, v24, k25, v25, k26, v26, k27, v27, k28, v28, k29, v29, k30, v30)
2467 local cat = currentTabletData:AddCategory(info)
2468 del(info)
2469 return cat
2470 end
2471 lib.AddCategory = wrap(lib.AddCategory, "lib:AddCategory")
2472  
2473 function lib:SetHint(text)
2474 assert(currentFrame, "You must set hint within a registration.")
2475 assert(not currentCategoryInfo, "You cannot set hint in a category.")
2476 currentTabletData:SetHint(text)
2477 end
2478 lib.SetHint = wrap(lib.SetHint, "lib:SetHint")
2479  
2480 function lib:SetTitle(text)
2481 assert(currentFrame, "You must set title within a registration")
2482 assert(not currentCategoryInfo, "You cannot set title in a category.")
2483 currentTabletData:SetTitle(text)
2484 end
2485 lib.SetTitle = wrap(lib.SetTitle, "lib:SetTitle")
2486  
2487 function lib:GetNormalFontSize()
2488 return normalSize
2489 end
2490  
2491 function lib:GetHeaderFontSize()
2492 return headerSize
2493 end
2494  
2495 function lib:GetNormalFontObject()
2496 return GameTooltipText
2497 end
2498  
2499 function lib:GetHeaderFontObject()
2500 return GameTooltipHeaderText
2501 end
2502  
2503 function lib:SetFontSizePercent(parent, percent)
2504 argCheck(parent, 2, "table", "string")
2505 local info = self.registry[parent]
2506 if info then
2507 if info.tooltip then
2508 info.tooltip:SetFontSizePercent(percent)
2509 else
2510 if detachedData.detached then
2511 detachedData.fontSizePercent = percent
2512 else
2513 data.fontSizePercent = percent
2514 end
2515 end
2516 elseif type(parent) == "table" then
2517 parent.fontSizePercent = percent
2518 else
2519 assert(false, "You cannot change font size with an unregistered parent frame.")
2520 end
2521 end
2522 lib.SetFontSizePercent = wrap(lib.SetFontSizePercent, "lib:SetFontSizePercent")
2523  
2524 function lib:GetFontSizePercent(parent)
2525 argCheck(parent, 2, "table", "string")
2526 local info = self.registry[parent]
2527 if info then
2528 local data = info.data
2529 local detachedData = info.detachedData
2530 if detachedData.detached then
2531 return detachedData.fontSizePercent or 1
2532 else
2533 return data.fontSizePercent or 1
2534 end
2535 elseif type(parent) == "table" then
2536 return parent.fontSizePercent or 1
2537 else
2538 assert(false, "You cannot check font size with an unregistered parent frame.")
2539 end
2540 end
2541 lib.GetFontSizePercent = wrap(lib.GetFontSizePercent, "lib:GetFontSizePercent")
2542  
2543 function lib:SetTransparency(parent, percent)
2544 argCheck(parent, 2, "table", "string")
2545 local info = self.registry[parent]
2546 if info then
2547 if info.tooltip then
2548 info.tooltip:SetTransparency(percent)
2549 else
2550 if detachedData.detached then
2551 detachedData.transparency = percent
2552 else
2553 data.transparency = percent
2554 end
2555 end
2556 elseif type(parent) == "table" then
2557 parent.transparency = percent
2558 else
2559 assert(false, "You cannot change transparency with an unregistered parent frame.")
2560 end
2561 end
2562 lib.SetTransparency = wrap(lib.SetTransparency, "lib:SetTransparency")
2563  
2564 function lib:GetTransparency(parent)
2565 argCheck(parent, 2, "table", "string")
2566 local info = self.registry[parent]
2567 if info then
2568 assert(info, "You cannot check transparency with an unregistered parent frame.")
2569 local data = info.data
2570 local detachedData = info.detachedData
2571 if detachedData.detached then
2572 return detachedData.transparency or 0.75
2573 else
2574 return data.transparency or 0.75
2575 end
2576 elseif type(parent) == "table" then
2577 return parent.transparency or 0.75
2578 else
2579 assert(parent, "You must provide a parent frame to check transparency")
2580 end
2581 end
2582 lib.GetTransparency = wrap(lib.GetTransparency, "lib:GetTransparency")
2583  
2584 function lib:SetColor(parent, r, g, b)
2585 argCheck(parent, 2, "table", "string")
2586 local info = self.registry[parent]
2587 if info then
2588 if info.tooltip then
2589 info.tooltip:SetColor(r, g, b)
2590 else
2591 if detachedData.detached then
2592 detachedData.r = r
2593 detachedData.g = g
2594 detachedData.b = b
2595 else
2596 data.r = r
2597 data.g = g
2598 data.b = b
2599 end
2600 end
2601 elseif type(parent) == "table" then
2602 parent.r = r
2603 parent.g = g
2604 parent.b = b
2605 else
2606 assert(false, "You cannot change color with an unregistered parent frame.")
2607 end
2608 end
2609 lib.SetColor = wrap(lib.SetColor, "lib:SetColor")
2610  
2611 function lib:GetColor(parent)
2612 argCheck(parent, 2, "table", "string")
2613 local info = self.registry[parent]
2614 if info then
2615 local data = info.data
2616 local detachedData = info.detachedData
2617 if detachedData.detached then
2618 return detachedData.r or 0, detachedData.g or 0, detachedData.b or 0
2619 else
2620 return data.r or 0, data.g or 0, data.b or 0
2621 end
2622 elseif type(parent) == "table" then
2623 return parent.r or 0, parent.g or 0, parent.b or 0
2624 else
2625 assert(parent, "You must provide a parent frame to check color")
2626 end
2627 end
2628 lib.GetColor = wrap(lib.GetColor, "lib:GetColor")
2629  
2630 function lib:Detach(parent)
2631 argCheck(parent, 2, "table", "string")
2632 local info = self.registry[parent]
2633 assert(info, "You cannot detach tablet with an unregistered parent frame.")
2634 assert(info.detachedData, "You cannot detach tablet without a data field.")
2635 if info.tooltip and info.tooltip == tooltip then
2636 tooltip:Detach()
2637 else
2638 info.detachedData.detached = true
2639 local detached = AcquireDetachedFrame(self, info, info.data, info.detachedData)
2640  
2641 detached.menu = info.menu
2642 local children = info.children
2643 function detached:children()
2644 if not self.preventRefresh then
2645 currentFrame = self
2646 currentTabletData = TabletData:new(self)
2647 self:ClearLines()
2648 if children then
2649 children()
2650 end
2651 currentTabletData:Display(currentFrame)
2652 self:Show(currentTabletData)
2653 currentTabletData:del()
2654 currentTabletData = nil
2655 currentFrame = nil
2656 end
2657 end
2658 detached:SetOwner(parent)
2659 detached:children()
2660 end
2661 end
2662 lib.Detach = wrap(lib.Detach, "lib:Detach")
2663  
2664 function lib:Attach(parent)
2665 argCheck(parent, 2, "table", "string")
2666 local info = self.registry[parent]
2667 assert(info, "You cannot detach tablet with an unregistered parent frame.")
2668 assert(info.detachedData, "You cannot attach tablet without a data field.")
2669 if info.tooltip and info.tooltip ~= tooltip then
2670 info.tooltip:Attach()
2671 else
2672 info.detachedData.detached = false
2673 end
2674 end
2675 lib.Attach = wrap(lib.Attach, "lib:Attach")
2676  
2677 function lib:IsAttached(parent)
2678 argCheck(parent, 2, "table", "string")
2679 local info = self.registry[parent]
2680 assert(info, "You cannot check tablet with an unregistered parent frame.")
2681 return not info.detachedData or not info.detachedData.detached
2682 end
2683 lib.IsAttached = wrap(lib.IsAttached, "lib:IsAttached")
2684  
2685 function lib:Refresh(parent)
2686 argCheck(parent, 2, "table", "string")
2687 local info = self.registry[parent]
2688 assert(info, "You cannot refresh tablet with an unregistered parent frame.")
2689 local tt = info.tooltip
2690 if tt and not tt.preventRefresh and tt:IsShown() then
2691 tt.updating = true
2692 tt:children()
2693 tt.updating = false
2694 end
2695 end
2696 lib.Refresh = wrap(lib.Refresh, "lib:Refresh")
2697  
2698 function lib:IsLocked(parent)
2699 argCheck(parent, 2, "table", "string")
2700 local info = self.registry[parent]
2701 assert(info, "You cannot detach tablet with an unregistered parent frame.")
2702 return info.detachedData and info.detachedData.locked
2703 end
2704 lib.IsLocked = wrap(lib.IsLocked, "lib:IsLocked")
2705  
2706 function lib:ToggleLocked(parent)
2707 argCheck(parent, 2, "table", "string")
2708 local info = self.registry[parent]
2709 assert(info, "You cannot detach tablet with an unregistered parent frame.")
2710 if info.tooltip and info.tooltip ~= tooltip then
2711 info.tooltip:Lock()
2712 elseif info.detachedData then
2713 info.detachedData.locked = info.detachedData.locked
2714 end
2715 end
2716 lib.ToggleLocked = wrap(lib.ToggleLocked, "lib:ToggleLocked")
2717  
2718 if DEBUG then
2719 function lib:ListProfileInfo()
2720 local duration, times, memories = GetProfileInfo()
2721 assert(duration and times and memories)
2722 local t = new()
2723 for method in pairs(memories) do
2724 table.insert(t, method)
2725 end
2726 table.sort(t, function(alpha, bravo)
2727 if memories[alpha] ~= memories[bravo] then
2728 return memories[alpha] < memories[bravo]
2729 elseif times[alpha] ~= times[bravo] then
2730 return times[alpha] < times[bravo]
2731 else
2732 return alpha < bravo
2733 end
2734 end)
2735 local memory = 0
2736 local time = 0
2737 for _,method in ipairs(t) do
2738 DEFAULT_CHAT_FRAME:AddMessage(format("%s || %.3f s || %.3f%% || %d KiB", method, times[method], times[method] / duration * 100, memories[method]))
2739 memory = memory + memories[method]
2740 time = time + times[method]
2741 end
2742 DEFAULT_CHAT_FRAME:AddMessage(format("%s || %.3f s || %.3f%% || %d KiB", "Total", time, time / duration * 100, memory))
2743 table.setn(t, 0)
2744 del(t)
2745 end
2746 SLASH_TABLET1 = "/tablet"
2747 SLASH_TABLET2 = "/tabletlib"
2748 SlashCmdList["TABLET"] = function(msg)
2749 TabletLib:GetInstance(MAJOR_VERSION):ListProfileInfo()
2750 end
2751 end
2752 TabletLib:Register(lib)
2753 lib = nil