# HG changeset patch # User Nenue # Date 1451184717 18000 # Node ID c6a2c2df4790863166cdc5d0b25946e15deebac3 # Parent 6fcfe60bbd0f838729d33c974b97801eeba336e8 v2 work diff -r 6fcfe60bbd0f -r c6a2c2df4790 Devian.lua --- a/Devian.lua Sat Dec 26 05:18:24 2015 -0500 +++ b/Devian.lua Sat Dec 26 21:51:57 2015 -0500 @@ -1,28 +1,31 @@ --- User: Krakyn --- Created: 11/30/2015 7:46 AM +--- ${PACKAGE_NAME} +-- @file-author@ +-- @project-revision@ @project-hash@ +-- @file-revision@ @file-hash@ if not LibStub then print('Something has happened...') end Devian = LibStub("AceAddon-3.0"):NewAddon("Devian", "AceConsole-3.0", "AceEvent-3.0") local MAJOR, MINOR = 'Devian-1.3', 'r@project-revision@' local D = _G.Devian -local STATE_LOW, STATE_HIGH = 1, 2 +local WORKSPACE_ON, WORKSPACE_OFF = 1, 2 local PLAYER_REALM = UnitName("player") .. '-' .. GetRealmName() local DEVIAN_FRAME = 'DevianConsole' local print = _G.print local db local defaults = { - ['global'] = {[STATE_LOW] = {}, [STATE_HIGH] = {}}, + ['global'] = {{}, {}}, ['tags'] = {}, - ['channels'] = {[1] = {signature = 'Dvn', name = 'Main', header = "%n [%t]", x = 100, y = 800, height = 500, width = 600, enabled = true}}, + ['channels'] = {[1] = {signature = 'Main', index = 1, x = 100, y = 800, height = 500, width = 600, enabled = true}}, primary_channel = 1, current_channel = 1, + max_channel = 1, toggle = true, - dnd_status = true, - dnd_message = "Debugging. Your messages may get eaten.", + load_message = "Defaults loaded.", font = [[Interface\Addons\Devian\font\SourceCodePro-Regular.ttf]], fontsize = 13, fontoutline = 'NONE', + headergrab = {'VERTICAL', 0, 0, 0, 0.5, 0.1, 0.1, 0.1, 0.3}, backalpha = 0.5, backdrop = {0,0,0,0.4}, backgrad = {'VERTICAL', 0.1, 0.1, 0.1, 0.3, 0, 0, 0, 0.5}, @@ -33,6 +36,8 @@ frontalpha = 1, frontborder = {1,0,0,1}, backborder = {0,0,1,0.75}, + tagcolor = {}, + workspace = 1, } @@ -49,86 +54,145 @@ -- no args, toggle ui - if mode == nil then - list_state = db.enabled and STATE_LOW or STATE_HIGH - db.enabled = (db.enabled == false) and true or false - --print(list_state, db.enabled) + if mode == 'dock' then + if #args <= 2 then + D:Print("Not enough arguments for dock command.") + return + end - if list_state == STATE_LOW then + local target + local worklist = {} + for i = 2, #args do + local ch + local k = tostring(args[i]) + local j = tonumber(args[i]) + if db.channels[j] then + ch = db.channels[j] + elseif D.sig[k] then + ch = D.sig[k] + elseif D.sigID[k] then + ch = db.channels[D.sigID[k]] + elseif db.tags[k] and db.tags[k][1] then + ch = db.channels[db.tags[j][1]] + -- last resort + else + D:Print('No entry for argument #'..i..': '..tostring(args[i])) + return + end + oldprint(i, '->', ch.index, '-', ch.signature) + if i > 2 then + table.insert(worklist, ch.index) + else + target = ch + + oldprint('arg1', args[2], target) + end end + D:Print("Docking |cFF88FFFF"..table.concat(worklist, "|r, |cFF88FFFF").."|r with |cFFFFFF00"..target.index..', '..target.signature.."|r.") + return D:DockFrame(target.index, unpack(worklist)) + + elseif mode == 'stack' then return D:StackFrames() elseif mode == 'grid' then return D:DistributeFrames() elseif mode == 'tag' then -- tagging + if tag ~= nil and dest ~= nil then - local channel = D:SetChannel(dest:match('%a+'), dest:match('%d+')) - if not D.tags[tag] then - D.tags[tag] = {} - end - if D.tags[tag][channel.index] then - D.tags[tag][channel.index] = nil - D:Print('Removed |cFFFFFF00'..tag..'|r to |cFF00FFFF['..channel.index..', '..channel.signature..']|r') - else - D.tags[tag][channel.index] = channel.index - D:Print('Assigning |cFFFFFF00'..tag..'|r to |cFF00FFFF['..channel.index..', '..channel.signature..']|r') + -- convert to ID + if tonumber(dest) == nil and D.sigID[dest] then + dest = db.channels[D.sigID[dest]].index end + -- make a new channel? + if not db.channels[dest] then + dest = db.max_channel + 1 + D:Print('Creating a new channel for '.. tag) + D:SetChannel(tag, dest) + end + + if db.tags[tag] and db.tags[tag][dest] then + db.tags[tag][dest] = nil + D:Print('Hiding |cFF88FFFF'..tag..'|r messages in |cFFFFFF00'..db.channels[dest].index ..':'.. db.channels[dest].index) + else + if not db.tags[tag] then + db.tags[tag] = {} + end + db.tags[tag][dest] = dest + D:Print('Showing |cFF88FFFF'..tag..'|r messages in |cFFFFFF00'..db.channels[dest].index ..':'.. db.channels[dest].index) + end else D:Print('Usage: /dvn tag ') end return - elseif mode ~= nil then - mode = tonumber(mode) - if mode > 2 then - --print('Something has happened.') - return + elseif tonumber(mode) ~= nil or mode == 'save' then + -- iterating for something + if mode == 'save' then + if tonumber(tag) == nil then + T:Print('Save ID is invalid:', tag) + end + list_state = tonumber(tag) + else + list_state = tonumber(mode) + db.workspace = list_state end - list_state = mode == STATE_LOW and STATE_LOW or STATE_HIGH + elseif mode == nil then + list_state = db.last_workspace and db.last_workspace or 1 + else + return D:PrintHelp() end + + -- start the iterating local char_list, global_list = db[PLAYER_REALM][list_state], db.global[list_state] - local playername = UnitName("player") for i = 1, GetNumAddOns() do local name = GetAddOnInfo(i) local enableState, globalState = GetAddOnEnableState(playername, i), GetAddOnEnableState(nil, i) - if mode == STATE_LOW or mode == STATE_HIGH then + if mode == 'save' then char_list[name] = enableState global_list[name] = globalState else if char_list[name] or global_list[name] then - - if char_list[name] ~= 0 and global_list[name] ~= 0 then - local value = false - if char_list[name] == 2 and global_list[name] == 1 then - value = UnitName("player") - elseif global_list[name] == 2 then - value = true + if char_list[name] ~= 0 and global_list[name] ~= 0 then + local value = false + if char_list[name] == 2 and global_list[name] == 1 then + value = UnitName("player") + elseif global_list[name] == 2 then + value = true + end + --print('EnableAddOn(', i, ',', value,')') + EnableAddOn(i, value) + else + local value = true + if char_list[name] == 2 and global_list[name] == 1 then + value = UnitName("player") + end + --print('DisableAddOn(', i, ',', value,')') + DisableAddOn(i,value) end - --print('EnableAddOn(', i, ',', value,')') - EnableAddOn(i, value) else - local value = true - if char_list[name] == 2 and global_list[name] == 1 then - value = UnitName("player") + if type(db.unlisted) ~= 'table' then + db.unlisted = {} end - --print('DisableAddOn(', i, ',', value,')') - DisableAddOn(i,value) - end + table.insert(db.unlisted, name) end end end - if mode == nil then + if mode ~= 'save' then + db.load_message = "AddOn profile ".. list_state .." was loaded." ReloadUI() - end - if mode == STATE_LOW then - D:Print('Developement AddOn list saved.') else - D:Print('Standard AddOn list saved.') + D:Print('Profile #'.. (list_state)..' saved.') + if list_state == 1 then + D:Print('This will be your main AddOn list.') + elseif list_state == db.default_list then + db.last_workspace = list_state + D:Print('This will be your default workspace') + end end end @@ -188,6 +252,9 @@ self:SetHeight(db.height) end + db.dockedTo = self.dockedTo + db.docked = self.docked + db.minimized = self.minimized and true or nil db.enabled = self:IsVisible() and true or nil db.active = self.active and true or nil @@ -278,57 +345,29 @@ end ---- Constructs the frame object for a console channel --- Initializes the console channel at a specified index. --- Configuration data can be overridden by passing a desired settings table. --- @param i Numeric index of the channel as it manifests in db.channels --- @param vars Optional settings table to be used. -local function CreateConsole(i, vars) - - if not vars then - vars = db.channels[i] - end - - --print('make:', vars.signature, '(', vars.x, vars.y, ')', vars.width, 'x', vars.height) - local f = CreateFrame('Frame', 'DevianChannelFrame' .. tostring(i), UIParent, DEVIAN_FRAME) - f:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', vars.x, vars.y) - f:SetSize(vars.width, vars.height) - f:Lower() - f.out:SetFont(db.font, db.fontsize, db.fontoutline) - if (db.current_channel == i) then - f.out.backdrop:SetTexture(unpack(db.frontdrop)) +local function Console_MouseDown(self, button, up) + if button == 'LeftButton' then + if up then + self:StopMovingOrSizing() + self:ToFront() + self.x = nil + self.y = nil + self.width = nil + self.height = nil + self:Save() + elseif self.out.grip:IsMouseOver() then + self:StartSizing() + else + self:StartMoving() + end else - f.out.backdrop:SetTexture(unpack(db.backdrop)) - end - - f.Save = Console_Save - f.Minimize = Console_Minimize - f.Maximize = Console_Maximize - f.MinMax = Console_MinMax - f.ToFront = Console_ToFront - f.Toggle = D.Console_Toggle - f.name = vars.name - f.index = i - f.signature = vars.signature - f.format = vars.header - f.x = vars.x - f.y = vars.y - f.width = vars.width - f.height = vars.height - - if vars.enabled then - f.enabled = true - if db.toggle then - f:Show() + if up then + self:MinMax() end end - if vars.minimized then - f:Minimize() - else - f:Maximize() - end - - return f +end +local function Console_MouseUp(self, button) + return Console_MouseDown(self, button, true) end --- Creates a Devian-style output. @@ -385,9 +424,9 @@ if type(var) == 'table' then if type(var.GetName) == 'function' then - var = '' + var = '' else - var = '' + var = '<'..tostring(var)..'>' end elseif type(var) == 'boolean' then @@ -407,42 +446,62 @@ table.wipe(buffer) end ---- Spaces each frame evenly across the screen. -function D:DistributeFrames() -- - --print('frame grid:', max, num_side) - local max = self.num_channels - local num_side = math.ceil(math.sqrt(max)) - local w = GetScreenWidth() / num_side - local h = GetScreenHeight() / num_side - for i, frame in pairs(D.console) do - local dx = (i-1) % num_side - local dy = math.floor((i-1) / num_side) - --print('move:', frame.signature, 'dx=', dx, 'dy=', dy) - --print('move:', frame.signature, ' x=', dx * w, 'y=', -(dy * h), 'h=', h, 'w=', w) - frame.width = w - frame.height = h - frame.x = dx * w - frame.y = -(dy * h) - frame:Save() +--- Constructs the frame object for a console channel +-- Initializes the console channel at a specified index. +-- Configuration data can be overridden by passing a desired settings table. +-- @param i Numeric index of the channel as it manifests in db.channels +-- @param vars Optional settings table to be used. +local function CreateConsole(i, vars) + + if not vars then + vars = db.channels[i] end -end + --print('make:', vars.signature, '(', vars.x, vars.y, ')', vars.width, 'x', vars.height) + local f = CreateFrame('Frame', 'DevianChannelFrame' .. tostring(i), UIParent, DEVIAN_FRAME) + f:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', vars.x, vars.y) + f:SetSize(vars.width, vars.height) + f:Lower() + f.out:SetFont(db.font, db.fontsize, db.fontoutline) + if (db.current_channel == i) then + f.out.backdrop:SetTexture(unpack(db.frontdrop)) + else + f.out.backdrop:SetTexture(unpack(db.backdrop)) + end ---- Place all frames stacked beneath the primary frame. -function D:StackFrames() - local last - for i, frame in pairs(self.console) do - if last then - frame.x = last.x - frame.y = last.y - 20 - else - frame.x = (GetScreenWidth()-frame:GetWidth())/2 - frame.y = 0 + f.Save = Console_Save + f.Minimize = Console_Minimize + f.Maximize = Console_Maximize + f.MinMax = Console_MinMax + f.ToFront = Console_ToFront + f.Toggle = D.Console_Toggle + f.name = vars.name + f.index = i + f.signature = vars.signature + f.format = vars.header + f.x = vars.x + f.y = vars.y + f.width = vars.width + f.height = vars.height + f.docked = vars.docked + f.dockedTo = vars.dockedTo + + f:SetScript('OnMouseDown', Console_MouseDown) + f:SetScript('OnMouseUp', Console_MouseUp) + if vars.enabled then + f.enabled = true + if db.toggle then + f:Show() end - frame:Save() - last = frame end + if vars.minimized then + f:Minimize() + else + f:Maximize() + end + + return f end --- Updates a console "channel" entry, generating a new one if necessary. @@ -452,87 +511,109 @@ -- @param cinfo Config variables table, or a string to be used as channel signature -- @param i Console index. If valid, settings will be inherited from that channel. function D:SetChannel(cinfo, i) - --print('join:', i , cinfo) + -- try to resolve from arguments + local dbvars local t_info = {} - local dbvars = db.channels[self.primary_channel] - local signame + local channel + local isNew + if type(i) =='number' and db.channels[i] then + dbvars = db.channels[i] + elseif type(i) == 'string' and D.sig[i] then + dbvars = db.channels[D.sig[i].index] + else + dbvars = db.channels[db.primary_channel] + isNew = true + end + --@debug@ + print('setchan(1)', cinfo, i, isNew)--@end-debug@ + + if type(cinfo) == 'string' and not db.sig[cinfo] then + t_info.signature = cinfo + cinfo = {} + elseif type(cinfo) ~= 'table' then + error('Expecting table of string as arg1') + end + + --@debug@ + print('setchan(2)', cinfo, i, isNew)--@end-debug@ + + --TODO: figure out why tag assignments are getting eaten -- is cinfo a table or signature? - if type(cinfo) == 'string' then - signame = tostring(cinfo) - t_info.signature = signame - elseif type(cinfo) ~= 'table' then - cinfo = {} - end + + -- did we get a signature string? if not (cinfo.signature or t_info.signature) then - t_info.signature = 'Console' + t_info.signature = 'noname' end - -- was an index given? - if D.sigID[t_info.signature] then - i = D.sigID[t_info.signature] - -- the signature has one - elseif not i then - i = D.num_channels + 1 - t_info.index = i - -- or we need to make a new one - else - i = tonumber(i) - -- is it valid? - if db.channels[i] then - dbvars = db.channels[i] - -- that is our base vars - else - if D.sig[t_info.signature] then - local sigvar = t_info.signature - local j = 2 - while D.sig[sigvar] do - sigvar = sigvar .. j - j = j + 1 - end - t_info.signature = sigvar - end - - i = D.num_channels + 1 - t_info.index = i - -- make a new index number and fix the signature + --@debug@ + print('setchan(3)', cinfo, i, isNew, t_info.signature)--@end-debug@ + -- look for existing sigs + if D.sig[t_info.signature] then + local sigvar = t_info.signature + local j = 2 + while D.sig[sigvar] do + sigvar = sigvar .. j + j = j + 1 end + t_info.signature = sigvar end + --@debug@ + print('setchan(4)', cinfo, i, isNew, t_info.signature)--@end-debug@ -- can proceed to fill in from base vars here for k,v in pairs(dbvars) do if not t_info[k] then if cinfo[k] then t_info[k] = cinfo[k] + --@debug@ + print('setchan(5a)', 'cinfo', k)--@end-debug@ elseif db.channels[self.primary_channel][k] then t_info[k] = db.channels[self.primary_channel][k] + --@debug@ + print('setchan(5b)', 'db', self.primary_channel, k)--@end-debug@ end end end -- we're working with a fresh channel right? - if not db.channels[i] then + if isNew then + i = D.num_channels + 1 + t_info.index = i t_info.x = t_info.x + 20 t_info.y = t_info.y - 20 db.channels[i] = t_info - -- set its position just off of the base vars and store it + --@debug@ + print('setchan(6)', 'new index', i)--@end-debug@ end -- can proceed to display something from here if not self.console[i] then self.console[i] = CreateConsole(i, t_info) -- if it isn't already spawned, create the frame + --@debug@ + print('setchan(7)', 'new console', i)--@end-debug@ end local channel = self.console[i] self.sig[t_info.signature] = channel self.sigID[t_info.signature] = i self.IDsig[i] = t_info.signature + --@debug@ + print('setchan(8)', 'end', self.sig[t_info.signature], self.sigID[t_info.signature], self.IDsig[i], self.docked)--@end-debug@ return channel end +function D:PrintHelp() + D:Print("|cFFFFFF00/dvn|r", + "\n |cFFFFFF00|r - Loads a saved addon list. List 1 is treated as a gameplay profile and consoles will be disabled by default.") + + D:Print("|cFFFFFF00/resetdvn|r", "- Resets all but profile data SavedVariables.") + D:Print("|cFFFFFF00/cleandvn|r", "- Fully resets SavedVariables, profiles and all.") +end + function D:OnEnable() -- commands local cmdlist = { @@ -544,10 +625,10 @@ self:RegisterChatCommand(cmd, func, true) end - if db.enabled == true then - D:Print('Standard AddOn list active. Type /dvn to switch to development mode.') + if db.workspace == 1 then + D:Print('Gameplay mode active. Print handling turned |cFFFFFF00OFF|r..') else - D:Print('Development AddOn list active. Type /dvn to revert to regular operation.') + D:Print('Development mode active (list #'..db.workspace..'). Print handling |cFF00FF00ON|r.') end end @@ -558,29 +639,35 @@ DevianDB = nil ReloadUI() end) + self:RegisterChatCommand("resetdvn", function(args) + for k,v in pairs(DevianDB) do + if k ~= 'global' then + DevianDB[k] = nil + end + end + + for k,v in pairs(defaults) do + DevianDB[k] = v + end + ReloadUI() + end) -- savedvars local cherry = false if not _G.DevianDB then _G.DevianDB = defaults - cherry = "Type /dvnsave to snapshot your current UI" end db = _G.DevianDB + self.tags = db.tags + self.channelinfo = db.channels if not db[PLAYER_REALM] then - db[PLAYER_REALM] = {[STATE_LOW] = {}, [STATE_HIGH] = {}} - if not cherry then - cherry = "This character didn't have an AddOn table." - end + db[PLAYER_REALM] = {[WORKSPACE_ON] = {}, [WORKSPACE_OFF] = {}} end - - if not db.tags then - db.tags = {} - end - self.tags = db.tags - if cherry then - D:Print(cherry) + if db.load_message then + D:Print(db.load_message) + db.load_message = nil end D.oldprint = getprinthandler() if not _G.oldprint then @@ -588,7 +675,7 @@ end --self.raise_ct = 0 - self.last_channel = 0 + self.max_channel = 0 self.num_channels = 0 self.console = {} self.sig = {} @@ -600,10 +687,15 @@ self.primary_channel = i end self:SetChannel(cinfo, i) - if i > self.last_channel then - self.last_channel = i + self.max_channel = math.max(i, self.max_channel) + self.num_channels = self.num_channels + 1 + end + + for i, channel in pairs(db.channels) do + if type(channel.docked) == 'table' then + oldprint('docking',i, unpack(channel.docked)) + self.DockFrame(i, unpack(channel.docked)) end - self.num_channels = self.num_channels + 1 end if self.console[db.current_channel] then @@ -619,7 +711,8 @@ -- only do this in dev mode - if db.enabled == false then + if db.workspace > 1 then + setprinthandler(Message) print = function(...) _G.print('Dvn', ...) diff -r 6fcfe60bbd0f -r c6a2c2df4790 Devian.toc --- a/Devian.toc Sat Dec 26 05:18:24 2015 -0500 +++ b/Devian.toc Sat Dec 26 21:51:57 2015 -0500 @@ -1,12 +1,10 @@ --- User: Krakyn --- Created: 11/30/2015 7:44 AM - ## Interface: 60200 ## Title: Devian ## Notes: Addon toggler for lua development ## Author: Krakyn ## Version: 1.2 @project-revision@ ## SavedVariables: DevianDB -## Deps: Ace3 +## OptionalDeps: Ace3 Devian.xml -Devian.lua \ No newline at end of file +Devian.lua +Dock.lua \ No newline at end of file diff -r 6fcfe60bbd0f -r c6a2c2df4790 Devian.xml --- a/Devian.xml Sat Dec 26 05:18:24 2015 -0500 +++ b/Devian.xml Sat Dec 26 21:51:57 2015 -0500 @@ -1,4 +1,9 @@ + +