Mercurial > wow > skeletonkey
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) |
