comparison LibKraken/LibKraken.lua @ 59:d8bb2629fea8

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