/
local LIBSTUB_MAJOR,LIBSTUB_MINOR="LibStub",2 |
local LibStub=_G[LIBSTUB_MAJOR] |
if not LibStub or LibStub.minor<LIBSTUB_MINOR then |
LibStub=LibStub or{libs={},minors={}} |
_G[LIBSTUB_MAJOR]=LibStub |
LibStub.minor=LIBSTUB_MINOR |
function LibStub:NewLibrary(major,minor) |
assert(type(major)=="string","Bad argument #2 to `NewLibrary' (string expected)") |
minor=assert(tonumber(strmatch(minor,"%d+")),"Minor version must either be a number or contain a number.") |
local oldminor=self.minors[major] |
if oldminor and oldminor>=minor then return nil end |
self.minors[major],self.libs[major]=minor,self.libs[major]or{} |
return self.libs[major],oldminor |
end |
function LibStub:GetLibrary(major,silent) |
if not self.libs[major]and not silent then |
error(("Cannot find a library instance of %q."):format(tostring(major)),2) |
end |
return self.libs[major],self.minors[major] |
end |
function LibStub:IterateLibraries()return pairs(self.libs)end |
setmetatable(LibStub,{__call=LibStub.GetLibrary}) |
end |
local MAJOR,MINOR="CallbackHandler-1.0",7 |
local CallbackHandler=LibStub:NewLibrary(MAJOR,MINOR) |
if not CallbackHandler then return end |
local meta={__index=function(tbl,key)tbl[key]={}return tbl[key]end} |
local tconcat=table.concat |
local assert,error,loadstring=assert,error,loadstring |
local setmetatable,rawset,rawget=setmetatable,rawset,rawget |
local next,select,pairs,type,tostring=next,select,pairs,type,tostring |
local xpcall=xpcall |
local function errorhandler(err) |
return geterrorhandler()(err) |
end |
local function Dispatch(handlers,...) |
local index,method=next(handlers) |
if not method then return end |
repeat |
xpcall(method,errorhandler,...) |
index,method=next(handlers,index) |
until not method |
end |
function CallbackHandler:New(target,RegisterName,UnregisterName,UnregisterAllName) |
RegisterName=RegisterName or"RegisterCallback" |
UnregisterName=UnregisterName or"UnregisterCallback" |
if UnregisterAllName==nil then |
UnregisterAllName="UnregisterAllCallbacks" |
end |
local events=setmetatable({},meta) |
local registry={recurse=0,events=events} |
function registry:Fire(eventname,...) |
if not rawget(events,eventname)or not next(events[eventname])then return end |
local oldrecurse=registry.recurse |
registry.recurse=oldrecurse+1 |
Dispatch(events[eventname],eventname,...) |
registry.recurse=oldrecurse |
if registry.insertQueue and oldrecurse==0 then |
for eventname,callbacks in pairs(registry.insertQueue)do |
local first=not rawget(events,eventname)or not next(events[eventname]) |
for self,func in pairs(callbacks)do |
events[eventname][self]=func |
if first and registry.OnUsed then |
registry.OnUsed(registry,target,eventname) |
first=nil |
end |
end |
end |
registry.insertQueue=nil |
end |
end |
target[RegisterName]=function(self,eventname,method,...) |
if type(eventname)~="string"then |
error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.",2) |
end |
method=method or eventname |
local first=not rawget(events,eventname)or not next(events[eventname]) |
if type(method)~="string"and type(method)~="function"then |
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.",2) |
end |
local regfunc |
if type(method)=="string"then |
if type(self)~="table"then |
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?",2) |
elseif self==target then |
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'",2) |
elseif type(self[method])~="function"then |
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.",2) |
end |
if select("#",...)>=1 then |
local arg=select(1,...) |
regfunc=function(...)self[method](self,arg,...)end |
else |
regfunc=function(...)self[method](self,...)end |
end |
else |
if type(self)~="table"and type(self)~="string"and type(self)~="thread"then |
error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string or thread expected.",2) |
end |
if select("#",...)>=1 then |
local arg=select(1,...) |
regfunc=function(...)method(arg,...)end |
else |
regfunc=method |
end |
end |
if events[eventname][self]or registry.recurse<1 then |
events[eventname][self]=regfunc |
if registry.OnUsed and first then |
registry.OnUsed(registry,target,eventname) |
end |
else |
registry.insertQueue=registry.insertQueue or setmetatable({},meta) |
registry.insertQueue[eventname][self]=regfunc |
end |
end |
target[UnregisterName]=function(self,eventname) |
if not self or self==target then |
error("Usage: "..UnregisterName.."(eventname): bad 'self'",2) |
end |
if type(eventname)~="string"then |
error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.",2) |
end |
if rawget(events,eventname)and events[eventname][self]then |
events[eventname][self]=nil |
if registry.OnUnused and not next(events[eventname])then |
registry.OnUnused(registry,target,eventname) |
end |
end |
if registry.insertQueue and rawget(registry.insertQueue,eventname)and registry.insertQueue[eventname][self]then |
registry.insertQueue[eventname][self]=nil |
end |
end |
if UnregisterAllName then |
target[UnregisterAllName]=function(...) |
if select("#",...)<1 then |
error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.",2) |
end |
if select("#",...)==1 and...==target then |
error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"",2) |
end |
for i=1,select("#",...)do |
local self=select(i,...) |
if registry.insertQueue then |
for eventname,callbacks in pairs(registry.insertQueue)do |
if callbacks[self]then |
callbacks[self]=nil |
end |
end |
end |
for eventname,callbacks in pairs(events)do |
if callbacks[self]then |
callbacks[self]=nil |
if registry.OnUnused and not next(callbacks)then |
registry.OnUnused(registry,target,eventname) |
end |
end |
end |
end |
end |
end |
return registry |
end |
--[[ $Id: CallbackHandler-1.0.lua 14 2010-08-09 00:43:38Z mikk $ ]] |
local MAJOR, MINOR = "CallbackHandler-1.0", 6 |
local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR) |
if not CallbackHandler then return end -- No upgrade needed |
local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end} |
-- Lua APIs |
local tconcat = table.concat |
local assert, error, loadstring = assert, error, loadstring |
local setmetatable, rawset, rawget = setmetatable, rawset, rawget |
local next, select, pairs, type, tostring = next, select, pairs, type, tostring |
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded |
-- List them here for Mikk's FindGlobals script |
-- GLOBALS: geterrorhandler |
local xpcall = xpcall |
local function errorhandler(err) |
return geterrorhandler()(err) |
end |
local function CreateDispatcher(argCount) |
local code = [[ |
local next, xpcall, eh = ... |
local method, ARGS |
local function call() method(ARGS) end |
local function dispatch(handlers, ...) |
local index |
index, method = next(handlers) |
if not method then return end |
local OLD_ARGS = ARGS |
ARGS = ... |
repeat |
xpcall(call, eh) |
index, method = next(handlers, index) |
until not method |
ARGS = OLD_ARGS |
end |
return dispatch |
]] |
local ARGS, OLD_ARGS = {}, {} |
for i = 1, argCount do ARGS[i], OLD_ARGS[i] = "arg"..i, "old_arg"..i end |
code = code:gsub("OLD_ARGS", tconcat(OLD_ARGS, ", ")):gsub("ARGS", tconcat(ARGS, ", ")) |
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(next, xpcall, errorhandler) |
end |
local Dispatchers = setmetatable({}, {__index=function(self, argCount) |
local dispatcher = CreateDispatcher(argCount) |
rawset(self, argCount, dispatcher) |
return dispatcher |
end}) |
-------------------------------------------------------------------------- |
-- CallbackHandler:New |
-- |
-- target - target object to embed public APIs in |
-- RegisterName - name of the callback registration API, default "RegisterCallback" |
-- UnregisterName - name of the callback unregistration API, default "UnregisterCallback" |
-- UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API. |
function CallbackHandler:New(target, RegisterName, UnregisterName, UnregisterAllName, OnUsed, OnUnused) |
-- TODO: Remove this after beta has gone out |
assert(not OnUsed and not OnUnused, "ACE-80: OnUsed/OnUnused are deprecated. Callbacks are now done to registry.OnUsed and registry.OnUnused") |
RegisterName = RegisterName or "RegisterCallback" |
UnregisterName = UnregisterName or "UnregisterCallback" |
if UnregisterAllName==nil then -- false is used to indicate "don't want this method" |
UnregisterAllName = "UnregisterAllCallbacks" |
end |
-- we declare all objects and exported APIs inside this closure to quickly gain access |
-- to e.g. function names, the "target" parameter, etc |
-- Create the registry object |
local events = setmetatable({}, meta) |
local registry = { recurse=0, events=events } |
-- registry:Fire() - fires the given event/message into the registry |
function registry:Fire(eventname, ...) |
if not rawget(events, eventname) or not next(events[eventname]) then return end |
local oldrecurse = registry.recurse |
registry.recurse = oldrecurse + 1 |
Dispatchers[select('#', ...) + 1](events[eventname], eventname, ...) |
registry.recurse = oldrecurse |
if registry.insertQueue and oldrecurse==0 then |
-- Something in one of our callbacks wanted to register more callbacks; they got queued |
for eventname,callbacks in pairs(registry.insertQueue) do |
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten. |
for self,func in pairs(callbacks) do |
events[eventname][self] = func |
-- fire OnUsed callback? |
if first and registry.OnUsed then |
registry.OnUsed(registry, target, eventname) |
first = nil |
end |
end |
end |
registry.insertQueue = nil |
end |
end |
-- Registration of a callback, handles: |
-- self["method"], leads to self["method"](self, ...) |
-- self with function ref, leads to functionref(...) |
-- "addonId" (instead of self) with function ref, leads to functionref(...) |
-- all with an optional arg, which, if present, gets passed as first argument (after self if present) |
target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]]) |
if type(eventname) ~= "string" then |
error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2) |
end |
method = method or eventname |
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten. |
if type(method) ~= "string" and type(method) ~= "function" then |
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2) |
end |
local regfunc |
if type(method) == "string" then |
-- self["method"] calling style |
if type(self) ~= "table" then |
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2) |
elseif self==target then |
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2) |
elseif type(self[method]) ~= "function" then |
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2) |
end |
if select("#",...)>=1 then -- this is not the same as testing for arg==nil! |
local arg=select(1,...) |
regfunc = function(...) self[method](self,arg,...) end |
else |
regfunc = function(...) self[method](self,...) end |
end |
else |
-- function ref with self=object or self="addonId" or self=thread |
if type(self)~="table" and type(self)~="string" and type(self)~="thread" then |
error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string or thread expected.", 2) |
end |
if select("#",...)>=1 then -- this is not the same as testing for arg==nil! |
local arg=select(1,...) |
regfunc = function(...) method(arg,...) end |
else |
regfunc = method |
end |
end |
if events[eventname][self] or registry.recurse<1 then |
-- if registry.recurse<1 then |
-- we're overwriting an existing entry, or not currently recursing. just set it. |
events[eventname][self] = regfunc |
-- fire OnUsed callback? |
if registry.OnUsed and first then |
registry.OnUsed(registry, target, eventname) |
end |
else |
-- we're currently processing a callback in this registry, so delay the registration of this new entry! |
-- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency |
registry.insertQueue = registry.insertQueue or setmetatable({},meta) |
registry.insertQueue[eventname][self] = regfunc |
end |
end |
-- Unregister a callback |
target[UnregisterName] = function(self, eventname) |
if not self or self==target then |
error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2) |
end |
if type(eventname) ~= "string" then |
error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2) |
end |
if rawget(events, eventname) and events[eventname][self] then |
events[eventname][self] = nil |
-- Fire OnUnused callback? |
if registry.OnUnused and not next(events[eventname]) then |
registry.OnUnused(registry, target, eventname) |
end |
end |
if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then |
registry.insertQueue[eventname][self] = nil |
end |
end |
-- OPTIONAL: Unregister all callbacks for given selfs/addonIds |
if UnregisterAllName then |
target[UnregisterAllName] = function(...) |
if select("#",...)<1 then |
error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2) |
end |
if select("#",...)==1 and ...==target then |
error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2) |
end |
for i=1,select("#",...) do |
local self = select(i,...) |
if registry.insertQueue then |
for eventname, callbacks in pairs(registry.insertQueue) do |
if callbacks[self] then |
callbacks[self] = nil |
end |
end |
end |
for eventname, callbacks in pairs(events) do |
if callbacks[self] then |
callbacks[self] = nil |
-- Fire OnUnused callback? |
if registry.OnUnused and not next(callbacks) then |
registry.OnUnused(registry, target, eventname) |
end |
end |
end |
end |
end |
end |
return registry |
end |
-- CallbackHandler purposefully does NOT do explicit embedding. Nor does it |
-- try to upgrade old implicit embeds since the system is selfcontained and |
-- relies on closures to work. |
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ |
..\FrameXML\UI.xsd"> |
<Script file="LibSharedMedia-3.0.lua" /> |
</Ui> |
--[[ |
Name: LibSharedMedia-3.0 |
Revision: $Revision: 91 $ |
Author: Elkano (elkano@gmx.de) |
Inspired By: SurfaceLib by Haste/Otravi (troeks@gmail.com) |
Website: http://www.wowace.com/projects/libsharedmedia-3-0/ |
Description: Shared handling of media data (fonts, sounds, textures, ...) between addons. |
Dependencies: LibStub, CallbackHandler-1.0 |
License: LGPL v2.1 |
]] |
local MAJOR, MINOR = "LibSharedMedia-3.0", 6010002 -- 6.1.0 v2 / increase manually on changes |
local lib = LibStub:NewLibrary(MAJOR, MINOR) |
if not lib then return end |
local _G = getfenv(0) |
local pairs = _G.pairs |
local type = _G.type |
local band = _G.bit.band |
local table_insert = _G.table.insert |
local table_sort = _G.table.sort |
local locale = GetLocale() |
local locale_is_western |
local LOCALE_MASK = 0 |
lib.LOCALE_BIT_koKR = 1 |
lib.LOCALE_BIT_ruRU = 2 |
lib.LOCALE_BIT_zhCN = 4 |
lib.LOCALE_BIT_zhTW = 8 |
lib.LOCALE_BIT_western = 128 |
local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0") |
lib.callbacks = lib.callbacks or CallbackHandler:New(lib) |
lib.DefaultMedia = lib.DefaultMedia or {} |
lib.MediaList = lib.MediaList or {} |
lib.MediaTable = lib.MediaTable or {} |
lib.MediaType = lib.MediaType or {} |
lib.OverrideMedia = lib.OverrideMedia or {} |
local defaultMedia = lib.DefaultMedia |
local mediaList = lib.MediaList |
local mediaTable = lib.MediaTable |
local overrideMedia = lib.OverrideMedia |
-- create mediatype constants |
lib.MediaType.BACKGROUND = "background" -- background textures |
lib.MediaType.BORDER = "border" -- border textures |
lib.MediaType.FONT = "font" -- fonts |
lib.MediaType.STATUSBAR = "statusbar" -- statusbar textures |
lib.MediaType.SOUND = "sound" -- sound files |
-- populate lib with default Blizzard data |
-- BACKGROUND |
if not lib.MediaTable.background then lib.MediaTable.background = {} end |
lib.MediaTable.background["None"] = [[]] |
lib.MediaTable.background["Blizzard Collections Background"] = [[Interface\Collections\CollectionsBackgroundTile]] |
lib.MediaTable.background["Blizzard Dialog Background"] = [[Interface\DialogFrame\UI-DialogBox-Background]] |
lib.MediaTable.background["Blizzard Dialog Background Dark"] = [[Interface\DialogFrame\UI-DialogBox-Background-Dark]] |
lib.MediaTable.background["Blizzard Dialog Background Gold"] = [[Interface\DialogFrame\UI-DialogBox-Gold-Background]] |
lib.MediaTable.background["Blizzard Garrison Background"] = [[Interface\Garrison\GarrisonUIBackground]] |
lib.MediaTable.background["Blizzard Garrison Background 2"] = [[Interface\Garrison\GarrisonUIBackground2]] |
lib.MediaTable.background["Blizzard Garrison Background 3"] = [[Interface\Garrison\GarrisonMissionUIInfoBoxBackgroundTile]] |
lib.MediaTable.background["Blizzard Low Health"] = [[Interface\FullScreenTextures\LowHealth]] |
lib.MediaTable.background["Blizzard Marble"] = [[Interface\FrameGeneral\UI-Background-Marble]] |
lib.MediaTable.background["Blizzard Out of Control"] = [[Interface\FullScreenTextures\OutOfControl]] |
lib.MediaTable.background["Blizzard Parchment"] = [[Interface\AchievementFrame\UI-Achievement-Parchment-Horizontal]] |
lib.MediaTable.background["Blizzard Parchment 2"] = [[Interface\AchievementFrame\UI-GuildAchievement-Parchment-Horizontal]] |
lib.MediaTable.background["Blizzard Rock"] = [[Interface\FrameGeneral\UI-Background-Rock]] |
lib.MediaTable.background["Blizzard Tabard Background"] = [[Interface\TabardFrame\TabardFrameBackground]] |
lib.MediaTable.background["Blizzard Tooltip"] = [[Interface\Tooltips\UI-Tooltip-Background]] |
lib.MediaTable.background["Solid"] = [[Interface\Buttons\WHITE8X8]] |
lib.DefaultMedia.background = "None" |
-- BORDER |
if not lib.MediaTable.border then lib.MediaTable.border = {} end |
lib.MediaTable.border["None"] = [[]] |
lib.MediaTable.border["Blizzard Achievement Wood"] = [[Interface\AchievementFrame\UI-Achievement-WoodBorder]] |
lib.MediaTable.border["Blizzard Chat Bubble"] = [[Interface\Tooltips\ChatBubble-Backdrop]] |
lib.MediaTable.border["Blizzard Dialog"] = [[Interface\DialogFrame\UI-DialogBox-Border]] |
lib.MediaTable.border["Blizzard Dialog Gold"] = [[Interface\DialogFrame\UI-DialogBox-Gold-Border]] |
lib.MediaTable.border["Blizzard Party"] = [[Interface\CHARACTERFRAME\UI-Party-Border]] |
lib.MediaTable.border["Blizzard Tooltip"] = [[Interface\Tooltips\UI-Tooltip-Border]] |
lib.DefaultMedia.border = "None" |
-- FONT |
if not lib.MediaTable.font then lib.MediaTable.font = {} end |
local SML_MT_font = lib.MediaTable.font |
--[[ |
All font files are currently in all clients, the following table depicts which font supports which charset as of 5.0.4 |
Fonts were checked using langcover.pl from DejaVu fonts (http://sourceforge.net/projects/dejavu/) and FontForge (http://fontforge.org/) |
latin means check for: de, en, es, fr, it, pt |
file name latin koKR ruRU zhCN zhTW |
2002.ttf 2002 X X X - - |
2002B.ttf 2002 Bold X X X - - |
ARHei.ttf AR CrystalzcuheiGBK Demibold X - X X X |
ARIALN.TTF Arial Narrow X - X - - |
ARKai_C.ttf AR ZhongkaiGBK Medium (Combat) X - X X X |
ARKai_T.ttf AR ZhongkaiGBK Medium X - X X X |
bHEI00M.ttf AR Heiti2 Medium B5 - - - - X |
bHEI01B.ttf AR Heiti2 Bold B5 - - - - X |
bKAI00M.ttf AR Kaiti Medium B5 - - - - X |
bLEI00D.ttf AR Leisu Demi B5 - - - - X |
FRIZQT__.TTF Friz Quadrata TT X - - - - |
FRIZQT___CYR.TTF FrizQuadrataCTT x - X - - |
K_Damage.TTF YDIWingsM - X X - - |
K_Pagetext.TTF MoK X X X - - |
MORPHEUS.TTF Morpheus X - - - - |
MORPHEUS_CYR.TTF Morpheus X - X - - |
NIM_____.ttf Nimrod MT X - X - - |
SKURRI.TTF Skurri X - - - - |
SKURRI_CYR.TTF Skurri X - X - - |
WARNING: Although FRIZQT___CYR is available on western clients, it doesn't support special European characters e.g. é, ï, ö |
Due to this, we cannot use it as a replacement for FRIZQT__.TTF |
]] |
if locale == "koKR" then |
LOCALE_MASK = lib.LOCALE_BIT_koKR |
-- |
SML_MT_font["êµµì ê¸ê¼´"] = [[Fonts\2002B.TTF]] |
SML_MT_font["기본 ê¸ê¼´"] = [[Fonts\2002.TTF]] |
SML_MT_font["ë°ë¯¸ì§ ê¸ê¼´"] = [[Fonts\K_Damage.TTF]] |
SML_MT_font["íì¤í¸ ê¸ê¼´"] = [[Fonts\K_Pagetext.TTF]] |
-- |
lib.DefaultMedia["font"] = "기본 ê¸ê¼´" -- someone from koKR please adjust if needed |
-- |
elseif locale == "zhCN" then |
LOCALE_MASK = lib.LOCALE_BIT_zhCN |
-- |
SML_MT_font["伤害æ°å"] = [[Fonts\ARKai_C.ttf]] |
SML_MT_font["é»è®¤"] = [[Fonts\ARKai_T.ttf]] |
SML_MT_font["è天"] = [[Fonts\ARHei.ttf]] |
-- |
lib.DefaultMedia["font"] = "é»è®¤" -- someone from zhCN please adjust if needed |
-- |
elseif locale == "zhTW" then |
LOCALE_MASK = lib.LOCALE_BIT_zhTW |
-- |
SML_MT_font["æ示è¨æ¯"] = [[Fonts\bHEI00M.ttf]] |
SML_MT_font["è天"] = [[Fonts\bHEI01B.ttf]] |
SML_MT_font["å·å®³æ¸å"] = [[Fonts\bKAI00M.ttf]] |
SML_MT_font["é è¨"] = [[Fonts\bLEI00D.ttf]] |
-- |
lib.DefaultMedia["font"] = "é è¨" -- someone from zhTW please adjust if needed |
elseif locale == "ruRU" then |
LOCALE_MASK = lib.LOCALE_BIT_ruRU |
-- |
SML_MT_font["2002"] = [[Fonts\2002.TTF]] |
SML_MT_font["2002 Bold"] = [[Fonts\2002B.TTF]] |
SML_MT_font["AR CrystalzcuheiGBK Demibold"] = [[Fonts\ARHei.TTF]] |
SML_MT_font["AR ZhongkaiGBK Medium (Combat)"] = [[Fonts\ARKai_C.TTF]] |
SML_MT_font["AR ZhongkaiGBK Medium"] = [[Fonts\ARKai_T.TTF]] |
SML_MT_font["Arial Narrow"] = [[Fonts\ARIALN.TTF]] |
SML_MT_font["Friz Quadrata TT"] = [[Fonts\FRIZQT___CYR.TTF]] |
SML_MT_font["MoK"] = [[Fonts\K_Pagetext.TTF]] |
SML_MT_font["Morpheus"] = [[Fonts\MORPHEUS_CYR.TTF]] |
SML_MT_font["Nimrod MT"] = [[Fonts\NIM_____.ttf]] |
SML_MT_font["Skurri"] = [[Fonts\SKURRI_CYR.TTF]] |
-- |
lib.DefaultMedia.font = "Friz Quadrata TT" |
-- |
else |
LOCALE_MASK = lib.LOCALE_BIT_western |
locale_is_western = true |
-- |
SML_MT_font["2002"] = [[Fonts\2002.TTF]] |
SML_MT_font["2002 Bold"] = [[Fonts\2002B.TTF]] |
SML_MT_font["AR CrystalzcuheiGBK Demibold"] = [[Fonts\ARHei.TTF]] |
SML_MT_font["AR ZhongkaiGBK Medium (Combat)"] = [[Fonts\ARKai_C.TTF]] |
SML_MT_font["AR ZhongkaiGBK Medium"] = [[Fonts\ARKai_T.TTF]] |
SML_MT_font["Arial Narrow"] = [[Fonts\ARIALN.TTF]] |
SML_MT_font["Friz Quadrata TT"] = [[Fonts\FRIZQT__.TTF]] |
SML_MT_font["MoK"] = [[Fonts\K_Pagetext.TTF]] |
SML_MT_font["Morpheus"] = [[Fonts\MORPHEUS_CYR.TTF]] |
SML_MT_font["Nimrod MT"] = [[Fonts\NIM_____.ttf]] |
SML_MT_font["Skurri"] = [[Fonts\SKURRI_CYR.TTF]] |
-- |
lib.DefaultMedia.font = "Friz Quadrata TT" |
-- |
end |
-- STATUSBAR |
if not lib.MediaTable.statusbar then lib.MediaTable.statusbar = {} end |
lib.MediaTable.statusbar["Blizzard"] = [[Interface\TargetingFrame\UI-StatusBar]] |
lib.MediaTable.statusbar["Blizzard Character Skills Bar"] = [[Interface\PaperDollInfoFrame\UI-Character-Skills-Bar]] |
lib.MediaTable.statusbar["Blizzard Raid Bar"] = [[Interface\RaidFrame\Raid-Bar-Hp-Fill]] |
lib.DefaultMedia.statusbar = "Blizzard" |
-- SOUND |
if not lib.MediaTable.sound then lib.MediaTable.sound = {} end |
lib.MediaTable.sound["None"] = [[Interface\Quiet.ogg]] -- Relies on the fact that PlaySound[File] doesn't error on non-existing input. |
lib.DefaultMedia.sound = "None" |
local function rebuildMediaList(mediatype) |
local mtable = mediaTable[mediatype] |
if not mtable then return end |
if not mediaList[mediatype] then mediaList[mediatype] = {} end |
local mlist = mediaList[mediatype] |
-- list can only get larger, so simply overwrite it |
local i = 0 |
for k in pairs(mtable) do |
i = i + 1 |
mlist[i] = k |
end |
table_sort(mlist) |
end |
function lib:Register(mediatype, key, data, langmask) |
if type(mediatype) ~= "string" then |
error(MAJOR..":Register(mediatype, key, data, langmask) - mediatype must be string, got "..type(mediatype)) |
end |
if type(key) ~= "string" then |
error(MAJOR..":Register(mediatype, key, data, langmask) - key must be string, got "..type(key)) |
end |
mediatype = mediatype:lower() |
if mediatype == lib.MediaType.FONT and ((langmask and band(langmask, LOCALE_MASK) == 0) or not (langmask or locale_is_western)) then return false end |
if mediatype == lib.MediaType.SOUND and type(data) == "string" then |
local path = data:lower() |
-- Only ogg and mp3 are valid sounds. |
if not path:find(".ogg", nil, true) and not path:find(".mp3", nil, true) then |
return false |
end |
end |
if not mediaTable[mediatype] then mediaTable[mediatype] = {} end |
local mtable = mediaTable[mediatype] |
if mtable[key] then return false end |
mtable[key] = data |
rebuildMediaList(mediatype) |
self.callbacks:Fire("LibSharedMedia_Registered", mediatype, key) |
return true |
end |
function lib:Fetch(mediatype, key, noDefault) |
local mtt = mediaTable[mediatype] |
local overridekey = overrideMedia[mediatype] |
local result = mtt and ((overridekey and mtt[overridekey] or mtt[key]) or (not noDefault and defaultMedia[mediatype] and mtt[defaultMedia[mediatype]])) or nil |
return result ~= "" and result or nil |
end |
function lib:IsValid(mediatype, key) |
return mediaTable[mediatype] and (not key or mediaTable[mediatype][key]) and true or false |
end |
function lib:HashTable(mediatype) |
return mediaTable[mediatype] |
end |
function lib:List(mediatype) |
if not mediaTable[mediatype] then |
return nil |
end |
if not mediaList[mediatype] then |
rebuildMediaList(mediatype) |
end |
return mediaList[mediatype] |
end |
function lib:GetGlobal(mediatype) |
return overrideMedia[mediatype] |
end |
function lib:SetGlobal(mediatype, key) |
if not mediaTable[mediatype] then |
return false |
end |
overrideMedia[mediatype] = (key and mediaTable[mediatype][key]) and key or nil |
self.callbacks:Fire("LibSharedMedia_SetGlobal", mediatype, overrideMedia[mediatype]) |
return true |
end |
function lib:GetDefault(mediatype) |
return defaultMedia[mediatype] |
end |
function lib:SetDefault(mediatype, key) |
if mediaTable[mediatype] and mediaTable[mediatype][key] and not defaultMedia[mediatype] then |
defaultMedia[mediatype] = key |
return true |
else |
return false |
end |
end |
## Interface: 80000 |
## LoadOnDemand: 1 |
## Title: Lib: SharedMedia-3.0 |
## Notes: Shared handling of media data (fonts, sounds, textures, ...) between addons. |
## Author: Elkano |
## Version: 3.0-102 |
## X-Website: http://www.wowace.com/projects/libsharedmedia-3-0/ |
## X-Category: Library |
## X-Revision: 102 |
## X-Date: 2018-07-17T19:25:42Z |
LibStub\LibStub.lua |
CallbackHandler-1.0\CallbackHandler-1.0.lua |
LibSharedMedia-3.0\lib.xml |
-- $Id: LibStub.lua 76 2007-09-03 01:50:17Z mikk $ |
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info |
-- LibStub is hereby placed in the Public Domain |
-- Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke |
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS! |
local LibStub = _G[LIBSTUB_MAJOR] |
-- Check to see is this version of the stub is obsolete |
if not LibStub or LibStub.minor < LIBSTUB_MINOR then |
LibStub = LibStub or {libs = {}, minors = {} } |
_G[LIBSTUB_MAJOR] = LibStub |
LibStub.minor = LIBSTUB_MINOR |
-- LibStub:NewLibrary(major, minor) |
-- major (string) - the major version of the library |
-- minor (string or number ) - the minor version of the library |
-- |
-- returns nil if a newer or same version of the lib is already present |
-- returns empty library object or old library object if upgrade is needed |
function LibStub:NewLibrary(major, minor) |
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)") |
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.") |
local oldminor = self.minors[major] |
if oldminor and oldminor >= minor then return nil end |
self.minors[major], self.libs[major] = minor, self.libs[major] or {} |
return self.libs[major], oldminor |
end |
-- LibStub:GetLibrary(major, [silent]) |
-- major (string) - the major version of the library |
-- silent (boolean) - if true, library is optional, silently return nil if its not found |
-- |
-- throws an error if the library can not be found (except silent is set) |
-- returns the library object if found |
function LibStub:GetLibrary(major, silent) |
if not self.libs[major] and not silent then |
error(("Cannot find a library instance of %q."):format(tostring(major)), 2) |
end |
return self.libs[major], self.minors[major] |
end |
-- LibStub:IterateLibraries() |
-- |
-- Returns an iterator for the currently registered libraries |
function LibStub:IterateLibraries() |
return pairs(self.libs) |
end |
setmetatable(LibStub, { __call = LibStub.GetLibrary }) |
end |
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ |
..\FrameXML\UI.xsd"> |
<Include file="LibSharedMedia-3.0\lib.xml"/> |
</Ui> |
local MAJOR,MINOR="LibSharedMedia-3.0",8020003 |
local lib=LibStub:NewLibrary(MAJOR,MINOR) |
if not lib then return end |
local _G=getfenv(0) |
local pairs=_G.pairs |
local type=_G.type |
local band=_G.bit.band |
local table_sort=_G.table.sort |
local RESTRICTED_FILE_ACCESS=WOW_PROJECT_ID==WOW_PROJECT_MAINLINE |
local locale=GetLocale() |
local locale_is_western |
local LOCALE_MASK=0 |
lib.LOCALE_BIT_koKR=1 |
lib.LOCALE_BIT_ruRU=2 |
lib.LOCALE_BIT_zhCN=4 |
lib.LOCALE_BIT_zhTW=8 |
lib.LOCALE_BIT_western=128 |
local CallbackHandler=LibStub:GetLibrary("CallbackHandler-1.0") |
lib.callbacks=lib.callbacks or CallbackHandler:New(lib) |
lib.DefaultMedia=lib.DefaultMedia or{} |
lib.MediaList=lib.MediaList or{} |
lib.MediaTable=lib.MediaTable or{} |
lib.MediaType=lib.MediaType or{} |
lib.OverrideMedia=lib.OverrideMedia or{} |
local defaultMedia=lib.DefaultMedia |
local mediaList=lib.MediaList |
local mediaTable=lib.MediaTable |
local overrideMedia=lib.OverrideMedia |
lib.MediaType.BACKGROUND="background" |
lib.MediaType.BORDER="border" |
lib.MediaType.FONT="font" |
lib.MediaType.STATUSBAR="statusbar" |
lib.MediaType.SOUND="sound" |
if not lib.MediaTable.background then lib.MediaTable.background={}end |
lib.MediaTable.background["None"]=[[]] |
lib.MediaTable.background["Blizzard Collections Background"]=[[Interface\Collections\CollectionsBackgroundTile]] |
lib.MediaTable.background["Blizzard Dialog Background"]=[[Interface\DialogFrame\UI-DialogBox-Background]] |
lib.MediaTable.background["Blizzard Dialog Background Dark"]=[[Interface\DialogFrame\UI-DialogBox-Background-Dark]] |
lib.MediaTable.background["Blizzard Dialog Background Gold"]=[[Interface\DialogFrame\UI-DialogBox-Gold-Background]] |
lib.MediaTable.background["Blizzard Garrison Background"]=[[Interface\Garrison\GarrisonUIBackground]] |
lib.MediaTable.background["Blizzard Garrison Background 2"]=[[Interface\Garrison\GarrisonUIBackground2]] |
lib.MediaTable.background["Blizzard Garrison Background 3"]=[[Interface\Garrison\GarrisonMissionUIInfoBoxBackgroundTile]] |
lib.MediaTable.background["Blizzard Low Health"]=[[Interface\FullScreenTextures\LowHealth]] |
lib.MediaTable.background["Blizzard Marble"]=[[Interface\FrameGeneral\UI-Background-Marble]] |
lib.MediaTable.background["Blizzard Out of Control"]=[[Interface\FullScreenTextures\OutOfControl]] |
lib.MediaTable.background["Blizzard Parchment"]=[[Interface\AchievementFrame\UI-Achievement-Parchment-Horizontal]] |
lib.MediaTable.background["Blizzard Parchment 2"]=[[Interface\AchievementFrame\UI-GuildAchievement-Parchment-Horizontal]] |
lib.MediaTable.background["Blizzard Rock"]=[[Interface\FrameGeneral\UI-Background-Rock]] |
lib.MediaTable.background["Blizzard Tabard Background"]=[[Interface\TabardFrame\TabardFrameBackground]] |
lib.MediaTable.background["Blizzard Tooltip"]=[[Interface\Tooltips\UI-Tooltip-Background]] |
lib.MediaTable.background["Solid"]=[[Interface\Buttons\WHITE8X8]] |
lib.DefaultMedia.background="None" |
if not lib.MediaTable.border then lib.MediaTable.border={}end |
lib.MediaTable.border["None"]=[[]] |
lib.MediaTable.border["Blizzard Achievement Wood"]=[[Interface\AchievementFrame\UI-Achievement-WoodBorder]] |
lib.MediaTable.border["Blizzard Chat Bubble"]=[[Interface\Tooltips\ChatBubble-Backdrop]] |
lib.MediaTable.border["Blizzard Dialog"]=[[Interface\DialogFrame\UI-DialogBox-Border]] |
lib.MediaTable.border["Blizzard Dialog Gold"]=[[Interface\DialogFrame\UI-DialogBox-Gold-Border]] |
lib.MediaTable.border["Blizzard Party"]=[[Interface\CHARACTERFRAME\UI-Party-Border]] |
lib.MediaTable.border["Blizzard Tooltip"]=[[Interface\Tooltips\UI-Tooltip-Border]] |
lib.DefaultMedia.border="None" |
if not lib.MediaTable.font then lib.MediaTable.font={}end |
local SML_MT_font=lib.MediaTable.font |
if locale=="koKR"then |
LOCALE_MASK=lib.LOCALE_BIT_koKR |
SML_MT_font["êµµì ê¸ê¼´"]=[[Fonts\2002B.TTF]] |
SML_MT_font["기본 ê¸ê¼´"]=[[Fonts\2002.TTF]] |
SML_MT_font["ë°ë¯¸ì§ ê¸ê¼´"]=[[Fonts\K_Damage.TTF]] |
SML_MT_font["íì¤í¸ ê¸ê¼´"]=[[Fonts\K_Pagetext.TTF]] |
lib.DefaultMedia["font"]="기본 ê¸ê¼´" |
elseif locale=="zhCN"then |
LOCALE_MASK=lib.LOCALE_BIT_zhCN |
SML_MT_font["伤害æ°å"]=[[Fonts\ARKai_C.ttf]] |
SML_MT_font["é»è®¤"]=[[Fonts\ARKai_T.ttf]] |
SML_MT_font["è天"]=[[Fonts\ARHei.ttf]] |
lib.DefaultMedia["font"]="é»è®¤" |
elseif locale=="zhTW"then |
LOCALE_MASK=lib.LOCALE_BIT_zhTW |
SML_MT_font["æ示è¨æ¯"]=[[Fonts\bHEI00M.ttf]] |
SML_MT_font["è天"]=[[Fonts\bHEI01B.ttf]] |
SML_MT_font["å·å®³æ¸å"]=[[Fonts\bKAI00M.ttf]] |
SML_MT_font["é è¨"]=[[Fonts\bLEI00D.ttf]] |
lib.DefaultMedia["font"]="é è¨" |
elseif locale=="ruRU"then |
LOCALE_MASK=lib.LOCALE_BIT_ruRU |
SML_MT_font["2002"]=[[Fonts\2002.TTF]] |
SML_MT_font["2002 Bold"]=[[Fonts\2002B.TTF]] |
SML_MT_font["AR CrystalzcuheiGBK Demibold"]=[[Fonts\ARHei.TTF]] |
SML_MT_font["AR ZhongkaiGBK Medium (Combat)"]=[[Fonts\ARKai_C.TTF]] |
SML_MT_font["AR ZhongkaiGBK Medium"]=[[Fonts\ARKai_T.TTF]] |
SML_MT_font["Arial Narrow"]=[[Fonts\ARIALN.TTF]] |
SML_MT_font["Friz Quadrata TT"]=[[Fonts\FRIZQT___CYR.TTF]] |
SML_MT_font["MoK"]=[[Fonts\K_Pagetext.TTF]] |
SML_MT_font["Morpheus"]=[[Fonts\MORPHEUS_CYR.TTF]] |
SML_MT_font["Nimrod MT"]=[[Fonts\NIM_____.ttf]] |
SML_MT_font["Skurri"]=[[Fonts\SKURRI_CYR.TTF]] |
lib.DefaultMedia.font="Friz Quadrata TT" |
else |
LOCALE_MASK=lib.LOCALE_BIT_western |
locale_is_western=true |
SML_MT_font["2002"]=[[Fonts\2002.TTF]] |
SML_MT_font["2002 Bold"]=[[Fonts\2002B.TTF]] |
SML_MT_font["AR CrystalzcuheiGBK Demibold"]=[[Fonts\ARHei.TTF]] |
SML_MT_font["AR ZhongkaiGBK Medium (Combat)"]=[[Fonts\ARKai_C.TTF]] |
SML_MT_font["AR ZhongkaiGBK Medium"]=[[Fonts\ARKai_T.TTF]] |
SML_MT_font["Arial Narrow"]=[[Fonts\ARIALN.TTF]] |
SML_MT_font["Friz Quadrata TT"]=[[Fonts\FRIZQT__.TTF]] |
SML_MT_font["MoK"]=[[Fonts\K_Pagetext.TTF]] |
SML_MT_font["Morpheus"]=[[Fonts\MORPHEUS_CYR.TTF]] |
SML_MT_font["Nimrod MT"]=[[Fonts\NIM_____.ttf]] |
SML_MT_font["Skurri"]=[[Fonts\SKURRI_CYR.TTF]] |
lib.DefaultMedia.font="Friz Quadrata TT" |
end |
if not lib.MediaTable.statusbar then lib.MediaTable.statusbar={}end |
lib.MediaTable.statusbar["Blizzard"]=[[Interface\TargetingFrame\UI-StatusBar]] |
lib.MediaTable.statusbar["Blizzard Character Skills Bar"]=[[Interface\PaperDollInfoFrame\UI-Character-Skills-Bar]] |
lib.MediaTable.statusbar["Blizzard Raid Bar"]=[[Interface\RaidFrame\Raid-Bar-Hp-Fill]] |
lib.MediaTable.statusbar["Solid"]=[[Interface\Buttons\WHITE8X8]] |
lib.DefaultMedia.statusbar="Blizzard" |
if not lib.MediaTable.sound then lib.MediaTable.sound={}end |
lib.MediaTable.sound["None"]=RESTRICTED_FILE_ACCESS and 1 or[[Interface\Quiet.ogg]] |
lib.DefaultMedia.sound="None" |
local function rebuildMediaList(mediatype) |
local mtable=mediaTable[mediatype] |
if not mtable then return end |
if not mediaList[mediatype]then mediaList[mediatype]={}end |
local mlist=mediaList[mediatype] |
local i=0 |
for k in pairs(mtable)do |
i=i+1 |
mlist[i]=k |
end |
table_sort(mlist) |
end |
function lib:Register(mediatype,key,data,langmask) |
if type(mediatype)~="string"then |
error(MAJOR..":Register(mediatype, key, data, langmask) - mediatype must be string, got "..type(mediatype)) |
end |
if type(key)~="string"then |
error(MAJOR..":Register(mediatype, key, data, langmask) - key must be string, got "..type(key)) |
end |
mediatype=mediatype:lower() |
if mediatype==lib.MediaType.FONT and((langmask and band(langmask,LOCALE_MASK)==0)or not(langmask or locale_is_western))then |
return false |
end |
if type(data)=="string"and(mediatype==lib.MediaType.BACKGROUND or mediatype==lib.MediaType.BORDER or mediatype==lib.MediaType.STATUSBAR or mediatype==lib.MediaType.SOUND)then |
local path=data:lower() |
if RESTRICTED_FILE_ACCESS and not path:find("^interface")then |
return false |
end |
if mediatype==lib.MediaType.SOUND and not(path:find(".ogg",nil,true)or path:find(".mp3",nil,true))then |
return false |
end |
end |
if not mediaTable[mediatype]then mediaTable[mediatype]={}end |
local mtable=mediaTable[mediatype] |
if mtable[key]then return false end |
mtable[key]=data |
rebuildMediaList(mediatype) |
self.callbacks:Fire("LibSharedMedia_Registered",mediatype,key) |
return true |
end |
function lib:Fetch(mediatype,key,noDefault) |
local mtt=mediaTable[mediatype] |
local overridekey=overrideMedia[mediatype] |
local result=mtt and((overridekey and mtt[overridekey]or mtt[key])or(not noDefault and defaultMedia[mediatype]and mtt[defaultMedia[mediatype]]))or nil |
return result~=""and result or nil |
end |
function lib:IsValid(mediatype,key) |
return mediaTable[mediatype]and(not key or mediaTable[mediatype][key])and true or false |
end |
function lib:HashTable(mediatype) |
return mediaTable[mediatype] |
end |
function lib:List(mediatype) |
if not mediaTable[mediatype]then |
return nil |
end |
if not mediaList[mediatype]then |
rebuildMediaList(mediatype) |
end |
return mediaList[mediatype] |
end |
function lib:GetGlobal(mediatype) |
return overrideMedia[mediatype] |
end |
function lib:SetGlobal(mediatype,key) |
if not mediaTable[mediatype]then |
return false |
end |
overrideMedia[mediatype]=(key and mediaTable[mediatype][key])and key or nil |
self.callbacks:Fire("LibSharedMedia_SetGlobal",mediatype,overrideMedia[mediatype]) |
return true |
end |
function lib:GetDefault(mediatype) |
return defaultMedia[mediatype] |
end |
function lib:SetDefault(mediatype,key) |
if mediaTable[mediatype]and mediaTable[mediatype][key]and not defaultMedia[mediatype]then |
defaultMedia[mediatype]=key |
return true |
else |
return false |
end |
end |
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> |
<Script file="libs\LibStub.lua"/> |
<Script file="libs\CallbackHandler-1.0.lua"/> |
<Script file="libs\LibSharedMedia-3.0.lua"/> |
</Ui> |
## Interface: 90002 |
## Title: Cellular (Shadowlands) |
## Notes: Instant messenger for whispers |
## Author: TotalPackage, Shexyriar |
## Version: 9.0.2 |
## SavedVariables: CellularDB |
## SavedVariablesPerCharacter: CellularCharDB, Cellular_History |
## OptionalDeps: LibSharedMedia-3.0 |
## LoadManagers: AddonLoader |
## X-OriginalAuthor: TotalPackage |
## X-Category: Chat/Communication |
## X-LoadOn-Always: true |
embeds.xml |
core.lua |
local Cellular=CreateFrame("Frame","Cellular",UIParent,BackdropTemplateMixin and "BackdropTemplate") |
local a=Cellular |
local smed=LibStub("LibSharedMedia-3.0") |
local _G=getfenv(0) |
local format,gsub,strmatch,gmatch=format,gsub,strmatch,gmatch |
local cfeb,ChatFrame_GetMessageEventFilters=ChatFrame10EditBox or ChatFrame1EditBox,ChatFrame_GetMessageEventFilters |
local db,svar |
local you,attached,lastwindow,currenttab,eb |
local nwin=0 |
local base,tabs,usedtabs,recentw,taborder={},{},{},{},{} |
local l_p,l_rt,l_rp,l_x,l_y,r_p,r_rt,r_rp,r_x,r_y |
local MinimizeWindow,GetWindow,CloseWindow,ShowOptions |
local realmName=GetRealmName() |
a:SetScript("OnEvent",function(this,event,...) |
a[event](a,...) |
end) |
a:RegisterEvent("ADDON_LOADED") |
function a:ADDON_LOADED(a1) |
if a1~="Cellular"then return end |
a:UnregisterEvent("ADDON_LOADED") |
a.ADDON_LOADED=nil |
CellularDB=CellularDB or{} |
if CellularDB.char then |
CellularCharDB=CellularCharDB or(CellularDB.profiles and CellularDB.profiles.Default)or CellularDB |
db=CellularCharDB |
else |
db=(CellularDB.profiles and CellularDB.profiles.Default)or CellularDB |
end |
if db.dbinit~=2 then |
db.dbinit=2 |
for k,v in pairs({ |
width=340,height=160, |
pos={}, |
alpha=0.9, |
bg="Tooltip", |
bgcolor={0,0,0,1,}, |
border="Blizzard Tooltip", |
bordercolor={0.7,0.7,0.7,1,}, |
incolor={1,0,1,1,}, |
outcolor={0,1,1,1,}, |
busymessage="Sorry, I'm busy right now...I'll chat with you later.", |
history=true,enabletabs=false,char=false, |
maxwindows=8, |
fade=true, |
automin=false,autominalways=false, |
showname=true,showtime=true,showside=true, |
fontmsg="Arial Narrow",fonttitle="Arial Narrow",fontsize=12, |
})do |
db[k]=(db[k]~=nil and db[k])or v |
end |
end |
db.border=(type(db.border)=="string"and db.border)or(db.border and"Blizzard Tooltip")or"None" |
a:SetAlpha(db.alpha) |
Cellular_History=Cellular_History or{} |
svar=Cellular_History |
SlashCmdList.CELLULAR=ShowOptions |
SLASH_CELLULAR1,SLASH_CELLULAR2="/cellular","/cell" |
local panel=CreateFrame("Frame",BackdropTemplateMixin and "BackdropTemplate") |
panel.name="Cellular" |
panel:SetScript("OnShow",function(this) |
local t1=this:CreateFontString(nil,"ARTWORK","GameFontNormalLarge") |
t1:SetJustifyH("LEFT") |
t1:SetJustifyV("TOP") |
t1:SetPoint("TOPLEFT",16,-16) |
t1:SetText(this.name) |
local t2=this:CreateFontString(nil,"ARTWORK","GameFontHighlightSmall") |
t2:SetJustifyH("LEFT") |
t2:SetJustifyV("TOP") |
t2:SetHeight(43) |
t2:SetPoint("TOPLEFT",t1,"BOTTOMLEFT",0,-8) |
t2:SetPoint("RIGHT",this,"RIGHT",-32,0) |
t2:SetNonSpaceWrap(true) |
t2:SetFormattedText("Notes: %s\nAuthor: %s\nVersion: %s", |
GetAddOnMetadata("Cellular","Notes"), |
GetAddOnMetadata("Cellular","Author"), |
GetAddOnMetadata("Cellular","Version")) |
local b=CreateFrame("Button",nil,this,"UIPanelButtonTemplate") |
b:SetWidth(120) |
b:SetHeight(20) |
b:SetText("Options Menu") |
b:SetScript("OnClick",ShowOptions) |
b:SetPoint("TOPLEFT",t2,"BOTTOMLEFT",-2,-8) |
this:SetScript("OnShow",nil) |
end) |
InterfaceOptions_AddCategory(panel) |
local cevents={"CHAT_MSG_WHISPER","CHAT_MSG_WHISPER_INFORM","CHAT_MSG_AFK","CHAT_MSG_DND","CHAT_MSG_IGNORED",} |
if not db.nobn then |
tinsert(cevents,"CHAT_MSG_BN_WHISPER") |
tinsert(cevents,"CHAT_MSG_BN_WHISPER_INFORM") |
end |
for _,v in ipairs(cevents)do |
a:RegisterEvent(v) |
end |
you=UnitName("player") |
a.pratloaded=select(4,GetAddOnInfo("Prat-3.0")) |
CONFIGMODE_CALLBACKS=CONFIGMODE_CALLBACKS or{} |
CONFIGMODE_CALLBACKS.Cellular=function(action,mode) |
if action=="ON"then |
SendChatMessage("Hey self, entering cheap config mode.","WHISPER",nil,you) |
end |
end |
if not db.chatshow then |
local _G=getfenv(0) |
local function Unreg(frame) |
if type(frame)~="table"then return end |
for _,v in ipairs(cevents)do |
frame:UnregisterEvent(v) |
end |
end |
for i=1,NUM_CHAT_WINDOWS,1 do |
Unreg(_G["ChatFrame"..i]) |
end |
hooksecurefunc("ChatFrame_AddMessageGroup",Unreg) |
hooksecurefunc("ChatFrame_RegisterForMessages",Unreg) |
end |
end |
local function Filter(event,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14) |
local cfilter=ChatFrame_GetMessageEventFilters(event) |
if cfilter then |
for _,filterFunc in next,cfilter do |
local filter,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14=filterFunc(a,event,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14) |
if filter then |
return true |
elseif n1 and n2 then |
a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14=n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14 |
end |
end |
end |
if a7<1 or(a7>=1 and _G.CHAT_SHOW_ICONS~="0")then |
for tag in gmatch(a1,"%b{}")do |
local termlist=ICON_TAG_LIST[strlower(gsub(tag,"[{}]",""))] |
local icon=termlist and ICON_LIST[termlist] |
if icon then |
a1=gsub(a1,tag,icon.."0|t") |
end |
end |
end |
return a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14 |
end |
function a:CHAT_MSG_WHISPER(...) |
local a1,a2,_,_,_,a6,_,_,_,_,a11,a12=Filter("CHAT_MSG_WHISPER",...) |
if a2 and a6~="GM"then |
a:IncomingMessage(a2,a1,a6,nil,a11,a12) |
end |
end |
function a:CHAT_MSG_BN_WHISPER(...) |
local a1,a2,_,_,_,a6,_,_,_,_,a11,a12,a13,a14,a15=Filter("CHAT_MSG_BN_WHISPER",...) |
if a2 then |
a:IncomingMessage(a2,a1,a6,nil,a11,a12,a13) |
end |
end |
function a:CHAT_MSG_WHISPER_INFORM(...) |
local a1,a2=Filter("CHAT_MSG_WHISPER_INFORM",...) |
if a2 and(not GMChatFrame_IsGM or not GMChatFrame_IsGM(a2))then |
a:OutgoingMessage(a2,a1) |
end |
end |
function a:CHAT_MSG_BN_WHISPER_INFORM(...) |
local a1,a2,_,_,_,_,_,_,_,_,_,_,a13,a14,a15=Filter("CHAT_MSG_BN_WHISPER_INFORM",...) |
if a2 then |
a:OutgoingMessage(a2,a1,a13) |
end |
end |
function a:CHAT_MSG_AFK(a1,a2) |
a:IncomingMessage(a2,a2.." is AFK: "..a1,nil,2) |
end |
function a:CHAT_MSG_DND(a1,a2) |
a:IncomingMessage(a2,a2.." is DND: "..a1,nil,3) |
end |
function a:CHAT_MSG_IGNORED(_,a2) |
a:IncomingMessage(a2,a2.." is ignoring you.",nil,4) |
end |
local parstrings |
function a:CHAT_MSG_SYSTEM(text) |
if not taborder[1]or not text then return end |
if not parstrings then |
parstrings={ |
"|Hplayer:(.+)|h%[(.+)%]|h(.+)",ERR_FRIEND_OFFLINE_S, |
JOINED_PARTY,LEFT_PARTY,ERR_DECLINE_GROUP_S, |
ERR_RAID_MEMBER_ADDED_S,ERR_RAID_MEMBER_REMOVED_S, |
ERR_GUILD_JOIN_S,ERR_GUILD_DECLINE_S,ERR_GUILD_LEAVE_S, |
ERR_PETITION_DECLINED_S,ERR_PETITION_SIGNED_S, |
} |
for index,s in ipairs(parstrings)do |
parstrings[index]=gsub(s,"%%s","(.+)") |
end |
end |
for index,s in ipairs(parstrings)do |
local name=strmatch(text,s) |
if name then |
return a:IncomingMessage(name,text,nil,1) |
end |
end |
end |
function a:CHAT_MSG_TEXT_EMOTE(emote,sender) |
if taborder[1]and strfind(emote," you")then |
a:IncomingMessage(sender,emote,nil,1) |
end |
end |
local function UpdateTabOrder(id) |
if not db.enabletabs then return end |
currenttab=id or currenttab or 1 |
base[1].tab=currenttab |
local n=#taborder+0.4 |
local tabsize=(db.width-(2*n+48))/n |
local i=0 |
for _,tid in ipairs(taborder)do |
i=i+1 |
local t=tabs[tid] |
t:SetPoint("TOPLEFT",base[1],"TOPLEFT",((i-1)*tabsize)+(2*i)+8,-6) |
if tid==currenttab then |
if not t:GetParent().mini then |
t.mininew=0 |
t.text:SetText(t.name) |
t.msg:Show() |
end |
t:SetBackdropColor(0,0,0,0) |
t.text:SetTextColor(t.text.r or 1,t.text.g or 1,t.text.b or 1,1) |
i=i+0.4 |
else |
t.msg:Hide() |
t:SetBackdropColor(0.7,0.7,0.7,0.7) |
t.text:SetTextColor(0.8,0.8,0.8,0.8) |
end |
t:SetPoint("BOTTOMRIGHT",base[1],"TOPLEFT",(i*tabsize)+(2*i)+8,-20) |
end |
if#taborder<1 then |
CloseWindow(tabs[1]) |
end |
end |
local function RemoveTab(id,activeid) |
if not id then return end |
for index,tid in pairs(taborder)do |
if tid==id or id=="a"then |
local tab=tabs[tid] |
usedtabs[tab.name]=nil |
tab:Hide() |
tab.text.r,tab.text.g,tab.text.b=nil,nil,nil |
tremove(taborder,index) |
if IsControlKeyDown()then |
svar[tabs[(id=="a"and activeid)or tid].name]=nil |
end |
end |
end |
currenttab=(id==currenttab and taborder[1])or currenttab |
if attached==id and cfeb:IsShown()then |
ChatEdit_DeactivateChat(cfeb) |
end |
UpdateTabOrder() |
end |
local function ResetEditBox() |
if not attached then return end |
cfeb:ClearAllPoints() |
cfeb:SetParent(l_rt) |
cfeb:SetPoint(l_p,l_rt,l_rp,l_x,l_y) |
if r_p then cfeb:SetPoint(r_p,r_rt,r_rp,r_x,r_y)end |
attached=nil |
end |
local skipupdate |
local sw=_G.SLASH_SMART_WHISPER1.." " |
local function AttachEditBox(id,skiptext,skipset) |
local tab=tabs[id] |
if not tab:IsShown()then return end |
if not db.noattach then |
ChatEdit_ActivateChat(cfeb) |
cfeb.setText=1 |
cfeb.text=sw..tab.name.." " |
ChatEdit_UpdateHeader(cfeb) |
ChatEdit_ParseText(cfeb,0) |
if not attached then |
l_p,l_rt,l_rp,l_x,l_y=cfeb:GetPoint(1) |
r_p,r_rt,r_rp,r_x,r_y=cfeb:GetPoint(2) |
end |
cfeb:SetParent(tab:GetParent()) |
cfeb:ClearAllPoints() |
if db.showtop then |
cfeb:SetPoint("BOTTOMLEFT",tab:GetParent(),"TOPLEFT",0,-6) |
cfeb:SetPoint("BOTTOMRIGHT",tab:GetParent(),"TOPRIGHT",0,-6) |
else |
cfeb:SetPoint("TOPLEFT",tab:GetParent(),"BOTTOMLEFT",0,6) |
cfeb:SetPoint("TOPRIGHT",tab:GetParent(),"BOTTOMRIGHT",0,6) |
end |
attached=id |
cfeb:SetFocus() |
else |
if tab.name and tab.name~=""then |
local editBox=ChatEdit_ChooseBoxForSend() |
local lastTell,lastTellType=ChatEdit_GetLastTellTarget(); |
if lastTell then |
editBox:SetAttribute("chatType",lastTellType) |
editBox:SetAttribute("tellTarget",tab.name) |
ChatEdit_UpdateHeader(editBox) |
if editBox~=ChatEdit_GetActiveWindow()then |
ChatFrame_OpenChat("") |
end |
end |
end |
end |
end |
local function ToggleEditBox(id,hidediff) |
if not db.noattach and(attached==id or(attached and hidediff))then |
ChatEdit_DeactivateChat(cfeb) |
elseif not hidediff and id then |
AttachEditBox(id) |
end |
end |
GetWindow=function(name,isSpecial,showmore,battleTag) |
local id=usedtabs[name] |
if(not id or not tabs[id]or not tabs[id]:IsShown())and not isSpecial then |
local t |
for _,tab in ipairs(tabs)do |
if not tab:IsShown()then |
t=tab |
break |
end |
end |
t=t or a:CreateWindow() |
if t then |
t.name=name |
t.lastspecial=nil |
t.tag=nil |
t.msg:Clear() |
t.msg:ScrollToBottom() |
local history=svar[battleTag or name] |
if history then |
local n=#history |
local numlines=(showmore and 50)or 15 |
if n>numlines then |
t.msg:AddMessage("**See ..\\WTF \\Account \\<Account Name> \\<Server> \\<Character> \\SavedVariables \\Cellular.lua for more**",1,1,0) |
end |
for i=max(1,n-numlines),n,1 do |
t.msg:AddMessage(history[i],0.6,0.6,0.6) |
end |
if not a.memchecked and(not db.memcheck or db.memcheck+21600<time())then |
db.memcheck=time() |
UpdateAddOnMemoryUsage() |
local mem=GetAddOnMemoryUsage("Cellular") |
if mem and mem>490 then |
t.msg:AddMessage(format("History usage is high ( +%d KB ). Consider cleaning it.",mem-85),0.7,0.5,0.5) |
end |
end |
a.memchecked=true |
end |
id=t.id |
usedtabs[name]=id |
tinsert(taborder,id) |
t:GetParent():Show() |
t:Show() |
t.mininew=0 |
t.text:SetText(t.name) |
t.msg:Show() |
t:EnableMouse(db.enabletabs) |
UpdateTabOrder(currenttab or taborder[1]) |
if id and(db.autominalways or(db.automin and InCombatLockdown()))and(not db.enabletabs or#taborder==1)then |
MinimizeWindow(t:GetParent().Minimize) |
end |
end |
end |
return id |
end |
do |
local ChatEdit_SetLastTellTarget,GetTime=ChatEdit_SetLastTellTarget,GetTime |
local function HandleHistory(name,dname,text,battleTag) |
recentw[name]=true |
if not db.history then return end |
local t=svar[battleTag or name] |
if not t then |
svar[battleTag or name]={} |
t=svar[battleTag or name] |
end |
t[#t+1]=format("<%s>[%s] %s",date("%m-%d-%y %H:%M"),dname,text) |
if eb and eb:IsShown()and eb.name==name then |
eb.max=#t |
end |
end |
local function HandleWindow(name,special,text,battleTag) |
if not name then return end |
local id=GetWindow(name,special,nil,battleTag) |
if not id then |
if not special then |
print(format("|cff88ff88Cellular|r: Max windows reached - [%s] %s",name,text)) |
end |
return |
end |
lastwindow=id |
return tabs[id] |
end |
local function addmsg(fmsg,out,form,...) |
local c=(out and db.outcolor)or db.incolor |
fmsg:AddMessage(format(form,...),c[1],c[2],c[3],c[4]) |
end |
local lastTell=0 |
function a:IncomingMessage(name,text,status,special,cid,guid,isbn) |
local battleTag,presenceName,_,toonName |
name=gsub(name,"-"..realmName,"") |
if isbn then |
_,presenceName,battleTag,_,toonName=C_BattleNet.GetAccountInfoByID(isbn) |
end |
local f=HandleWindow(name,special,text,battleTag) |
if not f then return end |
local ctime=GetTime() |
if special then |
if special==1 then |
f.msg:AddMessage(format("[%s] %s",date("%H:%M:%S"),text),1,1,0) |
else |
if not f.lastspecial or ctime>f.lastspecial+90 or f.tag~=special then |
f.lastspecial=ctime |
f.tag=special |
f.msg:AddMessage(format("[%s] %s",date("%H:%M:%S"),text),1,0,0) |
end |
end |
return |
end |
status,cid=status or"",cid or"" |
if status~=""then |
status=((status=="GM"or status=="DEV")and" |TInterface\\ChatFrame\\UI-ChatIcon-Blizz.blp:0:2:0:-3|t")or format(" (%s)",status) |
end |
local tname=gsub(name,"-(.+)","") |
if isbn then |
if db.showname and db.showtime then |
addmsg(f.msg,nil,"|HBNplayer:%s:%s:%s:BN_WHISPER:%s|h[%s %s|h%s] %s",name,isbn,cid,name,gsub(date("%I:%M:%S"),"^0",""),tname,status,text) |
elseif db.showtime then |
addmsg(f.msg,nil,"|HBNplayer:%s:%s:%s:BN_WHISPER:%s|h[%s|h%s] %s",name,isbn,cid,name,gsub(date("%I:%M:%S"),"^0",""),status,text) |
elseif db.showname then |
addmsg(f.msg,nil,"|HBNplayer:%s:%s:%s:BN_WHISPER:%s|h[%s|h%s] %s",name,isbn,cid,name,tname,status,text) |
else |
addmsg(f.msg,nil,"|HBNplayer:%s:%s:%s:BN_WHISPER:%s|h[>|h%s] %s",name,isbn,cid,name,status,text) |
end |
else |
if db.showname and db.showtime then |
addmsg(f.msg,nil,"|Hplayer:%s:%s:WHISPER:%s|h[%s %s|h%s] %s",name,cid,strupper(name),gsub(date("%I:%M:%S"),"^0",""),tname,status,text) |
elseif db.showtime then |
addmsg(f.msg,nil,"|Hplayer:%s:%s:WHISPER:%s|h[%s|h%s] %s",name,cid,strupper(name),gsub(date("%I:%M:%S"),"^0",""),status,text) |
elseif db.showname then |
addmsg(f.msg,nil,"|Hplayer:%s:%s:WHISPER:%s|h[%s|h%s] %s",name,cid,strupper(name),tname,status,text) |
else |
addmsg(f.msg,nil,"|Hplayer:%s:%s:WHISPER:%s|h[>|h%s] %s",name,cid,strupper(name),status,text) |
end |
end |
local r,g,b |
if ChatTypeInfo.WHISPER and ChatTypeInfo.WHISPER.colorNameByClass and guid and guid~=""then |
local _,englishClass,_,_,_=GetPlayerInfoByGUID(guid) |
local cc=englishClass and(CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS)[englishClass] |
r,g,b=cc and cc.r or 1,cc and cc.g or 1,cc and cc.b or 1 |
f.text.r,f.text.g,f.text.b=r,g,b |
else |
f.text.r,f.text.g,f.text.b=nil,nil,nil |
end |
if not f.msg:IsVisible()then |
f.mininew=f.mininew+1 |
r,g,b=0.8,0,0 |
f.text:SetFormattedText("%s (%d)",f.name,f.mininew) |
end |
f.text:SetTextColor(r or 1,g or 1,b or 1,1) |
ChatEdit_SetLastTellTarget(name,isbn and"BN_WHISPER"or"WHISPER") |
HandleHistory(name,tname,text,battleTag) |
if ctime>lastTell+2 then |
if a.pratloaded and Prat.Addon:GetModule("Sounds",true)then |
a.PLAYERLINK=name |
Prat.Addon:GetModule("Sounds",true):Prat_PostAddMessage(nil,a,nil,"CHAT_MSG_WHISPER") |
elseif ChatSounds_InitConfig then |
ChatSounds_PlaySound(ChatSounds_Config[ChatSounds_Player].Incoming["WHISPER"]) |
elseif not ChatSoundsDB then |
end |
lastTell=ctime |
end |
end |
function a:OutgoingMessage(name,text,isbn) |
local battleTag,presenceName,_,toonName |
name=gsub(name,"-"..realmName,"") |
if isbn then |
_,presenceName,battleTag,_,toonName=C_BattleNet.GetAccountInfoByID(isbn) |
end |
local f=HandleWindow(name,nil,text,battleTag) |
if not f then return end |
if db.showname and db.showtime then |
addmsg(f.msg,true,"[%s %s] %s",gsub(date("%I:%M:%S"),"^0",""),you,text) |
elseif db.showtime then |
addmsg(f.msg,true,"[%s] %s",gsub(date("%I:%M:%S"),"^0",""),text) |
elseif db.showname then |
addmsg(f.msg,true,"[%s] %s",you,text) |
else |
addmsg(f.msg,true,"[<] %s",text) |
end |
HandleHistory(name,you,text,battleTag) |
if a.pratloaded and Prat.Addon:GetModule("Sounds",true)then |
a.PLAYERLINK=you |
Prat.Addon:GetModule("Sounds",true):Prat_PostAddMessage(nil,a,nil,"CHAT_MSG_WHISPER_INFORM") |
elseif ChatSounds_InitConfig then |
ChatSounds_PlaySound(ChatSounds_Config[ChatSounds_Player].Outgoing["WHISPER"]) |
end |
end |
end |
local buttons |
local function ApplyFont(t,font,fontsize,fontstyle) |
if fontstyle=="Shadow"then |
t:SetFont(smed:Fetch("font",font),fontsize) |
t:SetShadowColor(0,0,0,0.7) |
t:SetShadowOffset(1,-1) |
else |
t:SetFont(smed:Fetch("font",font),fontsize,fontstyle~="None"and fontstyle) |
t:SetShadowOffset(0,0) |
end |
end |
do |
local function Who(this) |
C_FriendList.SendWho(tabs[this:GetParent().tab].name) |
end |
local function Busy(this) |
local bm=db.busymessage |
if bm and bm~=""then |
SendChatMessage(bm,"WHISPER",nil,tabs[this:GetParent().tab].name) |
end |
end |
local function Social(this) |
if not IsShiftKeyDown()then return end |
local b,n=this.text,tabs[this:GetParent().tab].name |
if b==_G.CHAT_INVITE_SEND then |
InviteUnit(n) |
elseif b==_G.ADD_FRIEND then |
AddFriend(n) |
elseif b==_G.IGNORE_PLAYER then |
AddIgnore(n) |
end |
end |
local function Scroll(this) |
local f=tabs[this:GetParent().tab].msg |
f[this.text](f) |
end |
MinimizeWindow=function(this) |
local p=this:GetParent() |
local t=tabs[p.tab] |
if not p.mini then |
p.mini=1 |
p:SetHeight(28) |
for b,k in pairs(buttons)do |
if not k.dontmin then |
p[b]:Hide() |
end |
end |
p.resizer:Hide() |
p.mininew=0 |
t.msg:Hide() |
else |
p.mini=nil |
p:SetHeight(db.height) |
for b,k in pairs(buttons)do |
if db.showside or not k.side then |
p[b]:Show() |
end |
end |
p.resizer:Show() |
t.mininew=0 |
t.text:SetText(t.name) |
t.text:SetTextColor(t.text.r or 1,t.text.g or 1,t.text.b or 1,1) |
t.msg:Show() |
end |
if eb and eb:IsShown()then eb:Hide()end |
end |
CloseWindow=function(this) |
local p=this:GetParent() |
if p.mini then MinimizeWindow(p.Minimize)end |
if attached==p.tab then ChatEdit_DeactivateChat(cfeb)end |
if eb and eb:IsShown()then eb:Hide()end |
if db.enabletabs then |
for i=1,#taborder,1 do |
RemoveTab("a",p.tab) |
end |
currenttab=1 |
else |
RemoveTab(p.tab) |
end |
p:Hide() |
end |
local EButtonClick |
local function CreateEButton(texture,left,close) |
local f=CreateFrame("Button",nil,eb) |
f:SetWidth(16) |
f:SetHeight(16) |
f:SetNormalTexture(texture) |
f:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight") |
EButtonClick=EButtonClick or function(this) |
local p=this:GetParent() |
p.i=(this.back and max(p.i-1,1))or min(p.max,p.i+1) |
p:SetText(svar[p.name][p.i]) |
p:HighlightText() |
p:SetFocus() |
end |
f:SetScript("OnClick",(not close and EButtonClick)or function(this)this:GetParent():Hide()end) |
f:SetPoint("BOTTOMLEFT",left,"BOTTOMRIGHT",-1,0) |
return f |
end |
local function Copy(this) |
local p=this:GetParent() |
local t=tabs[p.tab] |
local h=svar[t.name] |
if not h or not h[1]then return end |
if not eb then |
eb=CreateFrame("EditBox","CellularEB",UIParent) |
ApplyFont(eb,db.fontmsg,db.fontsize,db.fontmsgstyle) |
eb:SetMaxLetters(600) |
eb.back=CreateEButton("Interface\\Buttons\\UI-SpellbookIcon-PrevPage-Up",eb) |
eb.forward=CreateEButton("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Up",eb.back) |
eb.close=CreateEButton("Interface\\Buttons\\UI-Panel-MinimizeButton-Up",eb.forward,true) |
eb.back.back=true |
eb:Hide() |
eb:SetHeight(16) |
eb:SetScript("OnEscapePressed",function(this)this:Hide()this:ClearFocus()end) |
eb:SetScript("OnEditFocusLost",function(this)this:Hide()end) |
end |
if eb:IsShown()and eb.name==t.name then |
eb:Hide() |
else |
eb.name=t.name |
eb.max=#h |
eb.i=eb.max |
eb:SetText(h[eb.i]) |
eb:ClearAllPoints() |
if db.showtop then |
eb:SetPoint("LEFT",p,"BOTTOMLEFT",-4,-5) |
eb:SetPoint("RIGHT",p,"BOTTOMRIGHT",-40,-5) |
else |
eb:SetPoint("LEFT",p,"TOPLEFT",-4,5) |
eb:SetPoint("RIGHT",p,"TOPRIGHT",-40,5) |
end |
eb:Show() |
eb:HighlightText() |
eb:SetFocus() |
end |
end |
buttons={ |
[_G.WHO]={p="TOPLEFT",x=6,y=-22,tt=1,path="Interface\\Icons\\INV_Misc_QuestionMark",func=Who,side=true,}, |
["\"I'm Busy!\""]={p="TOPLEFT",x=6,y=-42,tt=1,path="Interface\\Icons\\Spell_Holy_Silence",func=Busy,side=true,}, |
[_G.CHAT_INVITE_SEND]={p="TOPLEFT",x=6,y=-59,tt=2,path="Interface\\Icons\\Spell_Holy_PrayerofSpirit",func=Social,side=true,}, |
[_G.ADD_FRIEND]={p="TOPLEFT",x=6,y=-76,tt=2,path="Interface\\Icons\\Spell_ChargePositive",func=Social,side=true,}, |
[_G.IGNORE_PLAYER]={p="TOPLEFT",x=6,y=-95,tt=2,path="Interface\\Icons\\Spell_ChargeNegative",func=Social,side=true,}, |
[_G.CALENDAR_COPY_EVENT]={p="BOTTOMLEFT",x=6,y=6,tt=3,path="Interface\\Icons\\INV_Scroll_01",func=Copy,side=true,}, |
ScrollUp={p="BOTTOMRIGHT",x=-6,y=42,path="Interface\\ChatFrame\\UI-ChatIcon-ScrollUp-Up",func=Scroll,}, |
ScrollDown={p="BOTTOMRIGHT",x=-6,y=26,path="Interface\\ChatFrame\\UI-ChatIcon-ScrollDown-Up",func=Scroll,}, |
ScrollToBottom={p="BOTTOMRIGHT",x=-6,y=10,path="Interface\\ChatFrame\\UI-ChatIcon-ScrollEnd-Up",func=Scroll,}, |
[_G.CLOSE]={p="TOPRIGHT",x=-6,y=-6,tt=1,tpl="UIPanelButtonTemplate",func=CloseWindow,bt="x",dontmin=true,}, |
Minimize={p="TOPRIGHT",x=-22,y=-6,tt=1,tpl="UIPanelButtonTemplate",func=MinimizeWindow,bt="-",dontmin=true,}, |
} |
end |
local bdt={tileSize=16,edgeSize=16,insets={left=4,right=4,top=4,bottom=4,},} |
local bdt2={bgFile="Interface\\Tooltips\\UI-Tooltip-Background",tile=true,tileSize=16,} |
local function UpdateBaseVars(f) |
bdt.bgFile=smed:Fetch(db.bglist or"statusbar",db.bg) |
bdt.tile=(db.bg=="Tooltip") |
bdt.edgeFile=smed:Fetch("border",db.border) |
f:SetBackdrop(bdt) |
f:SetBackdropColor(unpack(db.bgcolor)) |
f:SetBackdropBorderColor(unpack(db.bordercolor)) |
if db.strata then f:SetFrameStrata(db.strata)end |
for b,k in pairs(buttons)do |
if k.side and db.showside then |
f[b]:Show() |
elseif k.side then |
f[b]:Hide() |
end |
end |
end |
local function UpdateTabVars(f) |
ApplyFont(f.text,db.fonttitle,12,db.fonttitlestyle) |
ApplyFont(f.msg,db.fontmsg,db.fontsize,db.fontmsgstyle) |
f.msg:SetFading(db.fade) |
f.msg:SetPoint("TOPLEFT",f:GetParent(),"TOPLEFT",db.showside and 24 or 8,-18) |
f.msg:SetPoint("BOTTOMRIGHT",f:GetParent(),"BOTTOMRIGHT",-20,8) |
end |
local function UpdateSizes(reset) |
if reset then |
db.width,db.height=340,160 |
end |
for _,f in pairs(base)do |
f:SetWidth(db.width) |
f:SetHeight(db.height) |
end |
end |
local function UpdatePosition(this,reset) |
db.pos[this.id]=db.pos[this.id]or{} |
local t=db.pos[this.id] |
if reset then |
this:ClearAllPoints() |
this:SetPoint("TOPLEFT",UIParent,"CENTER",(this.id-1)*20+100,-(this.id-1)*20) |
t.p,t.rp,t.x,t.y="TOPLEFT","BOTTOMLEFT",this:GetLeft(),this:GetTop() |
elseif(this:GetTop()-db.height/2)>(GetScreenHeight()/2)then |
t.p,t.rp,t.x,t.y="TOPLEFT","BOTTOMLEFT",this:GetLeft(),this:GetTop() |
else |
t.p,t.rp,t.x,t.y="BOTTOMLEFT","BOTTOMLEFT",this:GetLeft(),this:GetBottom() |
end |
this:ClearAllPoints() |
this:SetPoint(t.p,UIParent,t.rp,t.x,t.y) |
end |
do |
local gtt=GameTooltip |
local function BOnEnter(this) |
gtt:SetOwner(this,"ANCHOR_BOTTOMLEFT") |
gtt:SetText(this.text,1,1,1) |
if this.tt then |
if this.tt==2 then |
gtt:AddLine(" Shift-click to execute",0,1,0) |
elseif not db.history and this.tt==3 then |
gtt:AddLine(" History must be enabled",0,1,0) |
end |
end |
gtt:Show() |
end |
local function GttHide()gtt:Hide()end |
local function BDown(this)this:SetAlpha(0.3)end |
local function BUp(this)this:SetAlpha(0.6)end |
local function ResizeStart(this) |
if not IsShiftKeyDown()then |
if not a.shiftsaid2 then |
print("|cff00ff00Cellular|r: Hold shift and drag to resize.") |
a.shiftsaid2=true |
end |
return |
end |
this:GetParent():StartSizing("BOTTOMRIGHT") |
end |
local function ResizeEnd(this) |
local p=this:GetParent() |
p:StopMovingOrSizing() |
db.height,db.width=floor(p:GetHeight()+0.5),floor(p:GetWidth()+0.5) |
UpdateSizes() |
UpdateTabOrder() |
UpdatePosition(p) |
end |
local function DragStart(this) |
if not IsShiftKeyDown()then |
if not a.shiftsaid then |
print("|cff00ff00Cellular|r: Hold shift and drag to move.") |
a.shiftsaid=true |
end |
return |
end |
this=this.msg and this:GetParent()or this |
this:StartMoving() |
end |
local function DragStop(this) |
this=this.msg and this:GetParent()or this |
this:StopMovingOrSizing() |
UpdatePosition(this) |
end |
local function Wheel(this,a1) |
if not a1 then return end |
local t=tabs[this.tab].msg |
if a1>0 then |
t:ScrollUp() |
t:ScrollUp() |
else |
t:ScrollDown() |
t:ScrollDown() |
end |
end |
local function MainClick(this,a1) |
if a1=="RightButton"then |
ShowOptions() |
else |
ToggleEditBox(this.tab) |
end |
end |
local function TabOnClick(this,a1) |
if a1=="LeftButton"then |
local id=this.id |
ToggleEditBox(id,currenttab~=id) |
if currenttab~=id then |
UpdateTabOrder(id) |
end |
elseif a1=="RightButton"then |
ShowOptions(nil,this.id) |
elseif a1=="MiddleButton"then |
RemoveTab(this.id) |
end |
end |
local function TabOnEnter(this) |
gtt:SetOwner(this,"ANCHOR_TOPLEFT") |
gtt:SetText(this.text:GetText(),1,1,1) |
gtt:Show() |
end |
function a:CreateBase(id) |
if base[id]then return base[id]end |
local f=CreateFrame("Button","CellularWindow"..id,a,BackdropTemplateMixin and "BackdropTemplate") |
f:SetWidth(db.width) |
f:SetHeight(db.height) |
local pos=db.pos[id] |
if pos then |
f:SetPoint(pos.p or"TOPLEFT",UIParent,pos.rp or"TOPLEFT",pos.x,pos.y) |
else |
f:SetPoint("TOPLEFT",UIParent,"CENTER",(id-1)*20+100,-(id-1)*20) |
end |
f.id=id |
f:SetMovable(true) |
f:SetResizable(true) |
f:EnableMouseWheel(true) |
f:RegisterForClicks("LeftButtonUp","RightButtonUp") |
f:RegisterForDrag("LeftButton") |
f:SetScript("OnDragStart",DragStart) |
f:SetScript("OnDragStop",DragStop) |
f:SetScript("OnClick",MainClick) |
f:SetScript("OnMouseWheel",Wheel) |
f:SetClampedToScreen(true) |
f:SetClampRectInsets(10,-10,-10,10) |
f:SetMinResize(120,80) |
local resize=CreateFrame("Button",nil,f,"UIPanelButtonGrayTemplate") |
resize:SetWidth(8) |
resize:SetHeight(8) |
resize:SetPoint("BOTTOMRIGHT",f,"BOTTOMRIGHT",-4,4) |
resize:SetScript("OnMouseDown",ResizeStart) |
resize:SetScript("OnMouseUp",ResizeEnd) |
if ChatFrame1ResizeButton then |
resize:SetNormalTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Up") |
resize:SetHighlightTexture("Interface\\ChatFrame\\UI-ChatIM-SizeGrabber-Highlight") |
resize:SetWidth(14) |
resize:SetHeight(14) |
end |
f.resizer=resize |
for bn,t in pairs(buttons)do |
local b=CreateFrame("Button",nil,f,t.tpl) |
b:SetWidth(16) |
b:SetHeight(16) |
b.text=bn |
b:SetPoint(t.p,f,t.p,t.x,t.y) |
if t.path then |
b:SetNormalTexture(t.path) |
b:SetHighlightTexture("Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight") |
end |
b:SetScript("OnMouseDown",BDown) |
b:SetScript("OnMouseUp",BUp) |
b:SetScript("OnClick",t.func) |
if t.tt then |
b:SetScript("OnEnter",BOnEnter) |
b:SetScript("OnLeave",GttHide) |
b.tt=t.tt |
end |
b:SetText(t.bt) |
b:SetAlpha(0.6) |
f[bn]=b |
end |
UpdateBaseVars(f) |
UpdatePosition(f) |
base[id]=f |
return f |
end |
function a:CreateTab(id,parent) |
if tabs[id]then return tabs[id]end |
local t=CreateFrame("Button",nil,parent,BackdropTemplateMixin and "BackdropTemplate") |
t:SetPoint("TOPLEFT",parent,"TOPLEFT",8,-6) |
t:SetPoint("BOTTOMRIGHT",parent,"TOPRIGHT",-8,-20) |
t:RegisterForClicks("LeftButtonUp","RightButtonUp","MiddleButtonUp") |
t:RegisterForDrag("LeftButton") |
t:SetScript("OnClick",TabOnClick) |
t:SetScript("OnEnter",TabOnEnter) |
t:SetScript("OnLeave",GttHide) |
t:SetScript("OnDragStart",DragStart) |
t:SetScript("OnDragStop",DragStop) |
t:SetBackdrop(bdt2) |
t:SetBackdropColor(0,0,0,0) |
t.id=id |
t.text=t:CreateFontString(nil,"ARTWORK") |
t.text:SetJustifyH("LEFT") |
t.text:SetJustifyV("TOP") |
t.text:SetAllPoints(t) |
local m=CreateFrame("ScrollingMessageFrame",nil,t) |
m:SetHyperlinksEnabled(true) |
m:UnregisterAllEvents() |
m:SetJustifyH("LEFT") |
m:SetTimeVisible(120) |
m:SetMaxLines(100) |
m:SetScript("OnHyperlinkClick",ChatFrame_OnHyperlinkShow) |
m:SetScript("OnHyperlinkEnter",ChatFrame1:GetScript("OnHyperlinkEnter")) |
m:SetScript("OnHyperlinkLeave",GttHide) |
m:Hide() |
t.msg=m |
UpdateTabVars(t) |
tabs[id]=t |
return t |
end |
function a:CreateWindow() |
if nwin>=db.maxwindows then return end |
nwin=nwin+1 |
if nwin==1 then |
a:RegisterEvent("CHAT_MSG_SYSTEM") |
a:RegisterEvent("CHAT_MSG_TEXT_EMOTE") |
hooksecurefunc("ChatFrame_ReplyTell",function(chatframe) |
local lastTell=ChatEdit_GetLastTellTarget() |
if not lastTell or lastTell==""then return end |
local id=GetWindow(lastTell) |
if id then |
AttachEditBox(id) |
UpdateTabOrder(id) |
end |
end) |
hooksecurefunc("ChatEdit_DeactivateChat",ResetEditBox) |
end |
if not db.enabletabs or(db.enabletabs and nwin==1)then |
local f=a:CreateBase(nwin) |
f.tab=nwin |
return a:CreateTab(nwin,f) |
else |
return a:CreateTab(nwin,base[1]) |
end |
end |
end |
local CellularDD |
local info,list={},{} |
local offsetvalue,offsetcount,lastb,showid |
ShowOptions=function(a1,id) |
showid=type(id)=="number"and id |
if not CellularDD then |
CellularDD=CreateFrame("Frame","CellularDD",Cellular,BackdropTemplateMixin and "BackdropTemplate") |
CellularDD.displayMode="MENU" |
hooksecurefunc("ToggleDropDownMenu",function(...)lastb=select(8,...)end) |
local function UpdateSettings() |
Cellular:SetAlpha(db.alpha) |
for _,f in pairs(base)do |
UpdateBaseVars(f) |
end |
for _,t in pairs(tabs)do |
UpdateTabVars(t) |
end |
end |
local function HideCheck(b) |
if b and b.GetName and _G[b:GetName().."Check"]then |
_G[b:GetName().."Check"]:Hide() |
end |
end |
local function CloseMenu(b) |
if not b or not b:GetParent()then return end |
CloseDropDownMenus(b:GetParent():GetID()) |
end |
local function RefreshMenu(b) |
local tb=_G[gsub(lastb:GetName(),"ExpandArrow","")] |
CloseMenu(b) |
ToggleDropDownMenu(b:GetParent():GetID(),tb.value,nil,nil,nil,nil,tb.menuList,tb) |
end |
local function Exec(b,k,value) |
HideCheck(b) |
if(k=="less"or k=="more")and lastb then |
local off=(k=="less"and-8)or 8 |
if offsetvalue==value then |
offsetcount=offsetcount+off |
else |
offsetvalue,offsetcount=value,off |
end |
RefreshMenu(b) |
elseif k=="showtab"then |
CloseMenu(b) |
ToggleEditBox(value,currenttab~=value) |
if currenttab~=value then |
UpdateTabOrder(value) |
end |
elseif k=="removetab"then |
CloseMenu(b) |
RemoveTab(value) |
elseif k=="showoptions"then |
CloseMenu(b) |
ShowOptions() |
elseif k=="resetsizes"then |
UpdateSizes(true) |
for id,f in pairs(base)do |
UpdatePosition(f,true) |
end |
elseif k=="movehelp"then |
print("|cff00ff00Cellular|r: Hold shift and drag empty space to move or bottom-right corner to resize windows.") |
elseif k=="busymessage"then |
StaticPopupDialogs["CellularBusy"]=StaticPopupDialogs["CellularBusy"]or{ |
text="Set your busy message.", |
button1=ACCEPT,button2=CANCEL, |
hasEditBox=1,maxLetters=60,editBoxWidth=350, |
OnAccept=function(this) |
db.busymessage=this.editBox:GetText()or"" |
end, |
EditBoxOnEnterPressed=function(this) |
db.busymessage=this:GetParent().editBox:GetText()or"" |
this:GetParent():Hide() |
end, |
EditBoxOnEscapePressed=function(this) |
this:GetParent():Hide() |
end, |
OnShow=function(this) |
this.editBox:SetText(db.busymessage or"") |
this.editBox:SetFocus() |
end, |
OnHide=function(this) |
this.editBox:SetText("") |
end, |
timeout=0,exclusive=1,whileDead=1,hideOnEscape=1, |
} |
StaticPopup_Show("CellularBusy") |
elseif k=="clearall"and IsShiftKeyDown()then |
for name in pairs(svar)do |
svar[name]=nil |
end |
print("|cff00ff00Cellular|r: History cleared.") |
elseif k=="clearold"and IsShiftKeyDown()then |
local cdays=tonumber(date("%y"))*365.25+tonumber(date("%m"))*30.4+tonumber(date("%d")) |
local cleared=0 |
for name,t in pairs(svar)do |
while true do |
if#t<1 then |
svar[name]=nil |
break |
end |
local m,d,y=strmatch(t[1],"<(%d+)-(%d+)-(%d+) ") |
if m and d and y then |
local days=tonumber(y)*365.25+tonumber(m)*30.4+tonumber(d) |
if days+42<cdays then |
cleared=cleared+1 |
tremove(t,1) |
else |
break |
end |
else |
break |
end |
end |
end |
print("|cff00ff00Cellular|r: "..cleared.." history entries removed.") |
end |
end |
local function Set(b,k) |
if not k then return end |
db[k]=not db[k] |
if k=="enabletabs"then |
if nwin<1 then return end |
local v=db.enabletabs |
for i,tab in pairs(tabs)do |
local p=base[(v and 1)or i]or a:CreateBase((v and 1)or i) |
tab:GetParent():Hide() |
tab:SetParent(p) |
tab:EnableMouse(db.enabletabs) |
tab.msg:SetPoint("TOPLEFT",p,"TOPLEFT",db.showside and 24 or 8,-18) |
tab.msg:SetPoint("BOTTOMRIGHT",p,"BOTTOMRIGHT",-20,8) |
if not v then |
if not tab:GetParent().mini then |
tab.mininew=0 |
tab.text:SetText(tab.name) |
tab.msg:Show() |
end |
tab:ClearAllPoints() |
tab:SetPoint("TOPLEFT",p,"TOPLEFT",8,-6) |
tab:SetPoint("BOTTOMRIGHT",p,"TOPRIGHT",-8,-20) |
tab:SetBackdropColor(0,0,0,0) |
tab.text:SetTextColor(tab.text.r or 1,tab.text.g or 1,tab.text.b or 1,1) |
p.tab=tab.id |
end |
tab:GetParent():Hide() |
end |
for _,id in pairs(usedtabs)do |
tabs[id]:GetParent():Show() |
tabs[id]:Show() |
end |
UpdateTabOrder(lastwindow or taborder[1]) |
ChatEdit_DeactivateChat(cfeb) |
elseif k=="char"or k=="chatshow"or k=="nobn"then |
print("|cff00ff00Cellular|r: This setting requires a reload and will effect all characters.") |
else |
UpdateSettings() |
end |
end |
local function SetSelect(b,a1) |
HideCheck(b) |
if a1=="show"or a1=="recent"then |
GetWindow(b.value,nil,true) |
elseif a1=="clear"then |
if IsShiftKeyDown()then |
svar[b.value]=nil |
RefreshMenu(b) |
end |
else |
db[a1]=tonumber(b.value)or b.value |
local level,num=strmatch(b:GetName(),"DropDownList(%d+)Button(%d+)") |
level,num=tonumber(level)or 0,tonumber(num)or 0 |
for i=1,UIDROPDOWNMENU_MAXBUTTONS,1 do |
local b=_G["DropDownList"..level.."Button"..i.."Check"] |
if b then |
b[i==num and"Show"or"Hide"](b) |
end |
end |
UpdateSettings() |
end |
end |
local function SetColor(a1) |
local dbc=db[UIDROPDOWNMENU_MENU_VALUE] |
if not dbc then return end |
if a1 then |
local pv=ColorPickerFrame.previousValues |
dbc[1],dbc[2],dbc[3],dbc[4]=pv.r,pv.g,pv.b,1-pv.opacity |
else |
dbc[1],dbc[2],dbc[3]=ColorPickerFrame:GetColorRGB() |
dbc[4]=1-OpacitySliderFrame:GetValue() |
end |
UpdateSettings() |
end |
local function AddButton(lvl,text,keepshown) |
info.text=text |
info.keepShownOnClick=keepshown |
UIDropDownMenu_AddButton(info,lvl) |
wipe(info) |
end |
local function AddToggle(lvl,text,value) |
info.arg1=value |
info.func=Set |
info.checked=db[value] |
info.isNotRadio=true |
AddButton(lvl,text,1) |
end |
local function AddExecute(lvl,text,arg1,arg2) |
info.arg1=arg1 |
info.arg2=arg2 |
info.func=Exec |
info.notCheckable=1 |
AddButton(lvl,text,1) |
end |
local function AddColor(lvl,text,value) |
local dbc=db[value] |
if not dbc then return end |
info.hasColorSwatch=true |
info.hasOpacity=1 |
info.r,info.g,info.b,info.opacity=dbc[1],dbc[2],dbc[3],1-(dbc[4]or 1) |
info.swatchFunc,info.opacityFunc,info.cancelFunc=SetColor,SetColor,SetColor |
info.value=value |
info.notCheckable=1 |
info.func=UIDropDownMenuButton_OpenColorPicker |
AddButton(lvl,text,nil) |
end |
local function AddList(lvl,text,value) |
info.value=value |
info.hasArrow=true |
info.func=HideCheck |
info.notCheckable=1 |
AddButton(lvl,text,1) |
end |
local function AddSelect(lvl,text,arg1,value) |
info.arg1=arg1 |
info.func=SetSelect |
info.value=value |
if tonumber(value)and tonumber(db[arg1]or"blah")then |
if floor(100*tonumber(value))==floor(100*tonumber(db[arg1]))then |
info.checked=true |
end |
else |
info.checked=(db[arg1]==value) |
end |
AddButton(lvl,text,1) |
end |
local function AddFakeSlider(lvl,value,minv,maxv,step,tbl) |
local cvalue=0 |
local dbv=db[value] |
if type(dbv)=="string"and tbl then |
for i,v in ipairs(tbl)do |
if dbv==v then |
cvalue=i |
break |
end |
end |
else |
cvalue=dbv or floor((maxv-minv)/2) |
end |
local adj=(offsetvalue==value and offsetcount)or 0 |
local starti=max(minv,cvalue-(7-adj)*step) |
local endi=min(maxv,cvalue+(8+adj)*step) |
if starti==minv then |
endi=min(maxv,starti+16*step) |
elseif endi==maxv then |
starti=max(minv,endi-16*step) |
end |
if starti>minv then |
AddExecute(lvl,"--","less",value) |
end |
if tbl then |
for i=starti,endi,step do |
AddSelect(lvl,tbl[i],value,tbl[i]) |
end |
else |
local fstring=(step>=1 and"%d")or(step>=0.1 and"%.1f")or"%.2f" |
for i=starti,endi,step do |
AddSelect(lvl,format(fstring,i),value,i) |
end |
end |
if endi<maxv then |
AddExecute(lvl,"++","more",value) |
end |
end |
CellularDD.initialize=function(self,lvl) |
if lvl==1 then |
if showid then |
AddExecute(lvl,"Show Message (or left-click)","showtab",showid) |
AddExecute(lvl,"Close Tab (or middle-click)","removetab",showid) |
info.isTitle=true |
AddButton(lvl," ") |
AddExecute(lvl,"Options","showoptions") |
else |
info.isTitle=true |
info.notCheckable=1 |
AddButton(lvl,"|cff5555ffCellular|r") |
AddList(lvl,"Frame","frame") |
AddList(lvl,"Text","text") |
AddList(lvl,"Behavior","behave") |
AddList(lvl,"History","history") |
end |
elseif lvl==2 then |
local sub=UIDROPDOWNMENU_MENU_VALUE |
if sub=="frame"then |
AddList(lvl,"Texture Group","bglist") |
AddList(lvl,"Background Texture","bg") |
AddColor(lvl,"Background Color","bgcolor") |
AddList(lvl,"Border","border") |
AddColor(lvl,"Border Color","bordercolor") |
AddToggle(lvl,"Show Side Buttons","showside") |
AddList(lvl,"Frame Opacity","alpha") |
AddList(lvl,"Frame Strata","strata") |
AddExecute(lvl,"Reset Size and Position","resetsizes") |
AddExecute(lvl,"How to Move/Resize","movehelp") |
elseif sub=="text"then |
AddToggle(lvl,"Show Name","showname") |
AddToggle(lvl,"Show Timestamp","showtime") |
AddToggle(lvl,"Fade Old Messages","fade") |
AddList(lvl,"Title Font","fonttitle") |
AddList(lvl,"Title Style","fonttitlestyle") |
AddList(lvl,"Message Font","fontmsg") |
AddList(lvl,"Message Style","fontmsgstyle") |
AddList(lvl,"Message Font Size","fontsize") |
AddColor(lvl,"Incoming Font Color","incolor") |
AddColor(lvl,"Outgoing Font Color","outcolor") |
elseif sub=="behave"then |
AddToggle(lvl,"Use Tabs","enabletabs") |
AddToggle(lvl,"No battle.net","nobn") |
AddToggle(lvl,"Combat Auto-Minimize","automin") |
AddToggle(lvl,"Always Auto-Minimize","autominalways") |
AddToggle(lvl,"Editbox Top Anchor","showtop") |
AddToggle(lvl,"Disable EditBox Move","noattach") |
AddToggle(lvl,"Disable Block to Default","chatshow") |
AddList(lvl,"Maximum Windows/Tabs","maxwindows") |
AddExecute(lvl,"Set Busy Message","busymessage") |
AddToggle(lvl,"Save Settings Per Character","char") |
elseif sub=="history"then |
AddToggle(lvl,"Enable History","history") |
AddList(lvl,"Show Recent","recent") |
AddList(lvl,"Show Entry","show") |
AddList(lvl,"Clear Entry (hold shift)","clear") |
AddExecute(lvl,"Clear +6 Weeks (hold shift)","clearold") |
AddExecute(lvl,"Clear All (hold shift)","clearall") |
end |
elseif lvl==3 then |
local sub=UIDROPDOWNMENU_MENU_VALUE |
if sub=="bglist"then |
AddSelect(lvl,"background",sub,"background") |
AddSelect(lvl,"statusbar",sub,"statusbar") |
elseif sub=="bg"then |
local t=smed:List(db.bglist or"statusbar") |
AddFakeSlider(lvl,sub,1,#t,1,t) |
elseif sub=="fonttitle"or sub=="fontmsg"then |
local t=smed:List("font") |
AddFakeSlider(lvl,sub,1,#t,1,t) |
elseif sub=="border"then |
local t=smed:List("border") |
AddFakeSlider(lvl,sub,1,#t,1,t) |
elseif sub=="fontsize"then |
AddFakeSlider(lvl,sub,4,30,1) |
elseif sub=="fonttitlestyle"or sub=="fontmsgstyle"then |
AddSelect(lvl,"None",sub,"None") |
AddSelect(lvl,"Shadow",sub,"Shadow") |
AddSelect(lvl,"Outline",sub,"OUTLINE") |
AddSelect(lvl,"Thick Outline",sub,"THICKOUTLINE") |
AddSelect(lvl,"Monochrome",sub,"MONOCHROME") |
elseif sub=="alpha"then |
AddFakeSlider(lvl,sub,0,1,0.1) |
elseif sub=="strata"then |
AddSelect(lvl,"BACKGROUND",sub,"BACKGROUND") |
AddSelect(lvl,"LOW",sub,"LOW") |
AddSelect(lvl,"MEDIUM",sub,"MEDIUM") |
AddSelect(lvl,"HIGH",sub,"HIGH") |
AddSelect(lvl,"DIALOG",sub,"DIALOG") |
elseif sub=="maxwindows"then |
AddFakeSlider(lvl,sub,4,20,1) |
elseif sub=="recent"or sub=="show"or sub=="clear"then |
wipe(list) |
for name in pairs(sub=="recent"and recentw or svar)do |
tinsert(list,name) |
end |
table.sort(list) |
AddFakeSlider(lvl,sub,1,#list,1,list) |
end |
end |
end |
end |
ToggleDropDownMenu(1,nil,CellularDD,"cursor") |
end |