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