Nenue@35: --- ${PACKAGE_NAME} Nenue@35: -- @file-author@ Nenue@35: -- @project-revision@ @project-hash@ Nenue@35: -- @file-revision@ @file-hash@ Nenue@35: -- Created: 12/27/2015 3:01 AM Nenue@35: Nenue@35: Nenue@35: if not LibStub then Nenue@35: print('Something has happened...') Nenue@35: end Nenue@35: local D = LibStub("AceAddon-3.0"):GetAddon("Devian") Nenue@35: Nenue@35: Nenue@35: Nenue@35: local DEVIAN_FRAME = 'DevianConsole' Nenue@47: local DEVIAN_DOCK_FRAME = 'DevianDock' Nenue@35: Nenue@35: Nenue@35: local function Console_MinMax(self) Nenue@35: if self.minimized then Nenue@35: self:Maximize() Nenue@35: else Nenue@35: self:Minimize() Nenue@35: end Nenue@35: end Nenue@35: Nenue@35: local function Console_Minimize(self) Nenue@35: self:SetHeight(20) Nenue@35: self:SetMaxResize(GetScreenWidth(),20) Nenue@35: self.minimized = true Nenue@35: self.out:Hide() Nenue@35: self:Save() Nenue@35: end Nenue@35: Nenue@35: local function Console_Maximize(self) Nenue@35: local db = D.channels[self.index] Nenue@35: self:SetHeight(db.height) Nenue@35: self:SetMaxResize(GetScreenWidth(),GetScreenHeight()) Nenue@35: self.minimized = nil Nenue@35: self.out:Show() Nenue@35: self:Save() Nenue@35: end Nenue@35: Nenue@35: Nenue@35: local function Console_Save(self) Nenue@35: local db = D.channels[self.index] Nenue@35: if self.x then Nenue@35: db.x = self.x Nenue@35: else Nenue@35: db.x = self:GetLeft() Nenue@35: end Nenue@35: Nenue@35: if self.y then Nenue@35: db.y = self.y Nenue@35: else Nenue@35: db.y = (self:GetTop() - GetScreenHeight()) Nenue@35: end Nenue@35: Nenue@35: if self.width then Nenue@35: db.width = self.width Nenue@35: else Nenue@35: db.width = self:GetWidth() Nenue@35: end Nenue@35: Nenue@35: if not self.minimized then Nenue@35: if self.height then Nenue@35: db.height = self.height Nenue@35: else Nenue@35: db.height = self:GetHeight() Nenue@35: end Nenue@35: self:SetHeight(db.height) Nenue@35: end Nenue@35: Nenue@35: db.dockedTo = self.dockedTo Nenue@35: db.docked = self.docked Nenue@35: Nenue@35: db.minimized = self.minimized and true or nil Nenue@35: db.enabled = self:IsVisible() and true or nil Nenue@35: db.active = self.active and true or nil Nenue@35: --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@35: self:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', db.x, db.y) Nenue@35: self:SetWidth(db.width) Nenue@35: end Nenue@35: Nenue@35: --- Brings the console to the front. Nenue@35: -- Frame method used to bring a console frame to the front of the display stack. Nenue@35: local function Console_ToFront(c) Nenue@35: local db = D.db Nenue@35: --print(D.raise_ct, 'Raising', c.signature) Nenue@35: --print(unpack(db.frontdrop)) Nenue@35: --print(unpack(db.frontgrad)) Nenue@35: --print(db.frontblend) Nenue@35: -- D.raise_ct = D.raise_ct + 1 Nenue@35: c:Raise() Nenue@35: c:SetAlpha(db.frontalpha) Nenue@35: c.out.backdrop:SetTexture(unpack(db.frontdrop)) Nenue@35: c.out.backdrop:SetGradientAlpha(unpack(db.frontgrad)) Nenue@35: c.out.backdrop:SetBlendMode(db.frontblend) Nenue@45: c.dropmenu.icon:SetVertexColor(unpack(db.frontheader)) Nenue@45: c.title:SetTextColor(unpack(db.frontborder)) Nenue@35: db.current_channel = c.index Nenue@35: Nenue@35: for _, part in pairs(c.border) do Nenue@35: part:SetTexture(unpack(db.frontborder)) Nenue@35: end Nenue@35: Nenue@35: for id, bc in pairs(D.console) do Nenue@35: if id ~= c.index then Nenue@35: --print(D.raise_ct, 'Lowering', bc.signature) Nenue@35: --print(unpack(db.backdrop)) Nenue@35: --print(unpack(db.backgrad)) Nenue@35: --print(db.backblend) Nenue@35: bc:SetAlpha(db.backalpha) Nenue@35: bc.out.backdrop:SetTexture(unpack(db.backdrop)) Nenue@35: bc.out.backdrop:SetGradientAlpha(unpack(db.backgrad)) Nenue@35: bc.out.backdrop:SetBlendMode(db.backblend) Nenue@45: bc.dropmenu.icon:SetVertexColor(unpack(db.backheader)) Nenue@36: bc.title:SetTextColor(unpack(db.backborder)) Nenue@35: Nenue@35: for _, part in pairs(bc.border) do Nenue@35: part:SetTexture(unpack(db.backborder)) Nenue@35: end Nenue@35: end Nenue@35: end Nenue@35: end Nenue@35: Nenue@35: local function Console_MouseDown(self, button, up) Nenue@35: if button == 'LeftButton' then Nenue@35: if up then Nenue@35: self:StopMovingOrSizing() Nenue@35: self:ToFront() Nenue@35: self.x = nil Nenue@35: self.y = nil Nenue@35: self.width = nil Nenue@35: self.height = nil Nenue@35: self:Save() Nenue@35: elseif self.out.grip:IsMouseOver() then Nenue@35: self:StartSizing() Nenue@35: else Nenue@35: self:StartMoving() Nenue@35: end Nenue@35: else Nenue@35: if up then Nenue@35: self:MinMax() Nenue@35: end Nenue@35: end Nenue@35: end Nenue@35: local function Console_MouseUp(self, button) Nenue@35: return Console_MouseDown(self, button, true) Nenue@35: end Nenue@35: Nenue@35: Nenue@35: --- Constructs the frame object for a console channel Nenue@35: -- Initializes the console channel at a specified index. Nenue@35: -- Configuration data can be overridden by passing a desired settings table. Nenue@35: -- @param i Numeric index of the channel as it manifests in db.channels Nenue@35: -- @param vars Optional settings table to be used. Nenue@35: local function CreateConsole(i, vars) Nenue@35: local db = D.db Nenue@35: if tonumber(i) == nil or math.floor(i) ~= i then Nenue@35: error('Non-integer index value.') Nenue@35: end Nenue@35: if not vars then Nenue@35: vars = D.channels[i] and D.channels[i] or D.channels[db.primary_channel] Nenue@35: end Nenue@35: local f Nenue@47: f= CreateFrame('Frame', 'DevianChannelFrame' .. i, UIParent, DEVIAN_FRAME) Nenue@47: Nenue@35: --@debug@ Nenue@35: --print(f:GetName()) Nenue@35: Nenue@35: --print('create(2)') Nenue@35: for k,v in pairs(vars) do Nenue@35: f[k] = v Nenue@35: --@debug@ Nenue@36: --print(' f['..type(k)..' '..tostring(k)..'] = '..type(v)..' '..tostring(v)) Nenue@35: end Nenue@35: Nenue@35: f:SetPoint('TOPLEFT', UIParent, 'TOPLEFT', vars.x, vars.y) Nenue@35: f:SetSize(vars.width, vars.height) Nenue@35: f:Lower() Nenue@35: f.out:SetFont(db.font, db.fontsize, db.fontoutline) Nenue@35: if (db.current_channel == i) then Nenue@35: f.out.backdrop:SetTexture(unpack(db.frontdrop)) Nenue@36: f.dropmenu.icon:SetVertexColor(unpack(db.headerfontcolor)) Nenue@36: f.title:SetTextColor(unpack(db.headerfontcolor)) Nenue@45: f.header:SetAlpha(db.headeralpha) Nenue@35: else Nenue@35: f.out.backdrop:SetTexture(unpack(db.backdrop)) Nenue@35: end Nenue@35: Nenue@35: f.Save = Console_Save Nenue@35: f.Minimize = Console_Minimize Nenue@35: f.Maximize = Console_Maximize Nenue@35: f.MinMax = Console_MinMax Nenue@35: f.ToFront = Console_ToFront Nenue@35: f.Toggle = D.Console_Toggle Nenue@35: f:SetScript('OnMouseDown', Console_MouseDown) Nenue@35: f:SetScript('OnMouseUp', Console_MouseUp) Nenue@35: Nenue@36: Nenue@36: UIDropDownMenu_Initialize(f.menuFrame, function() Nenue@36: local info = { { Nenue@36: text= "Close", Nenue@36: value = "OptClose", Nenue@36: func = function () Nenue@36: f.enabled = nil Nenue@36: f:Hide() Nenue@36: f:Save() Nenue@38: end },--[[ Nenue@36: { Nenue@36: text = "Dock", Nenue@36: value = "OptDock", Nenue@38: func = function() print('Dvn', 'docking shenanary') end }]] Nenue@36: } Nenue@36: for _, v in ipairs(info) do Nenue@36: UIDropDownMenu_AddButton(v) Nenue@36: end Nenue@36: end, 'MENU') Nenue@36: Nenue@47: D.dock.buttons[i] = CreateFrame('Button', 'Channel'..i..'Beacon', UIParent, 'DevianBeacon') Nenue@47: D.dock.buttons[i].icon:SetVertexColor(math.random(),math.random(),math.random()) Nenue@47: D.dock.buttons[i].console = f Nenue@47: D.dock.buttons[i].index = i Nenue@47: D.dock.buttons[i].caption.name:SetText(vars.signature) Nenue@47: D.dock.buttons[i]:Show() Nenue@47: Nenue@35: if vars.minimized then Nenue@35: f:Minimize() Nenue@35: else Nenue@35: f:Maximize() Nenue@35: end Nenue@35: if db.enabled and f.enabled then Nenue@35: f:Show() Nenue@35: end Nenue@35: Nenue@35: return f Nenue@35: end Nenue@35: Nenue@35: Nenue@35: --- Updates console information and returns the handle of the channel object that was worked on. Nenue@35: -- When key is nil or not a valid handle, a new channel is created using whatever signature can be found in cinfo. Nenue@35: -- The signature can be passed as a string, or as a table entry under the key 'signature' Nenue@35: -- If the signature of a new channel is also a tag, the channel will be added to that tag Nenue@35: -- @param cinfo string signature of a new channel, or a table of config variables to be imposed on the channel Nenue@35: -- @param key string signature or index number of channel to operate on Nenue@35: -- @usage channel = D:SetChannel('new', nil) -- creates a new channel Nenue@35: -- @usage channel = D:SetChannel({x = 200, y = 100}, 4) -- updates channel #4 Nenue@35: function D:SetChannel(cinfo, key) Nenue@35: local db = self.db Nenue@35: local t_info = {} Nenue@35: local channel, isNew, id, sig, t_id Nenue@36: --@debug@ Nenue@38: --print('setchan(0) cinfo, key', cinfo, key)--@end-debug@ Nenue@35: -- obtain source data Nenue@35: if tonumber(key) ~= nil and db.channels[key] then Nenue@35: id = tonumber(key) Nenue@35: elseif D.sigID[tostring(key)] then Nenue@35: id = D.sigID[tostring(key)] Nenue@35: else Nenue@35: id = db.primary_channel Nenue@35: isNew = true Nenue@35: end Nenue@35: local dbvars = db.channels[id] Nenue@35: t_id = id -- overridden later if new Nenue@35: t_info.index = t_id -- Nenue@35: --@debug@ Nenue@38: --print('setchan(1) cinfo, key, id=', cinfo, key, id)--@end-debug@ Nenue@35: Nenue@35: Nenue@35: -- obtain config info Nenue@35: if type(cinfo) == 'string' then Nenue@35: sig = cinfo Nenue@35: cinfo = {signature = sig} Nenue@35: elseif type(cinfo) ~= 'table' then -- stop here if a table wans't passed Nenue@35: error('Expecting table of string as arg1') Nenue@35: elseif cinfo.signature then -- new sig Nenue@35: sig = cinfo.signature Nenue@35: elseif isNew then -- new channel sig Nenue@35: sig = 'Ch' Nenue@35: else -- old sig Nenue@35: sig = db.channels[id].signature Nenue@35: end Nenue@35: t_info.signature = sig Nenue@35: --@debug@ Nenue@38: --print('setchan(2) sig,id,isNew=', sig, id, isNew)--@end-debug@ Nenue@35: Nenue@35: for k,v in pairs(cinfo) do -- allow all cinfo to pass Nenue@35: t_info[k] = v Nenue@35: end Nenue@35: Nenue@35: local blocked = { -- ignore these vars: Nenue@35: ['docked'] = true, -- table Nenue@35: ['dockedTo'] = true, -- table-related Nenue@35: ['signature'] = true} -- already determined Nenue@35: for k,v in pairs(dbvars) do Nenue@35: if not t_info[k] and not blocked[k] then -- already set or blocked? Nenue@35: t_info[k] = v Nenue@35: end Nenue@35: end Nenue@35: -- new channel overrides Nenue@35: if isNew then Nenue@35: if D.sigID[sig]then -- find a non-clashing signature Nenue@35: local result, i = sig, 1 Nenue@35: while D.sigID[result] do Nenue@35: result = sig .. i Nenue@35: i = i + 1 Nenue@35: end Nenue@35: t_info.signature = result Nenue@35: end Nenue@36: t_id = self.max_channel + 1 Nenue@35: t_info.index = t_id Nenue@35: --@debug@ Nenue@38: --print('setchan(3a) t_id, isNew, sig, t_info.signature=', t_id, isNew, sig, t_info.signature)--@end-debug@ Nenue@35: else Nenue@35: --@debug@ Nenue@38: --print('setchan(3b) t_id, isNew, sig, t_info.signature=', t_id, isNew, sig, t_info.signature)--@end-debug@ Nenue@35: end Nenue@35: Nenue@35: local channel Nenue@35: if not self.console[t_id] then -- create a frame Nenue@35: if isNew then -- position the channel frame Nenue@36: self.max_channel = t_id Nenue@36: db.max_channel = t_id Nenue@36: t_info.x = t_info.x + 20 Nenue@36: t_info.y = t_info.y - 20 Nenue@36: db.channels[t_id] = t_info Nenue@36: --@debug@ Nenue@38: --print('setchan(4a)', 't_id, x, y=', t_id, t_info.x, t_info.y)--@end-debug@ Nenue@35: end Nenue@35: channel = CreateConsole(t_id, t_info) Nenue@35: self.console[t_id] = channel Nenue@35: self.sig[t_info.signature] = channel Nenue@35: self.sigID[t_info.signature] = t_id Nenue@35: self.IDsig[t_id] = t_info.signature Nenue@35: Nenue@35: end Nenue@35: channel = self.console[t_id] Nenue@35: if channel.minimized then Nenue@35: channel:Minimize() Nenue@35: else Nenue@35: channel:Maximize() Nenue@35: end Nenue@35: Nenue@35: if channel.enabled and db.enabled then -- hide or show last since Min/Max mess with visibility Nenue@38: --print('setchan(5a) enable') Nenue@35: channel:Show() Nenue@45: channel:ToFront() Nenue@35: else Nenue@38: --print('setchan(5a) disable') Nenue@35: channel:Hide() Nenue@35: end Nenue@35: --@debug@ Nenue@35: --print('setchan(end); c:IsVisible(), c.enabled, db.enabled=', channel:IsVisible(), channel.enabled, db.enabled)--@end-debug@ Nenue@35: return channel Nenue@35: end