Nenue@37
|
1 --[[
|
Nenue@37
|
2 -- KrakynTools
|
Nenue@37
|
3 -- AddOn prototyping library.
|
Nenue@37
|
4 --
|
Nenue@37
|
5 --- Bundles an object into the handler queue, returning the core object, and handlers for debug output and co-routine.
|
Nenue@37
|
6 -- Addon name is determined in order of: (string first arg, second arg :GetName(), invoking filename).
|
Nenue@37
|
7 -- Once an addon name/object is registered, subsequent calls will return a debugger that reports the file or plugin name.
|
Nenue@37
|
8 -- @usage addon, print, wrap = KT.register(name, table) or KT.register(addon) or KT.register(addon, plugin)
|
Nenue@37
|
9 -- @param name - name of addon, as found in global varargs
|
Nenue@37
|
10 -- @param table - addon table from global varargs
|
Nenue@37
|
11 --
|
Nenue@37
|
12 -- @param frame - frame object used by addon
|
Nenue@37
|
13 -- @param plugin - string name of plugin or an object table to check for lib handlers
|
Nenue@37
|
14 --
|
Nenue@37
|
15 -- Handlers:
|
Nenue@37
|
16 -- :init() run immediately after KT sets itself up
|
Nenue@37
|
17 -- :profile("Name-TruncatedRealm") called the first time SavedVars data becomes available
|
Nenue@37
|
18 -- :variables() called upon variables being available
|
Nenue@37
|
19 -- :event(event, ...) replaces the event callback
|
Nenue@37
|
20 -- :ui() called by /ui when activating
|
Nenue@37
|
21 --
|
Nenue@37
|
22 -- Embedded:
|
Nenue@37
|
23 -- NOTES:
|
Nenue@37
|
24 -- * `name' is passed as is into CreateFrame, so using nil produce an anonymous frame
|
Nenue@37
|
25 -- * `coord' is a 4 or 8 size table unpacked into Texture:SetTexCoords()
|
Nenue@37
|
26 --
|
Nenue@37
|
27 -- tab = frame:tab(name, tooltip, texture, coord)
|
Nenue@37
|
28 -- produces a serial button that changes display tabs
|
Nenue@37
|
29 --
|
Nenue@37
|
30 -- button = frame:button(name, text, tooltip, onClick)
|
Nenue@37
|
31 -- produces a button with OnClick script
|
Nenue@37
|
32 --
|
Nenue@37
|
33 -- uibutton = frame:uibutton(name, text, tooltip, onClick, texture, coord)
|
Nenue@37
|
34 -- produces a header button with desired onClick
|
Nenue@37
|
35 --
|
Nenue@37
|
36 --
|
Nenue@37
|
37 ]]--
|
Nenue@37
|
38
|
Nenue@37
|
39 local LIBKT_MAJOR, LIBKT_MINOR = "LibKraken", 2
|
Nenue@37
|
40 local KT = LibStub:NewLibrary(LIBKT_MAJOR, LIBKT_MINOR)
|
Nenue@37
|
41
|
Nenue@37
|
42 --GLOBALS: KTErrorFrame, LibKTError, SlashCmdList, SLASH_RL1, SLASH_UI1
|
Nenue@37
|
43 local CreateFrame, debugstack, tostring, select = CreateFrame, debugstack, tostring, select
|
Nenue@37
|
44 local max, unpack, tinsert = max, unpack, tinsert
|
Nenue@37
|
45 local ipairs, xpcall, next, safecall = ipairs, xpcall, next, safecall
|
Nenue@37
|
46 local UI_TOGGLE = false
|
Nenue@37
|
47 local db
|
Nenue@37
|
48
|
Nenue@37
|
49
|
Nenue@37
|
50 KT.handler = CreateFrame('Frame', 'LibKTHostFrame', UIParent)
|
Nenue@37
|
51 KT.addons = {}
|
Nenue@37
|
52 KT.initStack = {}
|
Nenue@37
|
53 KT.varsStack = {}
|
Nenue@37
|
54 local print = DEVIAN_WORKSPACE and function(...) _G.print('LKT', ...) end or function() end
|
Nenue@37
|
55 local registeredHandles = {}
|
Nenue@37
|
56 local handlers = {}
|
Nenue@37
|
57
|
Nenue@37
|
58
|
Nenue@37
|
59 --- /rl
|
Nenue@37
|
60 -- ReloadUI shortcut
|
Nenue@37
|
61 SLASH_RL1 = "/rl"
|
Nenue@37
|
62 SlashCmdList.RL = function ()
|
Nenue@37
|
63 ReloadUI()
|
Nenue@37
|
64 end
|
Nenue@37
|
65
|
Nenue@37
|
66 --- /ui
|
Nenue@37
|
67 -- Run any addon:ui() methods
|
Nenue@37
|
68 SLASH_UI1 = "/ui"
|
Nenue@37
|
69 SlashCmdList.UI = function ()
|
Nenue@37
|
70 if UI_TOGGLE then
|
Nenue@37
|
71 UI_TOGGLE = false
|
Nenue@37
|
72 else
|
Nenue@37
|
73 UI_TOGGLE = true
|
Nenue@37
|
74 end
|
Nenue@37
|
75 for i, frame in pairs(KT.frames) do
|
Nenue@37
|
76 if UI_TOGGLE then
|
Nenue@37
|
77 if frame.close then
|
Nenue@37
|
78 frame.close()
|
Nenue@37
|
79 else
|
Nenue@37
|
80 frame:Hide()
|
Nenue@37
|
81 end
|
Nenue@37
|
82 else
|
Nenue@37
|
83 if frame.ui then
|
Nenue@37
|
84 frame.ui()
|
Nenue@37
|
85 end
|
Nenue@37
|
86 frame:Show()
|
Nenue@37
|
87 end
|
Nenue@37
|
88 end
|
Nenue@37
|
89 end
|
Nenue@37
|
90
|
Nenue@37
|
91 LibKTError = function(msg)
|
Nenue@37
|
92 local dstack = debugstack(2)
|
Nenue@37
|
93 :gsub("Interface\\AddOns\\",'')
|
Nenue@37
|
94 :gsub("<(.-)>", function(a) return '|cFF00FFFF<'.. a ..'>|r' end)
|
Nenue@37
|
95
|
Nenue@37
|
96
|
Nenue@37
|
97
|
Nenue@37
|
98 KTErrorFrame.errmsg:SetText(msg)
|
Nenue@37
|
99 KTErrorFrame.debugstack:SetText(dstack)
|
Nenue@37
|
100 KTErrorFrame:SetHeight(KTErrorFrame.debugstack:GetStringHeight() + KTErrorFrame.errmsg:GetStringHeight() + 12)
|
Nenue@37
|
101 KTErrorFrame:Show()
|
Nenue@37
|
102 end
|
Nenue@37
|
103
|
Nenue@37
|
104 local debuggers = {}
|
Nenue@37
|
105 local pending = {}
|
Nenue@37
|
106 local processing = false
|
Nenue@37
|
107 local isHandled = false
|
Nenue@37
|
108 local nodebug = false
|
Nenue@37
|
109 function KT.OnEvent (addon, event, ...)
|
Nenue@37
|
110 if processing then
|
Nenue@37
|
111 local args = {...}
|
Nenue@37
|
112 C_Timer.After(0, function() KT.OnEvent(addon, event, unpack(args)) end)
|
Nenue@37
|
113 return
|
Nenue@37
|
114 else
|
Nenue@37
|
115
|
Nenue@37
|
116 end
|
Nenue@37
|
117 --- reset state
|
Nenue@37
|
118 processing = true
|
Nenue@37
|
119 isHandled = false
|
Nenue@37
|
120 nodebug = false
|
Nenue@37
|
121
|
Nenue@37
|
122
|
Nenue@37
|
123 if addon.event then
|
Nenue@37
|
124 nodebug = addon.event(addon, event, ...)
|
Nenue@37
|
125 end
|
Nenue@37
|
126
|
Nenue@37
|
127 if addon[event] then
|
Nenue@37
|
128 nodebug = addon[event](addon, event, ...) or nodebug
|
Nenue@37
|
129 addon.missed = 0
|
Nenue@37
|
130 addon.handled = addon.handled + 1
|
Nenue@37
|
131 isHandled = true
|
Nenue@37
|
132 else
|
Nenue@37
|
133 addon.firstEvent = false
|
Nenue@37
|
134 addon.unhandled = addon.unhandled + 1
|
Nenue@37
|
135 addon.missed = addon.missed + 1
|
Nenue@37
|
136 end
|
Nenue@37
|
137
|
Nenue@37
|
138 for i, module in ipairs(addon.modules) do
|
Nenue@37
|
139 --print(i, module)
|
Nenue@37
|
140 if module[event] then
|
Nenue@37
|
141 nodebug = module[event](addon, event, ...) or nodebug
|
Nenue@37
|
142 addon.missed = 0
|
Nenue@37
|
143 addon.handled = addon.handled + 1
|
Nenue@37
|
144 isHandled = true
|
Nenue@37
|
145 else
|
Nenue@37
|
146 addon.firstEvent = false
|
Nenue@37
|
147 addon.unhandled = addon.unhandled + 1
|
Nenue@37
|
148 addon.missed = addon.missed + 1
|
Nenue@37
|
149 end
|
Nenue@37
|
150
|
Nenue@37
|
151 end
|
Nenue@37
|
152 --if nodebug then
|
Nenue@37
|
153 processing = false
|
Nenue@37
|
154 return
|
Nenue@37
|
155 --else
|
Nenue@37
|
156 -- KT.UpdateEventStatus(addon, event, ...)
|
Nenue@37
|
157 -- processing = false
|
Nenue@37
|
158 --end
|
Nenue@37
|
159
|
Nenue@37
|
160 end
|
Nenue@37
|
161
|
Nenue@37
|
162 KT.UpdateEventStatus = function(addon, event, ...)
|
Nenue@37
|
163 if (addon.DEVIAN_PNAME and addon.DEVIAN_PNAME == DEVIAN_PNAME) or ((not addon.DEVIAN_PNAME) and DEVIAN_WORKSPACE) then
|
Nenue@37
|
164 print(addon:GetName(), event, ...)
|
Nenue@37
|
165 end
|
Nenue@37
|
166
|
Nenue@37
|
167 -- debug outputs
|
Nenue@37
|
168 if addon.status then
|
Nenue@37
|
169 addon.status:SetText(event .. '\n|cFF00FF00' .. addon.handled .. '|r |cFFFF8800' .. addon.missed .. '|r |cFFFF4400' .. addon.unhandled .. '|r')
|
Nenue@37
|
170 if isHandled then
|
Nenue@37
|
171 addon.status:SetTextColor(0,1,0)
|
Nenue@37
|
172 if addon.log then
|
Nenue@37
|
173 local logtext = event
|
Nenue@37
|
174 for i = 1, select('#',...) do
|
Nenue@37
|
175 logtext = logtext .. '\n' .. i .. ':' .. tostring(select(i,...))
|
Nenue@37
|
176 end
|
Nenue@37
|
177 addon.log:SetText('|cFFFFFF00last|r\n' .. logtext)
|
Nenue@37
|
178 local newWidth = addon.log:GetStringWidth()
|
Nenue@37
|
179
|
Nenue@37
|
180 if addon.logfirst then
|
Nenue@37
|
181 if not addon.firstEvent then
|
Nenue@37
|
182 addon.firstEvent = event
|
Nenue@37
|
183 addon.logfirst:SetText('|cFF00FF88first|r\n' .. logtext)
|
Nenue@37
|
184 end
|
Nenue@37
|
185
|
Nenue@37
|
186 newWidth = newWidth + addon.logfirst:GetStringWidth()
|
Nenue@37
|
187 end
|
Nenue@37
|
188 if addon.logdiff then
|
Nenue@37
|
189 if not event ~= addon.firstEvent then
|
Nenue@37
|
190 addon.firstEvent = event
|
Nenue@37
|
191 addon.logdiff:SetText('|cFF0088FFdiff|r\n' .. logtext)
|
Nenue@37
|
192 end
|
Nenue@37
|
193 newWidth = newWidth + addon.logdiff:GetStringWidth()
|
Nenue@37
|
194 end
|
Nenue@37
|
195 --addon:SetWidth(newWidth)
|
Nenue@37
|
196 end
|
Nenue@37
|
197 else
|
Nenue@37
|
198 addon.status:SetTextColor(1,0,0)
|
Nenue@37
|
199 end
|
Nenue@37
|
200 end
|
Nenue@37
|
201 end
|
Nenue@37
|
202
|
Nenue@37
|
203 KT.map = function(addon, addonTable)
|
Nenue@37
|
204 setmetatable(addonTable, {
|
Nenue@37
|
205 __index = function(_,k)
|
Nenue@37
|
206 return addon[k]
|
Nenue@37
|
207 end,
|
Nenue@37
|
208 __newindex = function(_, k, v)
|
Nenue@37
|
209 addon[k] = v
|
Nenue@37
|
210 end
|
Nenue@37
|
211 })
|
Nenue@37
|
212 end
|
Nenue@37
|
213
|
Nenue@37
|
214 local emptyFunc = function() end
|
Nenue@37
|
215
|
Nenue@37
|
216 KT.register = function(addon, arg, noGUI)
|
Nenue@37
|
217
|
Nenue@37
|
218 local name, handler
|
Nenue@37
|
219 if type(addon) == 'string' and type(arg) == 'table' then
|
Nenue@37
|
220 -- it's a string, i.e. file vararg was passed
|
Nenue@37
|
221 if _G[addon] then
|
Nenue@37
|
222 -- check if it's the name of a frame and use that
|
Nenue@37
|
223 handler = _G[addon]
|
Nenue@37
|
224 else
|
Nenue@37
|
225 -- re-arrange
|
Nenue@37
|
226 name = addon
|
Nenue@37
|
227 handler = arg
|
Nenue@37
|
228 end
|
Nenue@37
|
229 else
|
Nenue@37
|
230 handler = addon
|
Nenue@37
|
231 assert(type(handler) == 'table', 'Unable to parse ('..tostring(type(addon))..', '..tostring(type(arg))..')')
|
Nenue@37
|
232 end
|
Nenue@37
|
233
|
Nenue@37
|
234
|
Nenue@37
|
235 local loadedName
|
Nenue@37
|
236 local printName
|
Nenue@37
|
237 local isModule
|
Nenue@37
|
238
|
Nenue@37
|
239 -- if exists, then second argument is probably a module name
|
Nenue@37
|
240 if registeredHandles[handler] then
|
Nenue@37
|
241 if type(arg) == 'table' then
|
Nenue@37
|
242 tinsert(handler.modules, arg)
|
Nenue@37
|
243 else
|
Nenue@37
|
244 name = arg or debugstack(2,1,0):match(".+\\(%S+)%.lua")
|
Nenue@37
|
245 end
|
Nenue@37
|
246 isModule = true
|
Nenue@37
|
247
|
Nenue@37
|
248 if not name then
|
Nenue@37
|
249 name = debugstack(2,1,0):match(".+\\(%S+)%.lua")
|
Nenue@37
|
250 end
|
Nenue@37
|
251 local handlerName = handler:GetName()
|
Nenue@37
|
252 loadedName = '|cFF00FF88'.. tostring(handlerName) .. '|r:|cFFFFFF00'.. tostring(name)
|
Nenue@37
|
253 else
|
Nenue@37
|
254 if handler.GetName then
|
Nenue@37
|
255 name = handler:GetName()
|
Nenue@37
|
256 elseif not name then
|
Nenue@37
|
257 name = debugstack(2,1,0):match(".+\\(%S+)%.lua")
|
Nenue@37
|
258 end
|
Nenue@37
|
259
|
Nenue@37
|
260 loadedName = '|cFF00FFFF'.. tostring(name) .. '|r'
|
Nenue@37
|
261
|
Nenue@37
|
262 registeredHandles[handler] = name
|
Nenue@37
|
263 if handler.SetScript then
|
Nenue@37
|
264 handler:SetScript('OnEvent', KT.OnEvent)
|
Nenue@37
|
265 end
|
Nenue@37
|
266 handler.unhandled = 0
|
Nenue@37
|
267 handler.missed = 0
|
Nenue@37
|
268 handler.handled = 0
|
Nenue@37
|
269 handler.firstEvent = false
|
Nenue@37
|
270 handler.modules = {}
|
Nenue@37
|
271 tinsert(KT.initStack, handler)
|
Nenue@37
|
272 tinsert(KT.varsStack, handler)
|
Nenue@37
|
273
|
Nenue@37
|
274 if handler.GetName and (not noGUI) then
|
Nenue@37
|
275 handler.UIPanelAnchor = {'TOPLEFT', handler, 'TOPLEFT', 12, -12 }
|
Nenue@37
|
276 handler.UIPanelGrowth = {'TOPLEFT', 'TOPRIGHT', 14, 0}
|
Nenue@37
|
277 handler.button = KT.button
|
Nenue@37
|
278 handler.uibutton = KT.uibutton
|
Nenue@37
|
279 handler.tab = KT.tab
|
Nenue@37
|
280 handler.print = KT.print
|
Nenue@37
|
281 end
|
Nenue@37
|
282 end
|
Nenue@37
|
283
|
Nenue@37
|
284 local debugID = isModule and name or handler
|
Nenue@37
|
285 local debugFunc = emptyFunc
|
Nenue@37
|
286 if (handler.DEVIAN_PNAME and DEVIAN_PNAME == handler.DEVIAN_PNAME) or ((not handler.DEVIAN_PNAME) and DEVIAN_WORKSPACE) then
|
Nenue@37
|
287 debuggers[debugID] = debuggers[debugID] or function(...) _G.print(name, ...) end
|
Nenue@37
|
288 debugFunc = debuggers[debugID]
|
Nenue@37
|
289 end
|
Nenue@37
|
290
|
Nenue@37
|
291 print(loadedName)
|
Nenue@37
|
292
|
Nenue@37
|
293 return handler, debugFunc, KT.wrap
|
Nenue@37
|
294 end
|
Nenue@37
|
295
|
Nenue@37
|
296
|
Nenue@37
|
297
|
Nenue@37
|
298 local onEvent = function(self, event, arg1)
|
Nenue@37
|
299 if (event == 'ADDON_LOADED' and arg1 ~= 'Blizzard_DebugTools') or event == 'PLAYER_LOGIN' then
|
Nenue@37
|
300 -- run any init blocks left in the queue
|
Nenue@37
|
301 while #KT.initStack >= 1 do
|
Nenue@37
|
302 local addon = tremove(KT.initStack, 1)
|
Nenue@37
|
303 print('KT', addon:GetName(), 'init')
|
Nenue@37
|
304 if addon.init then
|
Nenue@37
|
305 xpcall(addon.init, LibKTError)
|
Nenue@37
|
306 for i, module in ipairs(addon.modules) do
|
Nenue@37
|
307 if module.init then
|
Nenue@37
|
308 xpcall(module.init, LibKTError)
|
Nenue@37
|
309 end
|
Nenue@37
|
310 end
|
Nenue@37
|
311 end
|
Nenue@37
|
312 end
|
Nenue@37
|
313
|
Nenue@37
|
314 -- run any variables blocks if player variables are ready
|
Nenue@37
|
315 if IsLoggedIn() and #KT.varsStack >= 1 then
|
Nenue@37
|
316 while #KT.varsStack >= 1 do
|
Nenue@37
|
317 local addon = tremove(KT.varsStack, 1)
|
Nenue@37
|
318 print(addon:GetName())
|
Nenue@37
|
319 if addon.variables then
|
Nenue@37
|
320 xpcall(addon.variables, LibKTError)
|
Nenue@37
|
321 for i, module in ipairs(addon.modules) do
|
Nenue@37
|
322 if module.variables then
|
Nenue@37
|
323 xpcall(module.variables, LibKTError)
|
Nenue@37
|
324 end
|
Nenue@37
|
325 end
|
Nenue@37
|
326 end
|
Nenue@37
|
327 end
|
Nenue@37
|
328 end
|
Nenue@37
|
329 end
|
Nenue@37
|
330 end
|
Nenue@37
|
331
|
Nenue@37
|
332 KT.print = function(module, ...)
|
Nenue@37
|
333 local msg = '|cFF00FFFF'..module:GetName()..'|r:'
|
Nenue@37
|
334 for i = 1, select('#', ...) do
|
Nenue@37
|
335 msg = msg .. ' ' .. tostring(select(i, ...))
|
Nenue@37
|
336 end
|
Nenue@37
|
337 DEFAULT_CHAT_FRAME:AddMessage(msg)
|
Nenue@37
|
338 end
|
Nenue@37
|
339
|
Nenue@37
|
340 --- Button generators
|
Nenue@37
|
341
|
Nenue@37
|
342 local GetButtonTemplate = function(name, parent, template, onClick)
|
Nenue@37
|
343 if _G[name] then
|
Nenue@37
|
344 return _G[name]
|
Nenue@37
|
345 end
|
Nenue@37
|
346
|
Nenue@37
|
347 local button = CreateFrame('Button', name, parent, template)
|
Nenue@37
|
348 button:RegisterForClicks('AnyUp')
|
Nenue@37
|
349 button:SetScript('OnClick', onClick)
|
Nenue@37
|
350 return button
|
Nenue@37
|
351 end
|
Nenue@37
|
352
|
Nenue@37
|
353 local SetButtonAnchor = function(self, collector, anchor, growth)
|
Nenue@37
|
354 if self:GetID() == 0 then
|
Nenue@37
|
355 self:SetID(#collector)
|
Nenue@37
|
356 print('registered TabButton #', self:GetID())
|
Nenue@37
|
357 end
|
Nenue@37
|
358
|
Nenue@37
|
359 if self:GetID() == 1 then
|
Nenue@37
|
360 self:SetPoint(unpack(anchor))
|
Nenue@37
|
361 else
|
Nenue@37
|
362 growth[2] = collector[self:GetID()-1]
|
Nenue@37
|
363 self:SetPoint(unpack(growth))
|
Nenue@37
|
364 end
|
Nenue@37
|
365 end
|
Nenue@37
|
366
|
Nenue@37
|
367 KT.tab = function(self, name, tooltip, texture, coords)
|
Nenue@37
|
368 local button = GetButtonTemplate(name, self, 'KTTabButton', self.SelectTab)
|
Nenue@37
|
369 button.icon:SetTexture(texture)
|
Nenue@37
|
370 button.tooltip = tooltip
|
Nenue@37
|
371 button:SetSize(unpack(self.tabSize))
|
Nenue@37
|
372 if coords then
|
Nenue@37
|
373 button.icon:SetTexCoord(unpack(coords))
|
Nenue@37
|
374 end
|
Nenue@37
|
375 SetButtonAnchor(button, self.tabButtons, self.tabAnchor, self.tabGrowth)
|
Nenue@37
|
376 return button
|
Nenue@37
|
377 end
|
Nenue@37
|
378
|
Nenue@37
|
379 KT.button = function(self, name, text, tooltip, onClick)
|
Nenue@37
|
380 local button = GetButtonTemplate(name, self, 'KTButton', onClick)
|
Nenue@37
|
381
|
Nenue@37
|
382 button.tooltip = tooltip
|
Nenue@37
|
383 button:SetText(text)
|
Nenue@37
|
384 button:SetWidth(max(button:GetWidth(), button:GetFontString():GetStringWidth() + 12))
|
Nenue@37
|
385
|
Nenue@37
|
386 SetButtonAnchor(button, self.controls, self.controlsAnchor, self.controlsGrowth)
|
Nenue@37
|
387 return button
|
Nenue@37
|
388 end
|
Nenue@37
|
389
|
Nenue@37
|
390 KT.uibutton = function(self, name, text, tooltip, onClick, texture, coords)
|
Nenue@37
|
391 local button = GetButtonTemplate(name, self, 'KTUIPanelButton', onClick)
|
Nenue@37
|
392
|
Nenue@37
|
393 button.tooltip = tooltip
|
Nenue@37
|
394 button:SetText(text)
|
Nenue@37
|
395
|
Nenue@37
|
396 if self.UIPanelIcon then
|
Nenue@37
|
397 local w, h, anchor, x, y = unpack(self.UIPanelIcon)
|
Nenue@37
|
398 button.icon:SetTexture(texture)
|
Nenue@37
|
399 button.icon:SetSize(w, h)
|
Nenue@37
|
400 button.icon:ClearAllPoints()
|
Nenue@37
|
401 button.icon:SetPoint(anchor, button, anchor, x, y)
|
Nenue@37
|
402 end
|
Nenue@37
|
403
|
Nenue@37
|
404 if not self.UIPanelSize then
|
Nenue@37
|
405 button:SetWidth(button:GetFontString():GetStringWidth() + button.icon:GetWidth()/1.5)
|
Nenue@37
|
406 else
|
Nenue@37
|
407 button:SetSize(unpack(self.UIPanelSize))
|
Nenue@37
|
408 end
|
Nenue@37
|
409 if coords then
|
Nenue@37
|
410 button.icon:SetTexCoord(unpack(coords))
|
Nenue@37
|
411 end
|
Nenue@37
|
412 SetButtonAnchor(button, self.UIPanels, self.UIPanelAnchor, self.UIPanelGrowth)
|
Nenue@37
|
413 return button
|
Nenue@37
|
414 end
|
Nenue@37
|
415
|
Nenue@37
|
416 --- Co-routine Handler kajigger
|
Nenue@37
|
417 do
|
Nenue@37
|
418 local tickerQueue = {}
|
Nenue@37
|
419 local ticker
|
Nenue@37
|
420 local instant = false
|
Nenue@37
|
421 KT.tick = function()
|
Nenue@37
|
422
|
Nenue@37
|
423 if #tickerQueue == 0 then
|
Nenue@37
|
424 ticker:Cancel()
|
Nenue@37
|
425 ticker = nil
|
Nenue@37
|
426 end
|
Nenue@37
|
427 local func = tremove(tickerQueue, 1)
|
Nenue@37
|
428 if func then
|
Nenue@37
|
429 --print('#', #tickerQueue)
|
Nenue@37
|
430 func()
|
Nenue@37
|
431 end
|
Nenue@37
|
432 end
|
Nenue@37
|
433
|
Nenue@37
|
434 KT.wrap = function(f)
|
Nenue@37
|
435 if not ticker then
|
Nenue@37
|
436 --print('create ticker')
|
Nenue@37
|
437 ticker = C_Timer.NewTicker(.001, KT.tick)
|
Nenue@37
|
438 end
|
Nenue@37
|
439 tinsert(tickerQueue, f)
|
Nenue@37
|
440
|
Nenue@37
|
441 return #tickerQueue
|
Nenue@37
|
442
|
Nenue@37
|
443 end
|
Nenue@37
|
444 end
|
Nenue@37
|
445
|
Nenue@37
|
446 KT.handler:RegisterEvent('ADDON_LOADED')
|
Nenue@37
|
447 KT.handler:RegisterEvent('PLAYER_LOGIN')
|
Nenue@37
|
448 KT.handler:SetScript('OnEvent', onEvent) |