# HG changeset patch # User Nenue # Date 1450590402 18000 # Node ID 5254d1ba6013ec64d8e867c5df205fd62e204cf2 # Parent 080dfa4990fbfd3754fe817ad18ddefe33af2066 Multiple output windows can be created for different output prefixes, and prefixes can be designated to an existing or new "console" with /dvn Frame objects are generated directly from XML data, and their state information is stored in the object itself to resolve issues with GetWidth() returning old info in some cases. StackFrames and DistributeFrames methods can be invoked from /script to arrange the buffers. diff -r 080dfa4990fb -r 5254d1ba6013 Devian.lua --- a/Devian.lua Sat Dec 19 07:59:12 2015 -0500 +++ b/Devian.lua Sun Dec 20 00:46:42 2015 -0500 @@ -17,23 +17,36 @@ ['global'] = {[STATE_LOW] = {}, [STATE_HIGH] = {}}, ['tags'] = {}, ['channels'] = {[1] = {signature = 'Dvn', name = 'Main', header = "%n [%t]", x = 100, y = 800, height = 500, width = 600, enabled = true}}, + primary_channel = 1, current_channel = 1, - console = true, + toggle = true, dnd_status = true, dnd_message = "Debugging. Your messages may get eaten.", font = [[Interface\Addons\Devian\font\SourceCodePro-Regular.ttf]], fontsize = 13, fontoutline = 'NONE', + backdrop = {1,1,1,0.2}, + backgrad = {'VERTICAL', 0.1, 0.1, 0.1, 0.3, 0, 0, 0, 0.5}, + backblend = 'BLEND', + frontdrop = {1,1,1,1}, + frontgrad = {'VERTICAL', 0.1, 0.1, 0.1, 0.9, 0, 0, 0, 0.9}, + frontblend = 'BLEND' } local function ScanAddOnList(cmd, ...) local list_state - local mode = tonumber(cmd:match("%d")) + local args = {} + local arg, n = D:GetArgs(cmd, 1) + while arg do + table.insert(args, arg) + arg, n = D:GetArgs(cmd,1,n) + end + local mode, tag, dest = unpack(args) - print('Starting Addons scan. arg=', mode) + -- 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 @@ -41,15 +54,35 @@ if list_state == STATE_LOW then end - - else + 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 + if not D.console[dest] and not D.sig[dest] then + local sig = dest:match('%a') + local id = dest:match('%d') + if not id then + id = self.last_channel + 1 + end + if not sig then + sig = tag + end + D:SetChannel(sig, id) + end + D:Print('Assigning |cFFFFFF00'..tag..'|r to |cFF00FFFF'.. dest .. '|r') + else + D:Print('Usage: /dvn tag ') + end + return + elseif mode ~= nil then + mode = tonumber(mode) if mode > 2 then print('Something has happened.') return end list_state = mode == STATE_LOW and STATE_LOW or STATE_HIGH - - end local char_list, global_list = db[PLAYER_REALM][list_state], db.global[list_state] @@ -110,7 +143,8 @@ self:SetHeight(20) self:SetMaxResize(GetScreenWidth(),20) self.minimized = true - return self.out:Hide() + self.out:Hide() + self:Save() end local function Console_Maximize(self) @@ -118,59 +152,125 @@ self:SetHeight(db.height) self:SetMaxResize(GetScreenWidth(),GetScreenHeight()) self.minimized = nil - self.grip:SetTexture(0.5,0.5,0.5) - return self.out:Show() + self.out:Show() + self:Save() end local function Console_Save(self) local db = db.channels[self.index] - db.y = (self:GetTop() - GetScreenHeight()) - db.x = self:GetLeft() - db.width = self:GetWidth() + if self.x then + db.x = self.x + else + db.x = self:GetLeft() + end + + if self.y then + db.y = self.y + else + db.y = (self:GetTop() - GetScreenHeight()) + end + + if self.width then + db.width = self.width + else + db.width = self:GetWidth() + end + if not self.minimized then - db.height = self:GetHeight() - db.minimized = nil - else - db.minimized = true + if self.height then + db.height = self.height + else + db.height = self:GetHeight() + end + self:SetHeight(db.height) end - if self:IsVisible() then - db.enabled = true - else - db.enabled = nil - end + + db.minimized = self.minimized and true or nil + db.enabled = self:IsVisible() and true or nil + db.active = self.active and true or nil + 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) self:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', db.x, db.y) + self:SetWidth(db.width) end - +-- Console frame toggler +-- @paramsig [...] +-- @param ... one or more space-seperated channel keys local function Console_Toggle(input) - local key = input:gmatch("[%a%d]") - local search - if key and D.sig[key] then - search = {D.sig[key]} - elseif D.console[key] then - search = {D.console[key]} + local search = {} + local key, n = D:GetArgs(input, 1) + if key then + repeat + if D.sig[key] then + table.insert(search, D.sig[key]) + elseif D.console[key] then + table.insert(search, D.console[key]) + end + key, n = D:GetArgs(input,1,n) + until n == 1e9 else search = D.console end + db.toggle = not db.toggle and true or nil for _, c in ipairs(search) do - if c:IsVisible() then + if db.toggle then + c:Show() + else + c.enabled = nil + c.minimized = nil + c:Maximize() c:Hide() - else - c:Show() - c:Maximize() end - c:Save() end + + if db.toggle then + D:Print('toggled on?') + else + D:Print('toggled off?') + end end --- --- --- Construct a console frame +-- Bring console to the front +local function Console_ToFront(c) + --print(D.raise_ct, 'Raising', c.signature) + --print(unpack(db.frontdrop)) + --print(unpack(db.frontgrad)) + --print(db.frontblend) + D.raise_ct = D.raise_ct + 1 + c:Raise() + c.out.backdrop:SetTexture(unpack(db.frontdrop)) + c.out.backdrop:SetGradientAlpha(unpack(db.frontgrad)) + c.out.backdrop:SetBlendMode(db.frontblend) + + for id, bc in pairs(D.console) do + if id ~= c.index then + --print(D.raise_ct, 'Lowering', bc.signature) + --print(unpack(db.backdrop)) + --print(unpack(db.backgrad)) + --print(db.backblend) + bc.out.backdrop:SetTexture(unpack(db.backdrop)) + bc.out.backdrop:SetGradientAlpha(unpack(db.backgrad)) + bc.out.backdrop:SetBlendMode(db.backblend) + end + end + +end + +-- Generate a console frame +-- @paramsig id, vars +-- @param id channel number +-- @param vars alternative config, else uses db.channels[id] 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', db.channels[i].x, db.channels[i].y) + 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) @@ -178,23 +278,34 @@ 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 db.channels[i].enabled then - f:Show() + if vars.enabled then + f.enabled = true + if db.toggle then + f:Show() + end end - if db.channels[i].minimized then + if vars.minimized then f:Minimize() end return f end --- --- --- Send a message somewhere +-- Print to Devian output +-- @paramsig tag, ... +-- @param tag channel signature or number used to select console +-- @param ... print arguments local function Message(prefix, ...) if prefix == nil then prefix = 1 @@ -210,9 +321,6 @@ else channel = D.console[1] end - - - -- color me timbers local pcolor if D.tags[prefix] then @@ -257,6 +365,89 @@ 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() + end + +end + +-- Place all frames stacked beneath the primary frame +-- @paramsig +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 + end + frame:Save() + last = frame + end +end + +-- Creates or updates a console frame +-- @paramsig cinfo [, i] +-- @param cinfo an array from db.channels[x] or the desired string signature +-- @param id when set, the console at that index will be assigned all parameters in cinfo +function D:SetChannel(cinfo, i) + print('join:', i , cinfo) + local t_info = {} + if type(cinfo) ~= 'table' then + t_info.signature = tostring(cinfo) + cinfo = {} + end + local srcdb = db.channels[self.primary_channel] + if i ~= nil then + i = tonumber(i) + if db.channels[i] then + print('pull vars from '..db.channels[i].signature) + cinfo = db.channels[i] + srcdb = cinfo + end + end + + for k,v in pairs(srcdb) do + if not t_info[k] then + if cinfo[k] then + print('- pulling', k..':',v) + t_info[k] = cinfo[k] + end + end + end + + if not db.channels[i] then + t_info.x = t_info.x + 20 + t_info.y = t_info.y - 20 + db.channels[i] = t_info + end + if not self.console[i] then + self.console[i] = CreateConsole(i, t_info) + end + + self.sig[cinfo.signature] = self.console[i] + self.sigID[cinfo.signature] = i + self.IDsig[i] = cinfo.signature +end + function D:OnEnable() -- commands local cmdlist = { @@ -276,7 +467,6 @@ end - function D:OnInitialize() -- emergency button self:RegisterChatCommand("cleandvn", function(args) @@ -312,11 +502,23 @@ _G.oldprint = D.oldprint end + self.raise_ct = 0 + self.last_channel = 0 + self.num_channels = 0 self.console = {} self.sig = {} - for i, cinfo in ipairs(db.channels) do - self.console[i] = CreateConsole(i, cinfo) - self.sig[cinfo.signature] = self.console[i] + self.sigID = {} + self.IDsig = {} + for i, cinfo in pairs(db.channels) do + i = tonumber(i) + if not self.primary_channel then + self.primary_channel = i + end + self:SetChannel(cinfo, i) + if i > self.last_channel then + self.last_channel = i + end + self.num_channels = self.num_channels + 1 end setprinthandler(Message) print(MAJOR, MINOR) diff -r 080dfa4990fb -r 5254d1ba6013 Devian.xml --- a/Devian.xml Sat Dec 19 07:59:12 2015 -0500 +++ b/Devian.xml Sun Dec 20 00:46:42 2015 -0500 @@ -1,4 +1,10 @@ + + + + + + - - - - - + + self:ToFront() if button == 'LeftButton' then - if self.grip:IsMouseOver() then + if self.out.grip:IsMouseOver() then return self:StartSizing() end return self:StartMoving() @@ -33,6 +36,10 @@ return self:MinMax() end self:StopMovingOrSizing() + self.x = nil -- free these up + self.y = nil + self.width = nil + self.height = nil self:Save() @@ -56,8 +63,9 @@ else self.throttle = GetTime() end - - self.header:SetText(string.format(self.format, GetTime())) + local text = string.gsub(self.format, '%%t', GetTime(), 1) + text = string.gsub(text, '%%n', self.signature, 1) + self.header:SetText(text) @@ -92,6 +100,19 @@ + + + + + + + + + + + + + @@ -122,17 +143,50 @@ - - + + - + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 080dfa4990fb -r 5254d1ba6013 corner.blp Binary file corner.blp has changed