Mercurial > wow > devian
view Devian.lua @ 61:6ca4d0cae907
Added tag v2.1.60 for changeset 59e047d6c5de
author | Nenue |
---|---|
date | Tue, 26 Jan 2016 16:44:31 -0500 |
parents | 59e047d6c5de |
children | 516ceb31703d |
line wrap: on
line source
--- Devian - Devian.lua -- @file-author@ -- @project-revision@ @project-hash@ -- @file-revision@ @file-hash@ if not LibStub then print('Something has happened...') end local MAJOR, MINOR = 'Devian-2.0', 'r@project-revision@' Devian = LibStub("AceAddon-3.0"):NewAddon("Devian", "AceConsole-3.0", "AceEvent-3.0") local D = _G.Devian D:SetDefaultModuleState(false) D.L = {} setmetatable(D.L, {__index= function(t,k) return k end, __call = function(t,k,...) return string.format((t[k] or k) , ...) end}) local L = D.L local pairs, tostring, tonumber, ipairs, type = pairs, tostring, tonumber, ipairs, type local max, rand, format = math.max, math.random, string.format local insert, wipe, concat = table.insert, table.wipe, table.concat local select, unpack = select, unpack local GetNumAddOns, GetAddOnInfo, GetAddOnEnableState, EnableAddOn = GetNumAddOns, GetAddOnInfo, GetAddOnEnableState, EnableAddOn local UnitName, DisableAddOn = UnitName, DisableAddOn local WORKSPACE_ON, WORKSPACE_OFF = 1, 2 local PLAYER_REALM = UnitName("player") .. '-' .. GetRealmName() local print = _G.print local db local defaults = { ['global'] = {{}, {}}, ['tags'] = {}, ['channels'] = {[1] = { signature = 'Main', index = 1, x = 100, y = 800, height = 500, width = 600, enabled = true}}, ['profiles'] = { {'Main', false}, {'Devian', true}, {'Turok', true}, {'Bam', true} }, primary_channel = 1, -- the channel to which default output is sent current_channel = 1, -- the front channel max_channel = 1, -- the highest created channel id enabled = true, -- allow enabled consoles to appear load_message = "Defaults loaded.", -- messages to be displayed after reload font = [[Interface\Addons\Devian\font\SourceCodePro-Regular.ttf]], -- font info fontsize = 13, fontoutline = 'NONE', headergrad = {'VERTICAL', 0, 0, 0, 1, 1, 0.1, 0.1, 1}, -- header info headerdrop = {1,1,1,1}, headerblend = 'BLEND', headeralpha = 1, headerfontcolor = {1,1,1,1}, backdrop = {1,1,1,1}, -- background frame info backgrad = {'VERTICAL', 0, 0, 0, .75, 0,0,0, .65}, backblend = 'BLEND', backalpha = 1, backborder = {.5,.5,.5,1}, backheader = {.25,.25,.25,1}, frontdrop = {1,1,1,1}, -- foreground frame info frontgrad = {'VERTICAL', 0, 0, 0, 1, 0,0,0, 0.95}, frontblend = 'BLEND', frontalpha = 1, frontborder = {.07,.47,1,1}, frontheader = {1,1,1,1}, tagcolor = {}, -- tag color repository workspace = 2, -- current profile last_workspace = 2, -- default workspace to alternate with when just "/dvn" is issued dock_onshow_fade_time = 2.5, dock_onshow_fade_from = 1, dock_onshow_fade_to = 0.2, dock_alpha_on = 1, dock_alpha_off = 0.2, dock_fade_in = 0.15, dock_fade_out = 0.45, dock_button_alpha_on = 1, dock_button_alpha_off = 0.2, dock_button_fade_in = 0.075, dock_button_fade_out = 0.075, movement_fade = true, movement_fade_time = 0.15, movement_fade_from = 1, movement_fade_to = 0, movement_translation_x = 25, movement_translation_y = 25, } local function ScanAddOnList(cmd, ...) local list_state local args = {} local arg, n = D:GetArgs(cmd, 1) while arg do insert(args, arg) arg, n = D:GetArgs(cmd,1,n) end local mode, tag, dest = unpack(args) -- no args, toggle ui if mode == 'stack' then if db.workspace == 1 then return D:Print(L['Need devmode']) end return D:StackFrames() elseif mode == 'grid' then if db.workspace == 1 then return D:Print(L['Need devmode']) end return D:DistributeFrames() elseif mode == 'tag' then -- tagging if db.workspace == 1 then return D:Print(L['Need devmode']) end local sig if tag ~= nil and dest ~= nil then --@debug@ --print(tag, dest) --@end-debug@ -- convert to ID if tonumber(dest) == nil then if D.sigID[dest] then dest = db.channels[D.sigID[dest]].index else sig = dest end else dest = tonumber(dest) end --@debug@ --print('2 tag,dest,sig', tag, dest, sig)--@end-debug@ -- make a new channel? local channel if not D.db.channels[dest] then dest = D.max_channel + 1 D:Print(L('New channel created', sig and (dest..':'..sig) or dest )) channel = D:SetChannel(sig or tag,dest) else channel = D.db.channels[dest] end --@debug@ --print('3 tag,dest,channel.sig=',tag, dest, channel.signature)--@end-debug@ if not db.tags[tag] then -- no tag table? db.tags[tag] = {} end if db.tags[tag][dest] then -- is tag set? db.tags[tag][dest] = nil D:Print(L('Tag removed from channel', tag, db.channels[dest].index, db.channels[dest].signature)) else db.tags[tag][dest] = dest D:Print(L('Tag added to channel', tag, db.channels[dest].index, db.channels[dest].signature)) end D:UpdateDock() else D:Print(L['Command tag help']) end return elseif tonumber(mode) ~= nil or mode == 'save' then -- iterating for something if mode == 'save' then if tonumber(tag) == nil then T:Print(L('Invalid ID from arg', tag)) end list_state = tonumber(tag) else list_state = tonumber(mode) db.workspace = list_state if list_state ~= 1 then db.last_workspace = list_state end end elseif mode == nil then list_state = (db.workspace == 1) and db.last_workspace or 1 db.workspace = list_state else return D:PrintHelp() end -- start the iterating if not db[PLAYER_REALM][list_state] then db[PLAYER_REALM][list_state] = {} end if not db.global[list_state] then db.global[list_state] = {} 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 == '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 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 elseif mode ~= 'save' then if type(db.unlisted) ~= 'table' then db.unlisted = {} end insert(db.unlisted, name) end end end if mode ~= 'save' then db.load_message = (mode == nil) and L("Toggled to profile", list_state) or L('Switched to profile number', list_state) ReloadUI() else if list_state == 1 then D:Print(L['Profile main saved']) else db.last_workspace = list_state D:Print(L('Profile number saved', list_state, list_state)) end end end --- Creates a Devian-style output. -- The first argument describes the channel to output on, and the remaining arguments are concatenated in a manner similar to default print() -- This becomes the print handler when development mode is active. The original print() function is assigned to oldprint(). -- @param Tag, signature, or numeric index of the channel to output on. Defaults to primary channel. -- @param ... Output contents. local function Message(prefix, ...) if db.workspace == 1 then return D.oldprint(prefix, ...) end prefix = tostring(prefix) if prefix == nil then prefix = 'nil*' end local sendq = {} local tag, id, tagged local byName = true if D.tags[prefix] then for _, id in pairs(D.tags[prefix]) do if D.console[id] then sendq[id] = D.console[id] tagged = true end end end if D.sig[prefix] then sendq[D.sig[prefix].index] = D.sig[prefix] elseif D.console[prefix] then sendq[D.console[prefix]] = D.console[prefix] elseif not tagged then sendq[D.primary_channel] = D.console[D.primary_channel] end -- color me timbers local pcolor if (not db.tagcolor[prefix]) and byName then local c = { rand(64,255), rand(64,255), rand(64,255) } if c[1] > 223 and c[2] > 223 and c[3] > 223 then c[rand(1,3)] = rand(64,223) end db.tagcolor[prefix] = format('%02X%02X%02X', unpack(c)) end pcolor = db.tagcolor[prefix] local buffer = {} for i = 1, select('#',...) do local var = select(i, ...) if type(var) == 'table' then if type(var.GetName) == 'function' then var = '<table:'..tostring(var:GetName())..'>' else var = '<'..tostring(var)..'>' end 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' else var = tostring(var) end insert(buffer, var) end local message = concat(buffer, ' ') for id, channel in pairs(sendq) do if channel.width < 250 then prefix = string.sub(prefix, 0,2) end channel.out:AddMessage('|cFF'.. pcolor..prefix ..'|r ' .. message, 0.8, 0.8, 0.8, nil, nil, prefix, GetTime()) if not D.dock.buttons[id].newMessage then D.dock.buttons[id].newMessage = true D.UpdateBeacon(D.dock.buttons[id]) end end wipe(buffer) end function D:PrintHelp() D:Print("|cFFFFFF00/dvn|r", "\n |cFFFFFF00<number>|r - Loads a saved addon list. List 1 is treated as a gameplay profile and consoles will be disabled by default.") D:Print("|cFFFFFF00/dvc|r [<key>, ...]", "- Hides and show consoles. A list of channel keys can be passed to specify which ones get toggled.") D:Print("|cFFFFFF00/resetdvn|r", "- Resets all but profile data SavedVariables.") D:Print("|cFFFFFF00/cleandvn|r", "- Fully resets SavedVariables, profiles and all.") end local dot1, dot2 = CreateFrame('Frame', nil, UIParent), CreateFrame('Frame', nil, UIParent) dot1:SetSize(5,5) dot1:SetFrameStrata('TOOLTIP') local a = dot1:CreateTexture('fill', nil) a:SetAllPoints(dot1) a:SetTexture(1,0,0,1) dot2:SetSize(5,5) dot2:SetFrameStrata('TOOLTIP') a = dot2:CreateTexture('fill', nil) a:SetAllPoints(dot2) a:SetTexture(0,1,0,1) local OnStartedMoving = function() for k, v in pairs(D.console) do if v.enabled then v.moveFade:Stop() local F1 = v.moveFade.alphaOut F1:SetFromAlpha(db.movement_fade_from) F1:SetToAlpha(db.movement_fade_to) F1:SetDuration(db.movement_fade_time) v.moveFade:Play() v:EnableMouse(false) end end end local OnStoppedMoving = function() for k, v in pairs(D.console) do if v.enabled then v.moveFade:Stop() local F1 = v.moveFade.alphaOut F1:SetToAlpha(db.movement_fade_from) F1:SetFromAlpha(db.movement_fade_to) F1:SetDuration(db.movement_fade_time) v.moveFade:Play() v:EnableMouse(true) end end end function D:OnEnable() if db.unlisted and #db.unlisted > 0 then D:Print('New AddOns have been found since the last profile update: '.. concat(db.unlisted, ', ')) wipe(db.unlisted) end if db.workspace == 1 then D:Print(L('Devian loaded on standby',MAJOR, MINOR)) else D:Print(L('Devian loaded in workspace', MAJOR, MINOR, db.workspace)) -- movement fading if db.movement_fade then self:RegisterEvent('PLAYER_STARTED_MOVING', OnStartedMoving) self:RegisterEvent('PLAYER_STOPPED_MOVING', OnStoppedMoving) end end --@debug@ self:RegisterChatCommand("dvg", function(input) if not self.config then self.config = DevCon self:EnableModule("Config") end self.modules.Config:ChatCommand(input) end) --@end-debug@ end function D:OnInitialize() -- commands self:RegisterChatCommand("cleandvn", function(args) DevianDB = nil DevianDB = { load_message = "All SavedVars wiped." } ReloadUI() end) local blocked = {global = true, channels = true, tags = true, [PLAYER_REALM] = true} self:RegisterChatCommand("resetdvn", function(args) for k,v in pairs(DevianDB) do if not blocked[k] then DevianDB[k] = nil end end for k,v in pairs(defaults) do if not blocked[k] then DevianDB[k] = v end end DevianDB.load_message = "Non-user SavedVars have been reset." ReloadUI() end) local cmdlist = { ['dvn'] = ScanAddOnList, ['devian'] = ScanAddOnList, ['dvc'] = "Console_Toggle", } for cmd, func in pairs(cmdlist) do self:RegisterChatCommand(cmd, func, true) end -- pull defaults if not _G.DevianDB then _G.DevianDB = defaults end db = _G.DevianDB self.db = db self.tags = db.tags self.channelinfo = db.channels if not db[PLAYER_REALM] then db[PLAYER_REALM] = {[WORKSPACE_ON] = {}, [WORKSPACE_OFF] = {}} end if db.load_message then D:Print(db.load_message) db.load_message = nil end D.oldprint = getprinthandler() if not _G.oldprint then _G.oldprint = D.oldprint end -- Stop here in game mode if db.workspace == 1 then return end ----------------------------------------------------------------------- self.db = db self.channels = db.channels self.max_channel = 0 self.num_channels = 0 self.console = {} self.sig = {} self.sigID = {} self.IDsig = {} self.dock = DevianDock self.dock.buttons = {} 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) self.max_channel = max(i, self.max_channel) self.num_channels = self.num_channels + 1 end if self.console[db.current_channel] then print('bringing', self.console[db.current_channel].signature, 'to the front') self.console[db.current_channel]:ToFront() -- bring the current channel to the front end DevianDock:Show() self:UpdateDock() setprinthandler(Message) print = function(...) _G.print('Dvn', ...) end end --- Console frame toggler -- @paramsig [...] -- @param ... one or more space-seperated channel keys function D:Console_Toggle(input, force) --oldprint(input) local setAll if db.workspace == 1 then return self:Print(MSG_NEED_DEV_MODE) end local search = {} local key local n = 0 while self:GetArgs(input,1,n) and n < 255 do --should end itself when it gets nil, but key, n = self:GetArgs(input,1,n) if self.sig[key] then --print(key, self.sigID[key]) insert(search, self.sigID[key]) elseif self.console[tonumber(key)] then --print(key, tonumber(key)) insert(search, tonumber(key)) end --oldprint(#search, key, n) end if #search < 1 then search = self.sigID setAll = true end if setAll then --oldprint('setall', setAll) db.enabled = (not db.enabled) and true or nil if force == 0 then db.enabled = nil end end for i, id in pairs(search) do --oldprint(i, id) local c = self.console[id] if setAll then c.enabled = db.enabled and db.enabled or nil else db.enabled = true c.enabled = (not c.enabled) and true or nil if force == 0 then c.enabled = nil end --oldprint(id, ' ', force, c.enabled, db.enabled) end if c.enabled or (setAll and db.enabled) then c:Show() elseif not (c.enabled and db.enabled) then c:Hide() end c:Save() end if setAll then if db.enabled then self:Print('toggled all consoles ON') if D.console[db.current_channel] then oldprint('push', D.console[db.current_channel].signature, 'to the front') D.console[db.current_channel]:ToFront() end else self:Print('toggled all consoles OFF') end else local result = {} for i, id in pairs(search) do result[i] = tostring(id) .. ' = ' .. (self.console[id].enabled and 'ON' or 'OFF') end self:Print('toggled: '..concat(result, ', ')) end end