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