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