Nenue@2: --[[ Implements Nenue@2: -- KT.register(frame) to hook the following (all optional): Nenue@2: -- frame:init() run immediately after KT sets itself up Nenue@2: -- frame:profile("Name-TruncatedRealm") called the first time SavedVars data becomes available Nenue@2: -- frame:variables() called by PLAYER_ENTERING_WORLD Nenue@2: -- frame:event(event, ...) replaces the event callback Nenue@2: -- frame:ui() called by /ui when activating Nenue@2: ]]-- Nenue@2: Nenue@2: --GLOBALS: LibKT, KrakTool, KTErrorFrame, LibKTError, SlashCmdList, SLASH_RL1, SLASH_UI1 Nenue@2: local CreateFrame, debugstack, tostring, select = CreateFrame, debugstack, tostring, select Nenue@2: local print, max, unpack, tinsert = print, max, unpack, tinsert Nenue@2: local ipairs, xpcall = ipairs, xpcall Nenue@2: local UI_TOGGLE = false Nenue@2: Nenue@2: KrakTool = CreateFrame('Frame', 'KrakTool', UIParent) Nenue@2: LibKT = select(2, ...) Nenue@2: local KT = LibKT Nenue@2: KT.handler = KrakTool Nenue@2: KT.frames = {} Nenue@2: Nenue@2: SLASH_RL1 = "/rl" Nenue@2: SlashCmdList.RL = function () Nenue@2: ReloadUI() Nenue@2: end Nenue@2: Nenue@2: SLASH_UI1 = "/ui" Nenue@2: SlashCmdList.UI = function () Nenue@2: if UI_TOGGLE then Nenue@2: UI_TOGGLE = false Nenue@2: else Nenue@2: UI_TOGGLE = true Nenue@2: end Nenue@2: for i, frame in pairs(KT.frames) do Nenue@2: if UI_TOGGLE then Nenue@2: if frame.close then Nenue@2: frame.close() Nenue@2: else Nenue@2: frame:Hide() Nenue@2: end Nenue@2: else Nenue@2: if frame.ui then Nenue@2: frame.ui() Nenue@2: end Nenue@2: frame:Show() Nenue@2: end Nenue@2: end Nenue@2: end Nenue@2: Nenue@2: LibKTError = function(msg) Nenue@2: local dstack = debugstack() Nenue@2: :gsub("Interface\\AddOns\\",'~\\') Nenue@2: :gsub("<(.-)>", function(a) return '|cFF00FFFF<'.. a ..'>|r' end) Nenue@2: KTErrorFrame.errmsg:SetText(msg) Nenue@2: KTErrorFrame.debugstack:SetText(dstack) Nenue@2: KTErrorFrame:SetHeight(KTErrorFrame.debugstack:GetStringHeight() + KTErrorFrame.errmsg:GetStringHeight() + 12) Nenue@2: KTErrorFrame:Show() Nenue@2: end Nenue@2: Nenue@2: local initStack = {} Nenue@2: local eventStub = function(self, event, ...) Nenue@2: local isHandled Nenue@2: local nodebug Nenue@2: Nenue@2: if self.event then Nenue@2: nodebug = self.event(self, event, ...) Nenue@2: end Nenue@2: Nenue@2: if self[event] then Nenue@2: nodebug = nodebug or self[event](self, event, ...) Nenue@2: self.missed = 0 Nenue@2: self.handled = self.handled + 1 Nenue@2: isHandled = true Nenue@2: else Nenue@2: self.firstEvent = false Nenue@2: self.unhandled = self.unhandled + 1 Nenue@2: self.missed = self.missed + 1 Nenue@2: end Nenue@2: Nenue@2: if nodebug then Nenue@2: return Nenue@2: end Nenue@2: Nenue@2: print(self:GetName(), event, ...) Nenue@2: Nenue@2: -- debug outputs Nenue@2: if self.status then Nenue@2: self.status:SetText(event .. '\n|cFF00FF00' .. self.handled .. '|r |cFFFF8800' .. self.missed .. '|r |cFFFF4400' .. self.unhandled .. '|r') Nenue@2: if isHandled then Nenue@2: self.status:SetTextColor(0,1,0) Nenue@2: if self.log then Nenue@2: local logtext = event Nenue@2: for i = 1, select('#',...) do Nenue@2: logtext = logtext .. '\n' .. i .. ':' .. tostring(select(i,...)) Nenue@2: end Nenue@2: self.log:SetText('|cFFFFFF00last|r\n' .. logtext) Nenue@2: local newWidth = self.log:GetStringWidth() Nenue@2: Nenue@2: if self.logfirst then Nenue@2: if not self.firstEvent then Nenue@2: self.firstEvent = event Nenue@2: self.logfirst:SetText('|cFF00FF88first|r\n' .. logtext) Nenue@2: end Nenue@2: Nenue@2: newWidth = newWidth + self.logfirst:GetStringWidth() Nenue@2: end Nenue@2: if self.logdiff then Nenue@2: if not event ~= self.firstEvent then Nenue@2: self.firstEvent = event Nenue@2: self.logdiff:SetText('|cFF0088FFdiff|r\n' .. logtext) Nenue@2: end Nenue@2: newWidth = newWidth + self.logdiff:GetStringWidth() Nenue@2: end Nenue@2: --self:SetWidth(newWidth) Nenue@2: end Nenue@2: else Nenue@2: self.status:SetTextColor(1,0,0) Nenue@2: end Nenue@2: end Nenue@2: end Nenue@2: Nenue@2: KT.register = function(frame, name, noGUI) Nenue@2: if not name then Nenue@2: name = frame:GetName() Nenue@2: end Nenue@2: Nenue@2: KT.frames[name] = frame Nenue@2: frame:SetScript('OnEvent', eventStub) Nenue@2: frame.unhandled = 0 Nenue@2: frame.missed = 0 Nenue@2: frame.handled = 0 Nenue@2: frame.firstEvent = false Nenue@2: tinsert(initStack, frame) Nenue@2: Nenue@2: if noGUI then Nenue@2: return Nenue@2: end Nenue@2: Nenue@2: frame.UIPanelAnchor = {'TOPLEFT', frame, 'TOPLEFT', 12, -12 } Nenue@2: frame.UIPanelGrowth = {'TOPLEFT', 'TOPRIGHT', 14, 0} Nenue@2: frame.button = KT.button Nenue@2: frame.uibutton = KT.uibutton Nenue@2: frame.tab = KT.tab Nenue@2: frame.print = KT.print Nenue@2: Nenue@2: return KT Nenue@2: end Nenue@2: Nenue@2: KT.handler:RegisterEvent('VARIABLES_LOADED') Nenue@2: KT.handler:SetScript('OnEvent', function(self, event, ...) Nenue@2: print('KrakTool', event, ...) Nenue@2: if not LibKTDB then Nenue@2: LibKTDB = {} Nenue@2: end Nenue@2: KT.db = LibKTDB Nenue@2: Nenue@2: KT.db.runcount = KT.db.runcount or 1 Nenue@2: KT.db.runcount = KT.db.runcount + 1 Nenue@2: print(KT.db.runcount) Nenue@2: Nenue@2: for i, frame in ipairs(initStack) do Nenue@2: print('|cFF00FF00', i, '|r', frame:GetName()) Nenue@2: if frame.init then Nenue@2: xpcall(frame.init, LibKTError) Nenue@2: end Nenue@2: end Nenue@2: Nenue@2: self:RegisterEvent('PLAYER_ENTERING_WORLD') Nenue@2: self:SetScript('OnEvent', function() Nenue@2: for i, frame in ipairs(initStack) do Nenue@2: print('|cFF00FFFF', i, '|r', frame:GetName()) Nenue@2: if frame.variables then Nenue@2: xpcall(frame.variables, LibKTError) Nenue@2: end Nenue@2: end Nenue@2: end) Nenue@2: end) Nenue@2: Nenue@2: KT.print = function(module, ...) Nenue@2: print('|cFF00FFFF'..module:GetName()..'|r:', ...) Nenue@2: end Nenue@2: Nenue@2: --- Button generators Nenue@2: Nenue@2: local GetButtonTemplate = function(name, parent, template, onClick) Nenue@2: if _G[name] then Nenue@2: return _G[name] Nenue@2: end Nenue@2: Nenue@2: local button = CreateFrame('Button', name, parent, template) Nenue@2: button:SetScript('OnMouseUp', onClick) Nenue@2: return button Nenue@2: end Nenue@2: Nenue@2: local SetButtonAnchor = function(self, collector, anchor, growth) Nenue@2: if self:GetID() == 0 then Nenue@2: self:SetID(#collector) Nenue@2: print('registered TabButton #', self:GetID()) Nenue@2: end Nenue@2: Nenue@2: if self:GetID() == 1 then Nenue@2: self:SetPoint(unpack(anchor)) Nenue@2: else Nenue@2: growth[2] = collector[self:GetID()-1] Nenue@2: self:SetPoint(unpack(growth)) Nenue@2: end Nenue@2: end Nenue@2: Nenue@2: KT.tab = function(self, name, tooltip, texture, coords) Nenue@2: local button = GetButtonTemplate(name, self, 'KTTabButton', self.SelectTab) Nenue@2: button.icon:SetTexture(texture) Nenue@2: button.tooltip = tooltip Nenue@2: button:SetSize(unpack(self.tabSize)) Nenue@2: if coords then Nenue@2: button.icon:SetTexCoord(unpack(coords)) Nenue@2: end Nenue@2: SetButtonAnchor(button, self.tabButtons, self.tabAnchor, self.tabGrowth) Nenue@2: return button Nenue@2: end Nenue@2: Nenue@2: KT.button = function(self, name, text, tooltip, onClick) Nenue@2: local button = GetButtonTemplate(name, self, 'KTButton', onClick) Nenue@2: Nenue@2: button.tooltip = tooltip Nenue@2: button:SetText(text) Nenue@2: button:SetWidth(max(button:GetWidth(), button:GetFontString():GetStringWidth() + 12)) Nenue@2: Nenue@2: SetButtonAnchor(button, self.controls, self.controlsAnchor, self.controlsGrowth) Nenue@2: return button Nenue@2: end Nenue@2: Nenue@2: KT.uibutton = function(self, name, text, tooltip, onClick, texture, coords) Nenue@2: local button = GetButtonTemplate(name, self, 'KTUIPanelButton', onClick) Nenue@2: Nenue@2: button.tooltip = tooltip Nenue@2: button:SetText(text) Nenue@2: button.icon:SetTexture(texture) Nenue@2: button:SetWidth(button:GetFontString():GetStringWidth() + button.icon:GetWidth()/1.5) Nenue@2: if coords then Nenue@2: button.icon:SetTexCoord(unpack(coords)) Nenue@2: end Nenue@2: SetButtonAnchor(button, self.UIPanels, self.UIPanelAnchor, self.UIPanelGrowth) Nenue@2: return button Nenue@2: end