Mercurial > wow > devian
view Devian.lua @ 16:dee6cef56415
Added tag v1.3 for changeset ee5dd70e792f
author | Nenue |
---|---|
date | Sun, 20 Dec 2015 01:15:50 -0500 |
parents | 5254d1ba6013 |
children | 48a1d9c14af5 |
line wrap: on
line source
-- User: Krakyn -- Created: 11/30/2015 7:46 AM 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 PLAYER_REALM = UnitName("player") .. '-' .. GetRealmName() local DEVIAN_FRAME = 'DevianConsole' local print = function(...) _G.print('Dvn', ...) end local db local defaults = { ['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, 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 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) -- 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 list_state == STATE_LOW then end 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 <prefix> <console name or number>') 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] 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 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 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 end end end if mode == nil then ReloadUI() end if mode == STATE_LOW then D:Print('Developement AddOn list saved.') else D:Print('Standard AddOn list saved.') end end local function Console_MinMax(self) if self.minimized then self:Maximize() else self:Minimize() end end local function Console_Minimize(self) self:SetHeight(20) self:SetMaxResize(GetScreenWidth(),20) self.minimized = true self.out:Hide() self:Save() end local function Console_Maximize(self) local db = db.channels[self.index] self:SetHeight(db.height) self:SetMaxResize(GetScreenWidth(),GetScreenHeight()) self.minimized = nil self.out:Show() self:Save() end local function Console_Save(self) local db = db.channels[self.index] 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 if self.height then db.height = self.height else db.height = self:GetHeight() end self:SetHeight(db.height) 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 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 db.toggle then c:Show() else c.enabled = nil c.minimized = nil c:Maximize() c:Hide() end end if db.toggle then D:Print('toggled on?') else D:Print('toggled off?') end end -- 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', vars.x, vars.y) f:SetSize(vars.width, vars.height) f:Lower() f.out:SetFont(db.font, db.fontsize, db.fontoutline) 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() end end if vars.minimized then f:Minimize() end return f end -- 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 end local channel local byName = true if D.sig[prefix] then channel = D.sig[prefix] elseif D.console[prefix] then channel = D.console[prefix] byName = nil else channel = D.console[1] end -- color me timbers local pcolor if D.tags[prefix] then pcolor = db.tags[prefix] elseif byName then local c = {0, 0, 0 } local max = string.len(prefix) for i = 1, max, 3 do for k, v in ipairs(c) do local j = i + (k - 1) c[k] = c[k] + (j <= max and string.byte(prefix,j) or 0) end end for k,v in ipairs(c) do c[k] = c[k] % 255 if c[k] < 64 then c[k] = 0 elseif c[k] > 127 then c[k] = 255 end end D.tags[prefix] = string.format('%02X%02X%02X', unpack(c)) end local buffer = {'|cFF'.. D.tags[prefix]..prefix ..'|r'} for i = 1, select('#',...) do local var = select(i, ...) if type(var) == 'table' then var = '<table>' elseif type(var) == 'boolean' then var = var and 'true' or 'false' elseif type(var) == 'function' then var = '<funcref>' elseif type(var) == 'nil' then var = 'nil' end table.insert(buffer, var) end channel.out:AddMessage(table.concat(buffer, ' ')) 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 = { ['dvn'] = ScanAddOnList, ['devian'] = ScanAddOnList, ['dvc'] = Console_Toggle, } for cmd, func in pairs(cmdlist) do self:RegisterChatCommand(cmd, func, true) end if db.enabled == true then D:Print('Standard AddOn list active. Type /dvn to switch to development mode.') else D:Print('Development AddOn list active. Type /dvn to revert to regular operation.') end end function D:OnInitialize() -- emergency button self:RegisterChatCommand("cleandvn", function(args) DevianDB = nil 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 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 end -- copy tags self.tags = {} for n, c in pairs(db.tags) do self.tags[n] = c end if cherry then D:Print(cherry) end D.oldprint = getprinthandler() if not _G.oldprint then _G.oldprint = D.oldprint end self.raise_ct = 0 self.last_channel = 0 self.num_channels = 0 self.console = {} self.sig = {} 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) end