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