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