--[[ ############################################################################## _____/\\\\\\\\\\\____/\\\________/\\\__/\\\________/\\\__/\\\\\\\\\\\_ # ___/\\\/////////\\\_\/\\\_______\/\\\_\/\\\_______\/\\\_\/////\\\///__ # __\//\\\______\///__\//\\\______/\\\__\/\\\_______\/\\\_____\/\\\_____ # ___\////\\\__________\//\\\____/\\\___\/\\\_______\/\\\_____\/\\\_____ # ______\////\\\________\//\\\__/\\\____\/\\\_______\/\\\_____\/\\\_____ # _________\////\\\______\//\\\/\\\_____\/\\\_______\/\\\_____\/\\\_____ # __/\\\______\//\\\______\//\\\\\______\//\\\______/\\\______\/\\\_____ # _\///\\\\\\\\\\\/________\//\\\________\///\\\\\\\\\/____/\\\\\\\\\\\_# ___\///////////___________\///___________\/////////_____\///////////_# ############################################################################## S U P E R - V I L L A I N - U I By: Munglunch # ############################################################################## ########################################################## LOCALIZED LUA FUNCTIONS ########################################################## ]]-- --[[ GLOBALS ]]-- local _G = _G; local unpack = _G.unpack; local select = _G.select; local pairs = _G.pairs; local type = _G.type; local tinsert = _G.tinsert; local string = _G.string; local math = _G.math; local table = _G.table; --[[ STRING METHODS ]]-- local format,find = string.format, string.find; --[[ MATH METHODS ]]-- local floor = math.floor; --[[ TABLE METHODS ]]-- local twipe, tcopy = table.wipe, table.copy; --[[ ########################################################## GET ADDON DATA ########################################################## ]]-- local PLUGIN = select(2, ...) local Schema = PLUGIN.Schema; local VERSION = PLUGIN.Version; local SV = _G.SVUI local L = SV.L local NewHook = hooksecurefunc; --[[ ########################################################## CORE DATA ########################################################## ]]-- PLUGIN.DockedParent = {} PLUGIN.AddOnQueue = {}; PLUGIN.AddOnEvents = {}; PLUGIN.CustomQueue = {}; PLUGIN.EventListeners = {}; PLUGIN.OnLoadAddons = {}; PLUGIN.StyledAddons = {}; PLUGIN.OptionsCache = { order = 4, type = "group", name = "Addon Styling", get = function(a)return SV.db[Schema].addons[a[#a]] end, set = function(a,b) SV.db[Schema].addons[a[#a]] = b; SV:StaticPopup_Show("RL_CLIENT")end, disabled = function()return not SV.db[Schema].addons.enable end, guiInline = true, args = { ace3 = { type = "toggle", order = 1, name = "Ace3" }, } } PLUGIN.Debugging = false --[[ ########################################################## CORE FUNCTIONS ########################################################## ]]-- local charming = {"Spiffy", "Pimped Out", "Fancy", "Awesome", "Bad Ass", "Sparkly", "Gorgeous", "Handsome", "Shiny"} local errorMessage = '%s: |cffff0000There was an error in the|r |cff0affff%s|r |cffff0000skin|r. |cffFF0000[[|r%s|cffFF0000]]|r' local styleMessage = '|cff00FF77%s|r Is Now %s!' local function SendAddonMessage(msg, prefix) if(type(msg) == "table") then msg = tostring(msg) end if(not msg) then return end if(prefix) then local outbound = ("%s %s"):format(prefix, msg); print(outbound) else print(msg) end end function PLUGIN:AddonMessage(msg) local outbound = ("|cffFF2F00%s:|r"):format("Style-O-Matic") SendAddonMessage(msg, outbound) end function PLUGIN:LoadAlert(MainText, Function) self.Alert.Text:SetText(MainText) self.Alert.Accept:SetScript('OnClick', Function) self.Alert:Show() end function PLUGIN:Style(style, fn, ...) local pass, error = pcall(fn, ...) if(self.Debugging and error) then SV:Debugger(errorMessage:format(VERSION, style, error)) return end if(pass and (not style:find("Blizzard")) and not self.StyledAddons[style]) then self.StyledAddons[style] = true local verb = charming[math.random(1,#charming)] self:AddonMessage(styleMessage:format(style, verb)) end self.Debugging = false end function PLUGIN:IsAddonReady(addon, ...) if not SV.db[Schema].addons then return end for i = 1, select('#', ...) do local a = select(i, ...) if not a then break end if not IsAddOnLoaded(a) then return false end end return SV.db[Schema].addons[addon] end function PLUGIN:SaveAddonStyle(addon, fn, force, passive, ...) self:DefineEventFunction("PLAYER_ENTERING_WORLD", addon) if(passive) then self:DefineEventFunction("ADDON_LOADED", addon) end for i=1, select("#",...) do local event = select(i,...) if(event) then self:DefineEventFunction(event, addon) end end if(SV.db[Schema].addons and SV.db[Schema].addons[addon] == nil) then SV.db[Schema].addons[addon] = true end if force then fn() else self.AddOnQueue[addon] = fn end end function PLUGIN:SaveBlizzardStyle(addon, fn, force) if force then if(not IsAddOnLoaded(addon)) then LoadAddOn(addon) end fn() else self.OnLoadAddons[addon] = fn end end function PLUGIN:SaveCustomStyle(fn) tinsert(PLUGIN.CustomQueue, fn) end function PLUGIN:DefineEventFunction(addonEvent, addon) if(not addon) then return end if(not self.EventListeners[addonEvent]) then self.EventListeners[addonEvent] = {} end self.EventListeners[addonEvent][addon] = true if(not self[addonEvent]) then self[addonEvent] = function(self, event, ...) for name,fn in pairs(self.AddOnQueue) do if self:IsAddonReady(name) and self.EventListeners[event] and self.EventListeners[event][name] then self:Style(name, fn, event, ...) end end end self:RegisterEvent(addonEvent); end end function PLUGIN:SafeEventRemoval(addon, event) if not self.EventListeners[event] then return end if not self.EventListeners[event][addon] then return end self.EventListeners[event][addon] = nil; local defined = false; for name,_ in pairs(self.EventListeners[event]) do if name then defined = true; break end end if not defined then self:UnregisterEvent(event) end end function PLUGIN:RefreshAddonStyles() for addon,fn in pairs(self.AddOnQueue) do if(self:IsAddonReady(addon)) then self:Style(addon, fn) end end end function PLUGIN:AppendAddonOption(addon) if(not self.OptionsCache.args[addon]) then self.OptionsCache.args[addon] = { type = "toggle", name = addon, desc = L["Addon Styling"], get = function(key) return self:IsAddonReady(key[#key]) end, set = function(key,value) self:ChangeDBVar(value, key[#key], "addons"); SV:StaticPopup_Show("RL_CLIENT") end, disabled = function() if addon then return not IsAddOnLoaded(addon) else return false end end } end end function PLUGIN:PLAYER_ENTERING_WORLD(event, ...) for name,fn in pairs(self.OnLoadAddons) do if(SV.db[Schema].blizzard[name] == nil) then SV.db[Schema].blizzard[name] = true end if(IsAddOnLoaded(name) and (SV.db[Schema].blizzard[name] or SV.db[Schema].addons[name])) then self:Style(name, fn, event, ...) self.OnLoadAddons[name] = nil end end for _,fn in pairs(self.CustomQueue)do fn(event, ...) end twipe(self.CustomQueue) local listener = self.EventListeners[event] for name,fn in pairs(self.AddOnQueue)do self:AppendAddonOption(name) if(SV.db[Schema].addons[name] == nil) then SV.db[Schema].addons[name] = true end if(listener[name] and self:IsAddonReady(name)) then self:Style(name, fn, event, ...) end end end function PLUGIN:ADDON_LOADED(event, addon) -- print(addon) for name, fn in pairs(self.OnLoadAddons) do if(addon:find(name)) then self:Style(name, fn, event, addon) self.OnLoadAddons[name] = nil end end local listener = self.EventListeners[event] if(listener) then for name, fn in pairs(self.AddOnQueue) do if(listener[name] and self:IsAddonReady(name)) then self:Style(name, fn, event, addon) end end end end --[[ ########################################################## OPTIONS CREATION ########################################################## ]]-- local RegisterAddonDocklets = function() local MAIN = _G["SuperDockletMain"]; local EXTRA = _G["SuperDockletExtra"]; local main = SV.db.SVDock.docklets.DockletMain; local alternate = SV.db.SVDock.docklets.enableExtra and SV.db.SVDock.docklets.DockletExtra or ""; local tipLeft, tipRight = "", ""; if main == nil or main == "None" then return end if find(main, "Skada") or find(alternate, "Skada") then if SV:IsDockletReady("Skada") then PLUGIN:Docklet_Skada() if find(alternate, "Skada") and EXTRA.FrameName ~= "SkadaHolder2" then tipRight = "and Skada"; SV:RegisterExtraDocklet("SkadaHolder2") --PLUGIN.DockedParent["Skada"] = EXTRA end if find(main, "Skada") and MAIN.FrameName ~= "SkadaHolder" then tipLeft = "Skada"; SV:RegisterMainDocklet("SkadaHolder") --PLUGIN.DockedParent["Skada"] = MAIN end end end if main == "Omen" or alternate == "Omen" then if SV:IsDockletReady("Omen") then if alternate == "Omen" and EXTRA.FrameName ~= "OmenAnchor" then tipRight = "and Omen"; SV:RegisterExtraDocklet("OmenAnchor") PLUGIN:Docklet_Omen(EXTRA) PLUGIN.DockedParent["Omen"] = EXTRA elseif MAIN.FrameName ~= "OmenAnchor" then tipLeft = "Omen"; SV:RegisterMainDocklet("OmenAnchor") PLUGIN:Docklet_Omen(MAIN) PLUGIN.DockedParent["Omen"] = MAIN end end end if main == "Recount" or alternate == "Recount" then if SV:IsDockletReady("Recount") then if alternate == "Recount" and EXTRA.FrameName ~= "Recount_MainWindow" then tipRight = "and Recount"; SV:RegisterExtraDocklet("Recount_MainWindow") PLUGIN:Docklet_Recount(EXTRA) PLUGIN.DockedParent["Recount"] = EXTRA elseif MAIN.FrameName ~= "Recount_MainWindow" then tipLeft = "Recount"; SV:RegisterMainDocklet("Recount_MainWindow") PLUGIN:Docklet_Recount(MAIN) PLUGIN.DockedParent["Recount"] = MAIN end end end if main == "TinyDPS" or alternate == "TinyDPS" then if SV:IsDockletReady("TinyDPS") then if alternate == "TinyDPS" and EXTRA.FrameName ~= "tdpsFrame" then tipRight = "and TinyDPS"; SV:RegisterExtraDocklet("tdpsFrame") PLUGIN:Docklet_TinyDPS(EXTRA) PLUGIN.DockedParent["TinyDPS"] = EXTRA elseif MAIN.FrameName ~= "tdpsFrame" then tipLeft = "TinyDPS"; SV:RegisterMainDocklet("tdpsFrame") PLUGIN:Docklet_TinyDPS(MAIN) PLUGIN.DockedParent["TinyDPS"] = MAIN end end end if main == "alDamageMeter" or alternate == "alDamageMeter" then if SV:IsDockletReady("alDamageMeter") then if alternate == "alDamageMeter" and EXTRA.FrameName ~= "alDamagerMeterFrame" then tipRight = "and alDamageMeter"; SV:RegisterExtraDocklet("alDamagerMeterFrame") PLUGIN:Docklet_alDamageMeter(EXTRA) PLUGIN.DockedParent["alDamageMeter"] = EXTRA elseif MAIN.FrameName ~= "alDamagerMeterFrame" then tipLeft = "alDamageMeter"; SV:RegisterMainDocklet("alDamagerMeterFrame") PLUGIN:Docklet_alDamageMeter(MAIN) PLUGIN.DockedParent["alDamageMeter"] = MAIN end end end if(_G["SVUI_AddonDocklet"]) then _G["SVUI_AddonDocklet"].TText = ("%s%s"):format(tipLeft, tipRight) end end --[[ ########################################################## BUILD FUNCTION ########################################################## ]]-- function PLUGIN:Load() if(not SV.db[Schema].enable) then return end local alert = CreateFrame('Frame', nil, UIParent); alert:SetFixedPanelTemplate('Transparent'); alert:SetSize(250, 70); alert:SetPoint('CENTER', UIParent, 'CENTER'); alert:SetFrameStrata('DIALOG'); alert.Text = alert:CreateFontString(nil, "OVERLAY"); alert.Text:SetFont(SV.Media.font.default, 12); alert.Text:SetPoint('TOP', alert, 'TOP', 0, -10); alert.Accept = CreateFrame('Button', nil, alert); alert.Accept:SetSize(70, 25); alert.Accept:SetPoint('RIGHT', alert, 'BOTTOM', -10, 20); alert.Accept.Text = alert.Accept:CreateFontString(nil, "OVERLAY"); alert.Accept.Text:SetFont(SV.Media.font.default, 10); alert.Accept.Text:SetPoint('CENTER'); alert.Accept.Text:SetText(YES); alert.Close = CreateFrame('Button', nil, alert); alert.Close:SetSize(70, 25); alert.Close:SetPoint('LEFT', alert, 'BOTTOM', 10, 20); alert.Close:SetScript('OnClick', function(this) this:GetParent():Hide() end); alert.Close.Text = alert.Close:CreateFontString(nil, "OVERLAY"); alert.Close.Text:SetFont(SV.Media.font.default, 10); alert.Close.Text:SetPoint('CENTER'); alert.Close.Text:SetText(NO); alert.Accept:SetButtonTemplate(); alert.Close:SetButtonTemplate(); alert:Hide(); self.Alert = alert; NewHook(SV, "ReloadDocklets", RegisterAddonDocklets); SV:ReloadDocklets(); SV.DynamicOptions[Schema] = {key = "addons", data = self.OptionsCache}; local option = { order = 2, type = "toggle", name = "Standard UI Styling", get = function(a)return SV.db[Schema].blizzard.enable end, set = function(a,b) SV.db[Schema].blizzard.enable = b; SV:StaticPopup_Show("RL_CLIENT") end } self:AddOption("blizzardEnable", option) option = { order = 3, type = "toggle", name = "Addon Styling", get = function(a)return SV.db[Schema].addons.enable end, set = function(a,b) SV.db[Schema].addons.enable = b; SV:StaticPopup_Show("RL_CLIENT") end } self:AddOption("addonEnable", option) option = { order = 300, type = "group", name = "Individual Mods", get = function(a)return SV.db[Schema].blizzard[a[#a]]end, set = function(a,b) SV.db[Schema].blizzard[a[#a]] = b; SV:StaticPopup_Show("RL_CLIENT") end, disabled = function() return not SV.db[Schema].blizzard.enable end, guiInline = true, args = { bmah = { type = "toggle", name = L["Black Market AH"], desc = L["TOGGLEART_DESC"] }, chat = { type = "toggle", name = L["Chat Menus"], desc = L["TOGGLEART_DESC"] }, transmogrify = { type = "toggle", name = L["Transmogrify Frame"], desc = L["TOGGLEART_DESC"] }, encounterjournal = { type = "toggle", name = L["Encounter Journal"], desc = L["TOGGLEART_DESC"] }, reforge = { type = "toggle", name = L["Reforge Frame"], desc = L["TOGGLEART_DESC"] }, calendar = { type = "toggle", name = L["Calendar Frame"], desc = L["TOGGLEART_DESC"] }, achievement = { type = "toggle", name = L["Achievement Frame"], desc = L["TOGGLEART_DESC"] }, lfguild = { type = "toggle", name = L["LF Guild Frame"], desc = L["TOGGLEART_DESC"] }, inspect = { type = "toggle", name = L["Inspect Frame"], desc = L["TOGGLEART_DESC"] }, binding = { type = "toggle", name = L["KeyBinding Frame"], desc = L["TOGGLEART_DESC"] }, gbank = { type = "toggle", name = L["Guild Bank"], desc = L["TOGGLEART_DESC"] }, archaeology = { type = "toggle", name = L["Archaeology Frame"], desc = L["TOGGLEART_DESC"] }, guildcontrol = { type = "toggle", name = L["Guild Control Frame"], desc = L["TOGGLEART_DESC"] }, guild = { type = "toggle", name = L["Guild Frame"], desc = L["TOGGLEART_DESC"] }, tradeskill = { type = "toggle", name = L["TradeSkill Frame"], desc = L["TOGGLEART_DESC"] }, raid = { type = "toggle", name = L["Raid Frame"], desc = L["TOGGLEART_DESC"] }, talent = { type = "toggle", name = L["Talent Frame"], desc = L["TOGGLEART_DESC"] }, auctionhouse = { type = "toggle", name = L["Auction Frame"], desc = L["TOGGLEART_DESC"] }, timemanager = { type = "toggle", name = L["Time Manager"], desc = L["TOGGLEART_DESC"] }, barber = { type = "toggle", name = L["Barbershop Frame"], desc = L["TOGGLEART_DESC"] }, macro = { type = "toggle", name = L["Macro Frame"], desc = L["TOGGLEART_DESC"] }, debug = { type = "toggle", name = L["Debug Tools"], desc = L["TOGGLEART_DESC"] }, trainer = { type = "toggle", name = L["Trainer Frame"], desc = L["TOGGLEART_DESC"] }, socket = { type = "toggle", name = L["Socket Frame"], desc = L["TOGGLEART_DESC"] }, alertframes = { type = "toggle", name = L["Alert Frames"], desc = L["TOGGLEART_DESC"] }, loot = { type = "toggle", name = L["Loot Frames"], desc = L["TOGGLEART_DESC"] }, bgscore = { type = "toggle", name = L["BG Score"], desc = L["TOGGLEART_DESC"] }, merchant = { type = "toggle", name = L["Merchant Frame"], desc = L["TOGGLEART_DESC"] }, mail = { type = "toggle", name = L["Mail Frame"], desc = L["TOGGLEART_DESC"] }, help = { type = "toggle", name = L["Help Frame"], desc = L["TOGGLEART_DESC"] }, trade = { type = "toggle", name = L["Trade Frame"], desc = L["TOGGLEART_DESC"] }, gossip = { type = "toggle", name = L["Gossip Frame"], desc = L["TOGGLEART_DESC"] }, greeting = { type = "toggle", name = L["Greeting Frame"], desc = L["TOGGLEART_DESC"] }, worldmap = { type = "toggle", name = L["World Map"], desc = L["TOGGLEART_DESC"] }, taxi = { type = "toggle", name = L["Taxi Frame"], desc = L["TOGGLEART_DESC"] }, lfg = { type = "toggle", name = L["LFG Frame"], desc = L["TOGGLEART_DESC"] }, mounts = { type = "toggle", name = L["Mounts & Pets"], desc = L["TOGGLEART_DESC"] }, quest = { type = "toggle", name = L["Quest Frames"], desc = L["TOGGLEART_DESC"] }, petition = { type = "toggle", name = L["Petition Frame"], desc = L["TOGGLEART_DESC"] }, dressingroom = { type = "toggle", name = L["Dressing Room"], desc = L["TOGGLEART_DESC"] }, pvp = { type = "toggle", name = L["PvP Frames"], desc = L["TOGGLEART_DESC"] }, nonraid = { type = "toggle", name = L["Non-Raid Frame"], desc = L["TOGGLEART_DESC"] }, friends = { type = "toggle", name = L["Friends"], desc = L["TOGGLEART_DESC"] }, spellbook = { type = "toggle", name = L["Spellbook"], desc = L["TOGGLEART_DESC"] }, character = { type = "toggle", name = L["Character Frame"], desc = L["TOGGLEART_DESC"] }, misc = { type = "toggle", name = L["Misc Frames"], desc = L["TOGGLEART_DESC"] }, tabard = { type = "toggle", name = L["Tabard Frame"], desc = L["TOGGLEART_DESC"] }, guildregistrar = { type = "toggle", name = L["Guild Registrar"], desc = L["TOGGLEART_DESC"] }, bags = { type = "toggle", name = L["Bags"], desc = L["TOGGLEART_DESC"] }, stable = { type = "toggle", name = L["Stable"], desc = L["TOGGLEART_DESC"] }, bgmap = { type = "toggle", name = L["BG Map"], desc = L["TOGGLEART_DESC"] }, petbattleui = { type = "toggle", name = L["Pet Battle"], desc = L["TOGGLEART_DESC"] }, losscontrol = { type = "toggle", name = L["Loss Control"], desc = L["TOGGLEART_DESC"] }, voidstorage = { type = "toggle", name = L["Void Storage"], desc = L["TOGGLEART_DESC"] }, itemUpgrade = { type = "toggle", name = L["Item Upgrade"], desc = L["TOGGLEART_DESC"] } } } self:AddOption("blizzard", option) self:AddOption("addons", self.OptionsCache) self:RegisterEvent("PLAYER_ENTERING_WORLD"); self:RegisterEvent("ADDON_LOADED"); end