Nenue@32: --- ${PACKAGE_NAME} Nenue@32: -- @file-author@ Nenue@32: -- @project-revision@ @project-hash@ Nenue@32: -- @file-revision@ @file-hash@ Nenue@0: if not LibStub then Nenue@0: print('Something has happened...') Nenue@0: end Nenue@0: Devian = LibStub("AceAddon-3.0"):NewAddon("Devian", "AceConsole-3.0", "AceEvent-3.0") Nenue@13: local MAJOR, MINOR = 'Devian-1.3', 'r@project-revision@' Nenue@0: local D = _G.Devian Nenue@32: local WORKSPACE_ON, WORKSPACE_OFF = 1, 2 Nenue@0: local PLAYER_REALM = UnitName("player") .. '-' .. GetRealmName() Nenue@13: local DEVIAN_FRAME = 'DevianConsole' Nenue@18: local print = _G.print Nenue@9: local db Nenue@13: local defaults = { Nenue@32: ['global'] = {{}, {}}, Nenue@13: ['tags'] = {}, Nenue@32: ['channels'] = {[1] = {signature = 'Main', index = 1, x = 100, y = 800, height = 500, width = 600, enabled = true}}, Nenue@14: primary_channel = 1, Nenue@13: current_channel = 1, Nenue@32: max_channel = 1, Nenue@14: toggle = true, Nenue@32: load_message = "Defaults loaded.", Nenue@13: font = [[Interface\Addons\Devian\font\SourceCodePro-Regular.ttf]], Nenue@13: fontsize = 13, Nenue@13: fontoutline = 'NONE', Nenue@32: headergrab = {'VERTICAL', 0, 0, 0, 0.5, 0.1, 0.1, 0.1, 0.3}, Nenue@28: backalpha = 0.5, Nenue@28: backdrop = {0,0,0,0.4}, Nenue@14: backgrad = {'VERTICAL', 0.1, 0.1, 0.1, 0.3, 0, 0, 0, 0.5}, Nenue@14: backblend = 'BLEND', Nenue@28: frontdrop = {0,0,0,1}, Nenue@14: frontgrad = {'VERTICAL', 0.1, 0.1, 0.1, 0.9, 0, 0, 0, 0.9}, Nenue@22: frontblend = 'BLEND', Nenue@28: frontalpha = 1, Nenue@22: frontborder = {1,0,0,1}, Nenue@22: backborder = {0,0,1,0.75}, Nenue@32: tagcolor = {}, Nenue@32: workspace = 1, Nenue@13: } Nenue@9: Nenue@4: Nenue@13: local function ScanAddOnList(cmd, ...) Nenue@0: local list_state Nenue@0: Nenue@14: local args = {} Nenue@14: local arg, n = D:GetArgs(cmd, 1) Nenue@14: while arg do Nenue@14: table.insert(args, arg) Nenue@14: arg, n = D:GetArgs(cmd,1,n) Nenue@14: end Nenue@14: local mode, tag, dest = unpack(args) Nenue@0: Nenue@13: Nenue@14: -- no args, toggle ui Nenue@32: if mode == 'dock' then Nenue@32: if #args <= 2 then Nenue@32: D:Print("Not enough arguments for dock command.") Nenue@32: return Nenue@32: end Nenue@0: Nenue@32: local target Nenue@32: local worklist = {} Nenue@32: for i = 2, #args do Nenue@32: local ch Nenue@32: local k = tostring(args[i]) Nenue@32: local j = tonumber(args[i]) Nenue@32: if db.channels[j] then Nenue@32: ch = db.channels[j] Nenue@32: elseif D.sig[k] then Nenue@32: ch = D.sig[k] Nenue@32: elseif D.sigID[k] then Nenue@32: ch = db.channels[D.sigID[k]] Nenue@32: elseif db.tags[k] and db.tags[k][1] then Nenue@32: ch = db.channels[db.tags[j][1]] Nenue@32: -- last resort Nenue@32: else Nenue@32: D:Print('No entry for argument #'..i..': '..tostring(args[i])) Nenue@32: return Nenue@32: end Nenue@32: oldprint(i, '->', ch.index, '-', ch.signature) Nenue@32: if i > 2 then Nenue@32: table.insert(worklist, ch.index) Nenue@32: else Nenue@32: target = ch Nenue@32: Nenue@32: oldprint('arg1', args[2], target) Nenue@32: end Nenue@0: end Nenue@32: D:Print("Docking |cFF88FFFF"..table.concat(worklist, "|r, |cFF88FFFF").."|r with |cFFFFFF00"..target.index..', '..target.signature.."|r.") Nenue@32: return D:DockFrame(target.index, unpack(worklist)) Nenue@32: Nenue@32: Nenue@14: elseif mode == 'stack' then Nenue@14: return D:StackFrames() Nenue@14: elseif mode == 'grid' then Nenue@14: return D:DistributeFrames() Nenue@14: elseif mode == 'tag' then -- tagging Nenue@32: Nenue@14: if tag ~= nil and dest ~= nil then Nenue@32: -- convert to ID Nenue@32: if tonumber(dest) == nil and D.sigID[dest] then Nenue@32: dest = db.channels[D.sigID[dest]].index Nenue@18: end Nenue@18: Nenue@32: -- make a new channel? Nenue@32: if not db.channels[dest] then Nenue@32: dest = db.max_channel + 1 Nenue@32: D:Print('Creating a new channel for '.. tag) Nenue@32: D:SetChannel(tag, dest) Nenue@32: end Nenue@32: Nenue@32: if db.tags[tag] and db.tags[tag][dest] then Nenue@32: db.tags[tag][dest] = nil Nenue@32: D:Print('Hiding |cFF88FFFF'..tag..'|r messages in |cFFFFFF00'..db.channels[dest].index ..':'.. db.channels[dest].index) Nenue@32: else Nenue@32: if not db.tags[tag] then Nenue@32: db.tags[tag] = {} Nenue@32: end Nenue@32: db.tags[tag][dest] = dest Nenue@32: D:Print('Showing |cFF88FFFF'..tag..'|r messages in |cFFFFFF00'..db.channels[dest].index ..':'.. db.channels[dest].index) Nenue@32: end Nenue@14: else Nenue@14: D:Print('Usage: /dvn tag ') Nenue@14: end Nenue@14: return Nenue@32: elseif tonumber(mode) ~= nil or mode == 'save' then Nenue@32: -- iterating for something Nenue@32: if mode == 'save' then Nenue@32: if tonumber(tag) == nil then Nenue@32: T:Print('Save ID is invalid:', tag) Nenue@32: end Nenue@32: list_state = tonumber(tag) Nenue@32: else Nenue@32: list_state = tonumber(mode) Nenue@32: db.workspace = list_state Nenue@0: end Nenue@32: elseif mode == nil then Nenue@32: list_state = db.last_workspace and db.last_workspace or 1 Nenue@32: else Nenue@32: return D:PrintHelp() Nenue@0: end Nenue@32: Nenue@32: -- start the iterating Nenue@0: local char_list, global_list = db[PLAYER_REALM][list_state], db.global[list_state] Nenue@0: local playername = UnitName("player") Nenue@0: Nenue@0: for i = 1, GetNumAddOns() do Nenue@0: local name = GetAddOnInfo(i) Nenue@0: local enableState, globalState = GetAddOnEnableState(playername, i), GetAddOnEnableState(nil, i) Nenue@0: Nenue@32: if mode == 'save' then Nenue@0: char_list[name] = enableState Nenue@0: global_list[name] = globalState Nenue@0: else Nenue@13: if char_list[name] or global_list[name] then Nenue@32: if char_list[name] ~= 0 and global_list[name] ~= 0 then Nenue@32: local value = false Nenue@32: if char_list[name] == 2 and global_list[name] == 1 then Nenue@32: value = UnitName("player") Nenue@32: elseif global_list[name] == 2 then Nenue@32: value = true Nenue@32: end Nenue@32: --print('EnableAddOn(', i, ',', value,')') Nenue@32: EnableAddOn(i, value) Nenue@32: else Nenue@32: local value = true Nenue@32: if char_list[name] == 2 and global_list[name] == 1 then Nenue@32: value = UnitName("player") Nenue@32: end Nenue@32: --print('DisableAddOn(', i, ',', value,')') Nenue@32: DisableAddOn(i,value) Nenue@0: end Nenue@0: else Nenue@32: if type(db.unlisted) ~= 'table' then Nenue@32: db.unlisted = {} Nenue@0: end Nenue@32: table.insert(db.unlisted, name) Nenue@13: end Nenue@0: Nenue@0: end Nenue@0: end Nenue@0: Nenue@32: if mode ~= 'save' then Nenue@32: db.load_message = "AddOn profile ".. list_state .." was loaded." Nenue@0: ReloadUI() Nenue@0: else Nenue@32: D:Print('Profile #'.. (list_state)..' saved.') Nenue@32: if list_state == 1 then Nenue@32: D:Print('This will be your main AddOn list.') Nenue@32: elseif list_state == db.default_list then Nenue@32: db.last_workspace = list_state Nenue@32: D:Print('This will be your default workspace') Nenue@32: end Nenue@0: end Nenue@0: end Nenue@0: Nenue@0: Nenue@13: local function Console_MinMax(self) Nenue@13: if self.minimized then Nenue@7: self:Maximize() Nenue@7: else Nenue@7: self:Minimize() Nenue@7: end Nenue@7: end Nenue@13: Nenue@13: local function Console_Minimize(self) Nenue@13: self:SetHeight(20) Nenue@13: self:SetMaxResize(GetScreenWidth(),20) Nenue@13: self.minimized = true Nenue@14: self.out:Hide() Nenue@14: self:Save() Nenue@7: end Nenue@0: Nenue@13: local function Console_Maximize(self) Nenue@13: local db = db.channels[self.index] Nenue@13: self:SetHeight(db.height) Nenue@13: self:SetMaxResize(GetScreenWidth(),GetScreenHeight()) Nenue@13: self.minimized = nil Nenue@14: self.out:Show() Nenue@14: self:Save() Nenue@13: end Nenue@13: Nenue@13: Nenue@13: local function Console_Save(self) Nenue@13: local db = db.channels[self.index] Nenue@14: if self.x then Nenue@14: db.x = self.x Nenue@14: else Nenue@14: db.x = self:GetLeft() Nenue@14: end Nenue@14: Nenue@14: if self.y then Nenue@14: db.y = self.y Nenue@14: else Nenue@14: db.y = (self:GetTop() - GetScreenHeight()) Nenue@14: end Nenue@14: Nenue@14: if self.width then Nenue@14: db.width = self.width Nenue@14: else Nenue@14: db.width = self:GetWidth() Nenue@14: end Nenue@14: Nenue@13: if not self.minimized then Nenue@14: if self.height then Nenue@14: db.height = self.height Nenue@14: else Nenue@14: db.height = self:GetHeight() Nenue@14: end Nenue@14: self:SetHeight(db.height) Nenue@13: end Nenue@14: Nenue@32: db.dockedTo = self.dockedTo Nenue@32: db.docked = self.docked Nenue@32: Nenue@14: db.minimized = self.minimized and true or nil Nenue@14: db.enabled = self:IsVisible() and true or nil Nenue@14: db.active = self.active and true or nil Nenue@17: --print('save:', db.signature, 'min=', db.minimized, ' enabled=', db.enabled, ' active = ', db.active, 'x=', db.x, 'y=', db.y, 'h=', db.height, 'w=', db.width) Nenue@13: self:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', db.x, db.y) Nenue@14: self:SetWidth(db.width) Nenue@13: end Nenue@13: Nenue@14: -- Console frame toggler Nenue@14: -- @paramsig [...] Nenue@14: -- @param ... one or more space-seperated channel keys Nenue@13: local function Console_Toggle(input) Nenue@14: local search = {} Nenue@28: local n = 0 Nenue@28: if D:GetArgs(input,1) then Nenue@14: repeat Nenue@28: key, n = D:GetArgs(input,1,n) Nenue@14: if D.sig[key] then Nenue@14: table.insert(search, D.sig[key]) Nenue@14: elseif D.console[key] then Nenue@14: table.insert(search, D.console[key]) Nenue@14: end Nenue@14: until n == 1e9 Nenue@13: else Nenue@13: search = D.console Nenue@13: end Nenue@13: Nenue@14: db.toggle = not db.toggle and true or nil Nenue@28: for i, c in ipairs(search) do Nenue@28: print(i,c.index) Nenue@14: if db.toggle then Nenue@28: c.enabled = true Nenue@14: c:Show() Nenue@26: if db.current_channel == c.index then Nenue@26: c:ToFront() Nenue@26: end Nenue@14: else Nenue@14: c.enabled = nil Nenue@14: c.minimized = nil Nenue@14: c:Maximize() Nenue@13: c:Hide() Nenue@13: end Nenue@13: end Nenue@14: Nenue@14: if db.toggle then Nenue@14: D:Print('toggled on?') Nenue@14: else Nenue@14: D:Print('toggled off?') Nenue@14: end Nenue@13: end Nenue@13: Nenue@18: --- Brings the console to the front. Nenue@18: -- Frame method used to bring a console frame to the front of the display stack. Nenue@14: local function Console_ToFront(c) Nenue@14: --print(D.raise_ct, 'Raising', c.signature) Nenue@14: --print(unpack(db.frontdrop)) Nenue@14: --print(unpack(db.frontgrad)) Nenue@14: --print(db.frontblend) Nenue@22: -- D.raise_ct = D.raise_ct + 1 Nenue@14: c:Raise() Nenue@28: c:SetAlpha(db.frontalpha) Nenue@14: c.out.backdrop:SetTexture(unpack(db.frontdrop)) Nenue@14: c.out.backdrop:SetGradientAlpha(unpack(db.frontgrad)) Nenue@14: c.out.backdrop:SetBlendMode(db.frontblend) Nenue@20: db.current_channel = c.index Nenue@18: Nenue@18: for _, part in pairs(c.border) do Nenue@24: part:SetTexture(unpack(db.frontborder)) Nenue@18: end Nenue@14: Nenue@14: for id, bc in pairs(D.console) do Nenue@14: if id ~= c.index then Nenue@14: --print(D.raise_ct, 'Lowering', bc.signature) Nenue@14: --print(unpack(db.backdrop)) Nenue@14: --print(unpack(db.backgrad)) Nenue@14: --print(db.backblend) Nenue@28: bc:SetAlpha(db.backalpha) Nenue@14: bc.out.backdrop:SetTexture(unpack(db.backdrop)) Nenue@14: bc.out.backdrop:SetGradientAlpha(unpack(db.backgrad)) Nenue@14: bc.out.backdrop:SetBlendMode(db.backblend) Nenue@18: Nenue@18: for _, part in pairs(bc.border) do Nenue@24: part:SetTexture(unpack(db.backborder)) Nenue@14: end Nenue@18: end Nenue@18: Nenue@14: end Nenue@14: Nenue@14: end Nenue@14: Nenue@32: local function Console_MouseDown(self, button, up) Nenue@32: if button == 'LeftButton' then Nenue@32: if up then Nenue@32: self:StopMovingOrSizing() Nenue@32: self:ToFront() Nenue@32: self.x = nil Nenue@32: self.y = nil Nenue@32: self.width = nil Nenue@32: self.height = nil Nenue@32: self:Save() Nenue@32: elseif self.out.grip:IsMouseOver() then Nenue@32: self:StartSizing() Nenue@32: else Nenue@32: self:StartMoving() Nenue@32: end Nenue@22: else Nenue@32: if up then Nenue@32: self:MinMax() Nenue@14: end Nenue@13: end Nenue@32: end Nenue@32: local function Console_MouseUp(self, button) Nenue@32: return Console_MouseDown(self, button, true) Nenue@13: end Nenue@13: Nenue@18: --- Creates a Devian-style output. Nenue@18: -- The first argument describes the channel to output on, and the remaining arguments are concatenated in a manner similar to default print() Nenue@18: -- This becomes the print handler when development mode is active. The original print() function is assigned to oldprint(). Nenue@18: -- @param Tag, signature, or numeric index of the channel to output on. Defaults to primary channel. Nenue@18: -- @param ... Output contents. Nenue@0: local function Message(prefix, ...) Nenue@24: if db.enabled == true then Nenue@23: return D.oldprint(prefix, ...) Nenue@23: end Nenue@23: Nenue@1: if prefix == nil then Nenue@13: prefix = 1 Nenue@1: end Nenue@9: Nenue@18: local sendq = {} Nenue@30: local tag, id, tagged Nenue@13: local byName = true Nenue@18: if D.tags[prefix] then Nenue@18: for _, id in pairs(D.tags[prefix]) do Nenue@18: if D.console[id] then Nenue@18: sendq[id] = D.console[id] Nenue@30: tagged = true Nenue@18: end Nenue@18: end Nenue@18: end Nenue@18: Nenue@13: if D.sig[prefix] then Nenue@18: sendq[D.sig[prefix].index] = D.sig[prefix] Nenue@13: elseif D.console[prefix] then Nenue@18: sendq[D.console[prefix]] = D.console[prefix] Nenue@30: elseif not tagged then Nenue@18: sendq[D.primary_channel] = D.console[D.primary_channel] Nenue@13: end Nenue@18: Nenue@9: -- color me timbers Nenue@9: local pcolor Nenue@18: if (not db.tagcolor[prefix]) and byName then Nenue@30: local c = { Nenue@30: math.random(64,255), math.random(64,255), math.random(64,255) Nenue@30: } Nenue@30: if c[1] > 223 and c[2] > 223 and c[3] > 223 then Nenue@30: c[math.random(1,3)] = math.random(64,223) Nenue@0: end Nenue@30: Nenue@18: db.tagcolor[prefix] = string.format('%02X%02X%02X', unpack(c)) Nenue@0: end Nenue@18: pcolor = db.tagcolor[prefix] Nenue@0: Nenue@18: local buffer = {'|cFF'.. pcolor..prefix ..'|r'} Nenue@0: for i = 1, select('#',...) do Nenue@0: local var = select(i, ...) Nenue@0: Nenue@0: if type(var) == 'table' then Nenue@20: if type(var.GetName) == 'function' then Nenue@32: var = '' Nenue@20: else Nenue@32: var = '<'..tostring(var)..'>' Nenue@20: end Nenue@20: Nenue@0: elseif type(var) == 'boolean' then Nenue@0: var = var and 'true' or 'false' Nenue@0: elseif type(var) == 'function' then Nenue@0: var = '' Nenue@0: elseif type(var) == 'nil' then Nenue@0: var = 'nil' Nenue@0: end Nenue@0: Nenue@0: table.insert(buffer, var) Nenue@0: end Nenue@18: local message = table.concat(buffer, ' ') Nenue@18: for id, channel in pairs(sendq) do Nenue@18: channel.out:AddMessage(message) Nenue@18: end Nenue@0: table.wipe(buffer) Nenue@0: end Nenue@0: Nenue@14: Nenue@32: --- Constructs the frame object for a console channel Nenue@32: -- Initializes the console channel at a specified index. Nenue@32: -- Configuration data can be overridden by passing a desired settings table. Nenue@32: -- @param i Numeric index of the channel as it manifests in db.channels Nenue@32: -- @param vars Optional settings table to be used. Nenue@32: local function CreateConsole(i, vars) Nenue@32: Nenue@32: if not vars then Nenue@32: vars = db.channels[i] Nenue@14: end Nenue@14: Nenue@32: --print('make:', vars.signature, '(', vars.x, vars.y, ')', vars.width, 'x', vars.height) Nenue@32: local f = CreateFrame('Frame', 'DevianChannelFrame' .. tostring(i), UIParent, DEVIAN_FRAME) Nenue@32: f:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', vars.x, vars.y) Nenue@32: f:SetSize(vars.width, vars.height) Nenue@32: f:Lower() Nenue@32: f.out:SetFont(db.font, db.fontsize, db.fontoutline) Nenue@32: if (db.current_channel == i) then Nenue@32: f.out.backdrop:SetTexture(unpack(db.frontdrop)) Nenue@32: else Nenue@32: f.out.backdrop:SetTexture(unpack(db.backdrop)) Nenue@32: end Nenue@14: Nenue@32: f.Save = Console_Save Nenue@32: f.Minimize = Console_Minimize Nenue@32: f.Maximize = Console_Maximize Nenue@32: f.MinMax = Console_MinMax Nenue@32: f.ToFront = Console_ToFront Nenue@32: f.Toggle = D.Console_Toggle Nenue@32: f.name = vars.name Nenue@32: f.index = i Nenue@32: f.signature = vars.signature Nenue@32: f.format = vars.header Nenue@32: f.x = vars.x Nenue@32: f.y = vars.y Nenue@32: f.width = vars.width Nenue@32: f.height = vars.height Nenue@32: f.docked = vars.docked Nenue@32: f.dockedTo = vars.dockedTo Nenue@32: Nenue@32: f:SetScript('OnMouseDown', Console_MouseDown) Nenue@32: f:SetScript('OnMouseUp', Console_MouseUp) Nenue@32: if vars.enabled then Nenue@32: f.enabled = true Nenue@32: if db.toggle then Nenue@32: f:Show() Nenue@14: end Nenue@14: end Nenue@32: if vars.minimized then Nenue@32: f:Minimize() Nenue@32: else Nenue@32: f:Maximize() Nenue@32: end Nenue@32: Nenue@32: return f Nenue@14: end Nenue@14: Nenue@18: --- Updates a console "channel" entry, generating a new one if necessary. Nenue@18: -- Config data will be take from cinfo. If cinfo is a string, then only channel signature is set. The remaining variables are filled in from the primary channel. Nenue@18: -- i can be given to select a specific channel table entry to work on. Otherwise, it will just create a new channel and the frame associated with it. Nenue@18: -- @usage cinfo [, i] Nenue@18: -- @param cinfo Config variables table, or a string to be used as channel signature Nenue@18: -- @param i Console index. If valid, settings will be inherited from that channel. Nenue@14: function D:SetChannel(cinfo, i) Nenue@32: -- try to resolve from arguments Nenue@32: local dbvars Nenue@14: local t_info = {} Nenue@32: local channel Nenue@32: local isNew Nenue@32: if type(i) =='number' and db.channels[i] then Nenue@32: dbvars = db.channels[i] Nenue@32: elseif type(i) == 'string' and D.sig[i] then Nenue@32: dbvars = db.channels[D.sig[i].index] Nenue@32: else Nenue@32: dbvars = db.channels[db.primary_channel] Nenue@32: isNew = true Nenue@32: end Nenue@28: Nenue@32: --@debug@ Nenue@32: print('setchan(1)', cinfo, i, isNew)--@end-debug@ Nenue@32: Nenue@32: if type(cinfo) == 'string' and not db.sig[cinfo] then Nenue@32: t_info.signature = cinfo Nenue@32: cinfo = {} Nenue@32: elseif type(cinfo) ~= 'table' then Nenue@32: error('Expecting table of string as arg1') Nenue@32: end Nenue@32: Nenue@32: --@debug@ Nenue@32: print('setchan(2)', cinfo, i, isNew)--@end-debug@ Nenue@32: Nenue@32: --TODO: figure out why tag assignments are getting eaten Nenue@28: -- is cinfo a table or signature? Nenue@32: Nenue@32: Nenue@18: Nenue@28: -- did we get a signature string? Nenue@28: if not (cinfo.signature or t_info.signature) then Nenue@32: t_info.signature = 'noname' Nenue@28: end Nenue@28: Nenue@32: --@debug@ Nenue@32: print('setchan(3)', cinfo, i, isNew, t_info.signature)--@end-debug@ Nenue@32: -- look for existing sigs Nenue@32: if D.sig[t_info.signature] then Nenue@32: local sigvar = t_info.signature Nenue@32: local j = 2 Nenue@32: while D.sig[sigvar] do Nenue@32: sigvar = sigvar .. j Nenue@32: j = j + 1 Nenue@14: end Nenue@32: t_info.signature = sigvar Nenue@14: end Nenue@14: Nenue@32: --@debug@ Nenue@32: print('setchan(4)', cinfo, i, isNew, t_info.signature)--@end-debug@ Nenue@28: -- can proceed to fill in from base vars here Nenue@18: for k,v in pairs(dbvars) do Nenue@14: if not t_info[k] then Nenue@14: if cinfo[k] then Nenue@14: t_info[k] = cinfo[k] Nenue@32: --@debug@ Nenue@32: print('setchan(5a)', 'cinfo', k)--@end-debug@ Nenue@18: elseif db.channels[self.primary_channel][k] then Nenue@18: t_info[k] = db.channels[self.primary_channel][k] Nenue@32: --@debug@ Nenue@32: print('setchan(5b)', 'db', self.primary_channel, k)--@end-debug@ Nenue@14: end Nenue@14: end Nenue@14: end Nenue@14: Nenue@28: -- we're working with a fresh channel right? Nenue@32: if isNew then Nenue@32: i = D.num_channels + 1 Nenue@32: t_info.index = i Nenue@14: t_info.x = t_info.x + 20 Nenue@14: t_info.y = t_info.y - 20 Nenue@14: db.channels[i] = t_info Nenue@32: --@debug@ Nenue@32: print('setchan(6)', 'new index', i)--@end-debug@ Nenue@14: end Nenue@18: Nenue@28: -- can proceed to display something from here Nenue@14: if not self.console[i] then Nenue@14: self.console[i] = CreateConsole(i, t_info) Nenue@28: -- if it isn't already spawned, create the frame Nenue@32: --@debug@ Nenue@32: print('setchan(7)', 'new console', i)--@end-debug@ Nenue@14: end Nenue@18: local channel = self.console[i] Nenue@18: self.sig[t_info.signature] = channel Nenue@18: self.sigID[t_info.signature] = i Nenue@18: self.IDsig[i] = t_info.signature Nenue@20: Nenue@32: --@debug@ Nenue@32: print('setchan(8)', 'end', self.sig[t_info.signature], self.sigID[t_info.signature], self.IDsig[i], self.docked)--@end-debug@ Nenue@18: return channel Nenue@14: end Nenue@14: Nenue@32: function D:PrintHelp() Nenue@32: D:Print("|cFFFFFF00/dvn|r", Nenue@32: "\n |cFFFFFF00|r - Loads a saved addon list. List 1 is treated as a gameplay profile and consoles will be disabled by default.") Nenue@32: Nenue@32: D:Print("|cFFFFFF00/resetdvn|r", "- Resets all but profile data SavedVariables.") Nenue@32: D:Print("|cFFFFFF00/cleandvn|r", "- Fully resets SavedVariables, profiles and all.") Nenue@32: end Nenue@32: Nenue@0: function D:OnEnable() Nenue@13: -- commands Nenue@13: local cmdlist = { Nenue@13: ['dvn'] = ScanAddOnList, Nenue@13: ['devian'] = ScanAddOnList, Nenue@13: ['dvc'] = Console_Toggle, Nenue@13: } Nenue@13: for cmd, func in pairs(cmdlist) do Nenue@13: self:RegisterChatCommand(cmd, func, true) Nenue@13: end Nenue@13: Nenue@32: if db.workspace == 1 then Nenue@32: D:Print('Gameplay mode active. Print handling turned |cFFFFFF00OFF|r..') Nenue@0: else Nenue@32: D:Print('Development mode active (list #'..db.workspace..'). Print handling |cFF00FF00ON|r.') Nenue@0: end Nenue@13: Nenue@0: end Nenue@0: Nenue@0: function D:OnInitialize() Nenue@13: -- emergency button Nenue@13: self:RegisterChatCommand("cleandvn", function(args) Nenue@13: DevianDB = nil Nenue@13: ReloadUI() Nenue@13: end) Nenue@32: self:RegisterChatCommand("resetdvn", function(args) Nenue@32: for k,v in pairs(DevianDB) do Nenue@32: if k ~= 'global' then Nenue@32: DevianDB[k] = nil Nenue@32: end Nenue@32: end Nenue@32: Nenue@32: for k,v in pairs(defaults) do Nenue@32: DevianDB[k] = v Nenue@32: end Nenue@32: ReloadUI() Nenue@32: end) Nenue@13: Nenue@13: -- savedvars Nenue@13: local cherry = false Nenue@9: if not _G.DevianDB then Nenue@13: _G.DevianDB = defaults Nenue@9: end Nenue@9: db = _G.DevianDB Nenue@32: self.tags = db.tags Nenue@32: self.channelinfo = db.channels Nenue@0: Nenue@0: if not db[PLAYER_REALM] then Nenue@32: db[PLAYER_REALM] = {[WORKSPACE_ON] = {}, [WORKSPACE_OFF] = {}} Nenue@0: end Nenue@0: Nenue@32: if db.load_message then Nenue@32: D:Print(db.load_message) Nenue@32: db.load_message = nil Nenue@0: end Nenue@0: D.oldprint = getprinthandler() Nenue@0: if not _G.oldprint then Nenue@0: _G.oldprint = D.oldprint Nenue@0: end Nenue@13: Nenue@22: --self.raise_ct = 0 Nenue@32: self.max_channel = 0 Nenue@14: self.num_channels = 0 Nenue@13: self.console = {} Nenue@13: self.sig = {} Nenue@14: self.sigID = {} Nenue@14: self.IDsig = {} Nenue@14: for i, cinfo in pairs(db.channels) do Nenue@14: i = tonumber(i) Nenue@14: if not self.primary_channel then Nenue@14: self.primary_channel = i Nenue@14: end Nenue@14: self:SetChannel(cinfo, i) Nenue@32: self.max_channel = math.max(i, self.max_channel) Nenue@32: self.num_channels = self.num_channels + 1 Nenue@32: end Nenue@32: Nenue@32: for i, channel in pairs(db.channels) do Nenue@32: if type(channel.docked) == 'table' then Nenue@32: oldprint('docking',i, unpack(channel.docked)) Nenue@32: self.DockFrame(i, unpack(channel.docked)) Nenue@14: end Nenue@13: end Nenue@18: Nenue@18: if self.console[db.current_channel] then Nenue@18: self.console[db.current_channel]:ToFront() Nenue@28: -- bring the current channel to the front Nenue@18: end Nenue@18: Nenue@23: if db.enabled then Nenue@24: for i, c in pairs(self.console) do Nenue@23: self.console[i]:Hide() Nenue@23: end Nenue@23: end Nenue@23: Nenue@23: Nenue@18: -- only do this in dev mode Nenue@32: if db.workspace > 1 then Nenue@32: Nenue@18: setprinthandler(Message) Nenue@18: print = function(...) Nenue@18: _G.print('Dvn', ...) Nenue@18: end Nenue@18: end Nenue@13: print(MAJOR, MINOR) Nenue@0: end