vanilla-wow-addons – Blame information for rev 1

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