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