diff --git a/Elements/armor.lua b/Elements/armor.lua
new file mode 100644
index 0000000..b113908
--- /dev/null
+++ b/Elements/armor.lua
@@ -0,0 +1,161 @@
+--[[ SLDataText Module: Armor ]]
+--[[ Author: Taffu RevDate: 07/13/2012 Version: 5.0.0 ]]
+
+-- Added guild fund repair
+
+local SLDT, MODNAME = SLDataText, "Armor"
+if ( SLDT ) then SLDT.Armor = CreateFrame("Frame") end
+local L = SLDT.Locale
+local db, frame, text, tool
+
+local durMin, durCol
+local function convertMoney(moolah, display)
+ local g, s, c = abs(moolah/10000), abs(mod(moolah/100, 100)), abs(mod(moolah, 100))
+ local cash
+ if ( display ) then -- True = Long display
+ if ( g < 1 ) then g = "" else g = string.format("%d|cffffd700g|r ", g) end
+ if ( s < 1 ) then s = "" else s = string.format("%d|cffc7c7cfs|r ", s) end
+ c = string.format("%d|cffeda55fc|r", c)
+ cash = string.format("%s%s%s", g, s, c)
+ else
+ cash = string.format("%.1f|cffffd700g|r", g)
+ end
+ return cash
+end
+
+local function SetupToolTip()
+ tool:SetScript("OnEnter", function(this)
+ GameTooltip:SetOwner(this, db.aF)
+ GameTooltip:AddLine("|cffffffff"..L["Armor"].."|r")
+ local durFull = true
+ for slot, slotName in gmatch("1HEAD3SHOULDER5CHEST6WAIST7LEGS8FEET9WRIST10HANDS16MAINHAND17SECONDARYHAND18RANGED","(%d+)([^%d]+)") do
+ local durCur, durMax = GetInventoryItemDurability(slot)
+ local slotName = _G[slotName.."SLOT"]
+ if ( durCur ~= durMax ) then
+ GameTooltip:AddDoubleLine(slotName, string.format("%.0f%%", durCur ~= 0 and durCur*(100/durMax) or 0), 1,1,0,1,1,1)
+ if ( durFull ) then durFull = false end
+ end
+ end
+ if ( durFull ) then
+ GameTooltip:AddDoubleLine(L["All Items"], "100%", 1,1,0,1,1,1)
+ end
+ GameTooltip:AddLine(" ")
+ GameTooltip:AddDoubleLine(L["Auto Repair"], string.format("%s", db.autorepair and L["On"] or L["Off"]), 1,1,0,1,1,1)
+ GameTooltip:Show()
+ end)
+ tool:SetScript("OnLeave", function(this) if ( GameTooltip:IsShown() ) then GameTooltip:Hide() end end)
+end
+
+function SLDT.Armor:Enable()
+ if ( db.enabled ) then
+ SLDT:UpdateBaseText(self, db)
+ self:RegisterEvent("UPDATE_INVENTORY_DURABILITY")
+ self:RegisterEvent("MERCHANT_SHOW")
+ self:SetScript("OnEvent", function(self, event)
+ if ( event == "MERCHANT_SHOW" and db.autorepair and CanMerchantRepair() ) then
+ local repCost, totCost = GetRepairAllCost(), 0
+ if ( repCost > 0 ) then
+ if ( CanGuildBankRepair() and db.usegfunds ) then
+ RepairAllItems(1)
+ print(string.format("|cff6698FFSLDataText|r: %s %s.", L["GFAutoRepairLine"], convertMoney(repCost, true)))
+ else
+ RepairAllItems()
+ print(string.format("|cff6698FFSLDataText|r: %s %s.", L["AutoRepairLine"], convertMoney(repCost, true)))
+ end
+ end
+ else self:Refresh() end
+ end)
+ end
+ self:Refresh()
+end
+
+function SLDT.Armor:Disable()
+ if ( not db.enabled ) then
+ self:UnregisterEvent("UPDATE_INVENTORY_DURABILITY")
+ self:UnregisterEvent("MERCHANT_SHOW")
+ end
+ self:Refresh()
+end
+
+local tags = {
+ ["Dur"] = function()
+ durMin, durCol = 100, "ffffff"
+ for i = 1, 18 do
+ local durCur, durMax = GetInventoryItemDurability(i)
+ if ( durCur ~= durMax ) then durMin = min(durMin, durCur*(100/durMax)) end
+ end
+ if ( durMin < 60 ) then durCol = "ffff00" elseif ( durMin < 30 ) then durCol = "ff0000" end
+ return string.format("|cff%s%.0f|r|cff%s", durCol, durMin, SLDT.db.profile.cCol and SLDT.classColor or "ffffff")
+ end,
+}
+
+function SLDT.Armor:Refresh()
+ if ( db.enabled or SLDataText.db.profile.configMode ) then
+ if ( not self.firstRun ) then self.firstRun = true; SLDT:UpdateBaseText(self, db) end
+
+ local str = db.textDisplay
+ str = string.gsub(str, "%[(%w+)%]", function(w) return tags[w]() end)
+ text:SetFormattedText("|cff%s%s|r", SLDT.db.profile.cCol and SLDT.classColor or "ffffff", str)
+
+ SLDT:UpdateBaseFrame(self, db)
+ else
+ if ( frame:IsShown() and not SLDataText.db.profile.configMode ) then frame:Hide() end
+ end
+end
+
+SLDT.Armor.optsTbl = {
+ [1] = { [1] = "toggle", [2] = L["Enabled"], [3] = "enabled" },
+ [2] = { [1] = "toggle", [2] = L["Global Font"], [3] = "gfont" },
+ [3] = { [1] = "toggle", [2] = L["Outline"], [3] = "outline" },
+ [4] = { [1] = "toggle", [2] = L["Force Shown"], [3] = "forceShow" },
+ [5] = { [1] = "toggle", [2] = L["Tooltip On"], [3] = "tooltipOn" },
+ [6] = { [1] = "toggle", [2] = L["Auto Repair"], [3] = "autorepair" },
+ [7] = { [1] = "toggle", [2] = L["Use Guild Bank"], [3] = "usegfunds" },
+ [8] = { [1] = "text", [2] = L["Text Display"], [3] = "textDisplay" },
+ [9] = { [1] = "desc", [2] = "ArmorTextDesc", [3] = L["ArmorTextDesc"] },
+ [10] = { [1] = "range", [2] = L["Font Size"], [3] = "fontSize", [4] = 6, [5] = 40, [6] = 1 },
+ [11] = { [1] = "select", [2] = L["Font"], [3] = "font", [4] = SLDT.fontTbl },
+ [12] = { [1] = "select", [2] = L["Justify"], [3] = "aP", [4] = SLDT.justTbl },
+ [13] = { [1] = "text", [2] = L["Parent"], [3] = "anch" },
+ [14] = { [1] = "select", [2] = L["Anchor"], [3] = "aF", [4] = SLDT.anchTbl },
+ [15] = { [1] = "text", [2] = L["X Offset"], [3] = "xOff" },
+ [16] = { [1] = "text", [2] = L["Y Offset"], [3] = "yOff" },
+ [17] = { [1] = "select", [2] = L["Frame Strata"], [3] = "strata", [4] = SLDT.stratTbl },
+}
+
+local function OnInit()
+ SLDT.Armor.db = SLDT.db:RegisterNamespace(MODNAME)
+ SLDT.Armor.db:RegisterDefaults({
+ profile = {
+ name = "Armor",
+ enabled = true,
+ autorepair = false,
+ usegfunds = false,
+ forceShow = false,
+ aP = "CENTER",
+ anch = "UIParent",
+ aF = "BOTTOMLEFT",
+ xOff = 449,
+ yOff = 7,
+ strata = "LOW",
+ gfont = false,
+ fontSize = 14,
+ font = "Arial Narrow",
+ outline = false,
+ tooltipOn = true,
+ textDisplay = "Armor [Dur]%",
+ },
+ })
+ db = SLDT.Armor.db.profile
+
+ SLDT.Modules = SLDT.Modules or {}
+ if ( not SLDT.Modules[MODNAME] ) then table.insert(SLDT.Modules, { MODNAME, db }) end
+ frame, text, tool = SLDT:SetupBaseFrame(SLDT.Armor)
+ SetupToolTip()
+
+ SLDT.Armor:UnregisterEvent("PLAYER_ENTERING_WORLD")
+ SLDT.Armor:Enable()
+end
+
+SLDT.Armor:RegisterEvent("PLAYER_ENTERING_WORLD")
+SLDT.Armor:SetScript("OnEvent", OnInit)
\ No newline at end of file
diff --git a/Elements/bag.lua b/Elements/bag.lua
new file mode 100644
index 0000000..374fe69
--- /dev/null
+++ b/Elements/bag.lua
@@ -0,0 +1,173 @@
+--[[ SLDataText Module: Bag ]]
+--[[ Author: Taffu RevDate: 01/21/2018 Version: 7.3.1 ]]
+
+local SLDT, MODNAME = SLDataText, "Bag"
+if ( SLDT ) then SLDT.Bag = CreateFrame("Frame") end
+local L = SLDT.Locale
+local db, frame, text, tool
+
+local function convertMoney(moolah, display)
+ local g, s, c = abs(moolah/10000), abs(mod(moolah/100, 100)), abs(mod(moolah, 100))
+ local cash
+ if ( display ) then -- True = Long display
+ if ( g < 1 ) then g = "" else g = string.format("%d|cffffd700g|r ", g) end
+ if ( s < 1 ) then s = "" else s = string.format("%d|cffc7c7cfs|r ", s) end
+ c = string.format("%d|cffeda55fc|r", c)
+ cash = string.format("%s%s%s", g, s, c)
+ else
+ cash = string.format("%.1f|cffffd700g|r", g)
+ end
+ return cash
+end
+
+local function SetupToolTip()
+ tool:SetScript("OnEnter", function(this)
+ GameTooltip:SetOwner(this, db.aF)
+ local bagRem, bagTtl = 0, 0
+ for i = 0, NUM_BAG_SLOTS do
+ bagRem, bagTtl = bagRem + GetContainerNumFreeSlots(i), bagTtl + GetContainerNumSlots(i)
+ end
+ GameTooltip:AddLine("|cffffffff"..L["Bag Info"].."|r")
+ GameTooltip:AddDoubleLine(L["Space Used"], string.format("%d", bagTtl - bagRem), 1,1,0,1,1,1)
+ GameTooltip:AddDoubleLine(L["Space Avail"], string.format("%d", bagTtl), 1,1,0,1,1,1)
+ GameTooltip:AddDoubleLine(L["Space Left"], string.format("%d", bagRem), 1,1,0,1,1,1)
+ GameTooltip:AddLine(" ")
+ GameTooltip:AddDoubleLine(L["AutoSell Junk"], string.format("%s", db.selljunk and "On" or "Off"), 1,1,0,1,1,1)
+ GameTooltip:AddLine(" ")
+ GameTooltip:AddDoubleLine(L["Left-Click"], L["Toggle Bags"], 1,1,0,1,1,1)
+ GameTooltip:Show()
+ end)
+ tool:SetScript("OnLeave", function(this) if ( GameTooltip:IsShown() ) then GameTooltip:Hide() end end)
+ tool:SetScript("OnMouseDown", function(this, button)
+ if ( button == "LeftButton" ) then OpenAllBags() end
+ end)
+end
+
+function SLDT.Bag:Enable()
+ if ( db.enabled ) then
+ SLDT:UpdateBaseText(self, db)
+ self:RegisterEvent("BAG_UPDATE")
+ self:RegisterEvent("MERCHANT_SHOW")
+ self:SetScript("OnEvent", function(self, event)
+ if ( event == "MERCHANT_SHOW" and db.selljunk ) then
+ local junkMon = 0
+ for bag = 0, NUM_BAG_SLOTS do
+ for slot = 0, GetContainerNumSlots(bag) do
+ local link = GetContainerItemLink(bag, slot)
+ if ( link ) then
+ if ( select(3, GetItemInfo(link)) == 0 ) then
+ junkMon = junkMon + select(11, GetItemInfo(link)) * select(2, GetContainerItemInfo(bag, slot))
+ UseContainerItem(bag, slot)
+ end
+ end
+ end
+ end
+ if ( junkMon > 0 ) then print(string.format("|cff6698FFSLDataText|r: %s %s", L["JunkSoldLine"], convertMoney(junkMon, true))) end
+ self:Refresh()
+ else self:Refresh() end
+ end)
+ end
+ self:Refresh()
+end
+
+function SLDT.Bag:Disable()
+ if ( not db.enabled ) then
+ self:UnregisterEvent("BAG_UPDATE")
+ self:UnregisterEvent("MERCHANT_SHOW")
+ end
+ self:Refresh()
+end
+
+local tags = {
+ ["T"] = function()
+ local total = 0
+ for i = 0, NUM_BAG_SLOTS do
+ total = total + GetContainerNumSlots(i)
+ end
+ return string.format("|cffffffff%s|r|cff%s", total, SLDT.db.profile.cCol and SLDT.classColor or "ffffff")
+ end,
+ ["U"] = function()
+ local rem, total = 0, 0
+ for i = 0, NUM_BAG_SLOTS do
+ rem, total = rem + GetContainerNumFreeSlots(i), total + GetContainerNumSlots(i)
+ end
+ return string.format("|cffffffff%s|r|cff%s", total-rem, SLDT.db.profile.cCol and SLDT.classColor or "ffffff")
+ end,
+ ["R"] = function()
+ local rem = 0
+ for i = 0, NUM_BAG_SLOTS do
+ rem = rem + GetContainerNumFreeSlots(i)
+ end
+ return string.format("|cffffffff%s|r|cff%s", rem, SLDT.db.profile.cCol and SLDT.classColor or "ffffff")
+ end,
+}
+
+function SLDT.Bag:Refresh()
+ if ( db.enabled or SLDataText.db.profile.configMode ) then
+ if ( not self.firstRun ) then self.firstRun = true; SLDT:UpdateBaseText(self, db) end
+
+ local str = db.textDisplay
+ str = string.gsub(str, "%[(%w+)%]", function(w) return tags[w]() end)
+ text:SetFormattedText("|cff%s%s|r", SLDT.db.profile.cCol and SLDT.classColor or "ffffff", str)
+
+ SLDT:UpdateBaseFrame(SLDT.Bag, db)
+ else
+ if ( frame:IsShown() and not SLDataText.db.profile.configMode ) then frame:Hide() end
+ end
+end
+
+SLDT.Bag.optsTbl = {
+ [1] = { [1] = "toggle", [2] = L["Enabled"], [3] = "enabled" },
+ [2] = { [1] = "toggle", [2] = L["Global Font"], [3] = "gfont" },
+ [3] = { [1] = "toggle", [2] = L["Outline"], [3] = "outline" },
+ [4] = { [1] = "toggle", [2] = L["Force Shown"], [3] = "forceShow" },
+ [5] = { [1] = "toggle", [2] = L["Tooltip On"], [3] = "tooltipOn" },
+ [6] = { [1] = "toggle", [2] = L["AutoSell Junk"], [3] = "selljunk" },
+ [7] = { [1] = "text", [2] = L["Text Display"], [3] = "textDisplay" },
+ [8] = { [1] = "desc", [2] = "BagTextDesc", [3] = L["BagTextDesc"] },
+ [9] = { [1] = "range", [2] = L["Font Size"], [3] = "fontSize", [4] = 6, [5] = 40, [6] = 1 },
+ [10] = { [1] = "select", [2] = L["Font"], [3] = "font", [4] = SLDT.fontTbl },
+ [11] = { [1] = "select", [2] = L["Justify"], [3] = "aP", [4] = SLDT.justTbl },
+ [12] = { [1] = "text", [2] = L["Parent"], [3] = "anch" },
+ [13] = { [1] = "select", [2] = L["Anchor"], [3] = "aF", [4] = SLDT.anchTbl },
+ [14] = { [1] = "text", [2] = L["X Offset"], [3] = "xOff" },
+ [15] = { [1] = "text", [2] = L["Y Offset"], [3] = "yOff" },
+ [16] = { [1] = "select", [2] = L["Frame Strata"], [3] = "strata", [4] = SLDT.stratTbl },
+}
+
+
+local function OnInit()
+ SLDT.Bag.db = SLDT.db:RegisterNamespace(MODNAME)
+ SLDT.Bag.db:RegisterDefaults({
+ profile = {
+ name = "Bag",
+ enabled = true,
+ selljunk = false,
+ forceShow = false,
+ aP = "CENTER",
+ anch = "UIParent",
+ aF = "BOTTOMLEFT",
+ xOff = 364,
+ yOff = 7,
+ strata = "LOW",
+ gfont = false,
+ fontSize = 14,
+ font = "Arial Narrow",
+ outline = false,
+ tooltipOn = true,
+ textDisplay = "Bag: [R]/[T]",
+ },
+ })
+ db = SLDT.Bag.db.profile
+
+ SLDT.Modules = SLDT.Modules or {}
+ if ( not SLDT.Modules[MODNAME] ) then table.insert(SLDT.Modules, { MODNAME, db }) end
+ frame, text, tool = SLDT:SetupBaseFrame(SLDT.Bag)
+ SetupToolTip()
+
+ SLDT.Bag:UnregisterEvent("PLAYER_ENTERING_WORLD")
+ SLDT.Bag:Enable()
+end
+
+SLDT.Bag:RegisterEvent("PLAYER_ENTERING_WORLD")
+SLDT.Bag:SetScript("OnEvent", OnInit)
\ No newline at end of file
diff --git a/Elements/clock.lua b/Elements/clock.lua
new file mode 100644
index 0000000..1b9cde0
--- /dev/null
+++ b/Elements/clock.lua
@@ -0,0 +1,329 @@
+--[[ SLDataText Module: Clock ]]
+--[[ Author: Taffu RevDate: 01/21/2018 Version: 7.3.1 ]]
+
+-- Updated by Suicidal Katt
+-- Added additional toggle for "Custom Time Format", previously the custom string was only used if realmTime was not used.
+-- Added additional toggle for "Military Time" and added support for the db value 'format24'.
+-- Fix: Custom Time formatting will use class colors if used and will lowercase the am/pm for any instance of %p throughout the string.
+-- Fix: 'hourCorrect' will now work on any instance of %H or %I throughout the string.
+-- Fix: Realm Time will now toggle between local and realm time for both custom strings and default formatting.
+-- Added 'getLocalTime()' function to allow formatted text for local time.
+-- Alteration: Options ordering has changed, see table below as well as the default value for the 'timeString'.
+-- Note: A lot of my code could probably be shrunken down but I feel like this change is a pretty large one. Some additional localizations are needed.
+
+
+local SLDT, MODNAME = SLDataText, "Clock"
+if ( SLDT ) then SLDT.Clock = CreateFrame("Frame") end
+local L = SLDT.Locale
+local db, frame, text, tool
+
+local rCol, gCol = RED_FONT_COLOR_CODE, GREEN_FONT_COLOR_CODE
+local locTime, rlmTime
+local function getGameTime()
+ local serTime, serAMPM
+ local hour, minu = GetGameTime()
+ if ( minu < 10 ) then minu = string.format("0%i", minu) end
+ if ( db.format24 ) then
+ serAMPM = ""; serTime = string.format("%s:%s", hour, minu)
+ else
+ if ( hour > 11 ) then serAMPM = "pm" else serAMPM = "am" end
+ if ( hour == 0 ) then hour = hour + 12 elseif hour > 12 then hour = hour - 12 end
+ serTime = string.format("%s:%s", hour, minu)
+ end
+ return serTime, serAMPM
+end
+
+local function getLocalTime()
+ local serTime, serAMPM
+ local hour, minu = tonumber(date("%H")),tonumber(date("%M"))
+ if ( minu < 10 ) then minu = string.format("0%i", minu) end
+ if ( db.format24 ) then
+ serAMPM = ""; serTime = string.format("%s:%s", hour, minu)
+ else
+ if ( hour > 11 ) then serAMPM = "pm" else serAMPM = "am" end
+ if ( hour == 0 ) then hour = hour + 12 elseif hour > 12 then hour = hour - 12 end
+ serTime = string.format("%s:%s", hour, minu)
+ end
+ return serTime, serAMPM
+end
+
+local function formatTimer(wait, long)
+ local timestring
+ local h, m, s = 0, 0, 0
+ if ( wait >= 3600 ) then
+ h = floor(wait / 3600); wait = wait - (h * 3600)
+ m = floor(wait / 60); wait = wait - (m * 60)
+ s = floor(wait)
+
+ if ( m < 10 ) then m = string.format("%d%d", 0, m) end
+ if ( s < 10 ) then s = string.format("%d%d", 0, s) end
+
+ if ( long ) then
+ timestring = string.format("%s hours", h)
+ else
+ timestring = string.format("%s:%s:%s", h, m, s)
+ end
+ elseif ( wait >= 60 and wait < 3600 ) then
+ m = floor(wait / 60); wait = wait - (m * 60)
+ s = floor(wait)
+
+ if ( s < 10 ) then s = string.format("%d%d", 0, s) end
+
+ if ( long ) then
+ timestring = string.format("%s min %s sec", m, s)
+ else
+ timestring = string.format("%s:%s", m, s)
+ end
+ elseif ( wait < 60 ) then
+ s = floor(wait)
+
+ if ( long ) then
+ timestring = string.format("%s sec", s)
+ else
+ timestring = string.format("%s", s)
+ end
+ end
+
+ return timestring
+end
+
+local function SetupToolTip()
+ tool:SetScript("OnEnter", function(this)
+ GameTooltip:SetOwner(this, db.aF)
+ GameTooltip:AddLine(string.format("|cffffffff%s %i, %i|r", date("%B"), date("%d"), date("%Y")))
+ GameTooltip:AddDoubleLine("Realm Time", string.format("%s%s", select(1, getGameTime()), select(2, getGameTime())), 1,1,0,1,1,1)
+ local hr, mi, mer = date("%I"), date("%M"), string.lower(date("%p"))
+ GameTooltip:AddDoubleLine("Local Time", string.format("%i:%s%s", hr, mi, mer), 1,1,0,1,1,1)
+ GameTooltip:AddLine(" ")
+
+ if ( db.showPVP ) then
+ local inQueue = nil
+ for i = 1, 2 do
+ local id, name, active, canQ, wait, _ = GetWorldPVPAreaInfo(i)
+ if ( active ) then
+ name = string.format("%s%s (A)|r", rCol, name)
+ elseif ( canQ ) then
+ name = string.format("%s%s (Q)|r", gCol, name)
+ end
+ GameTooltip:AddDoubleLine(name, formatTimer(wait))
+ end
+
+ for j = 1, MAX_WORLD_PVP_QUEUES do
+ local status, map = GetWorldPVPQueueStatus(j)
+ if ( status == "queued" ) then inQueue = {}; table.insert(inQueue, map) end
+ end
+
+ if ( inQueue ~= nil ) then
+ local maps = ""
+ for k, v in pairs(inQueue) do
+ maps = string.format("%s %s", maps, v)
+ end
+ GameTooltip:AddLine(string.format("%s %s", L["Queued for:"], maps))
+ end
+
+ GameTooltip:AddLine(" ")
+ end
+
+ GameTooltip:AddDoubleLine(L["Left-Click"], L["Toggle Calendar"], 1,1,0,1,1,1)
+ GameTooltip:AddDoubleLine(L["Right-Click"], L["Toggle Time Manager"], 1,1,0,1,1,1)
+ GameTooltip:Show()
+ end)
+ tool:SetScript("OnLeave", function(this)
+ if ( GameTooltip:IsShown() ) then GameTooltip:Hide() end
+ end)
+ tool:SetScript("OnMouseDown", function(self, button)
+ if ( button == "LeftButton" ) then
+ ToggleCalendar()
+ elseif ( button == "RightButton" ) then
+ ToggleTimeManager()
+ end
+ end)
+end
+
+function SLDT.Clock:Enable()
+ if ( db.enabled ) then
+ SLDT:UpdateBaseText(self, db)
+ frame:SetScript("OnUpdate", function(_, elapsed)
+ self:Refresh()
+ end)
+ end
+end
+
+function SLDT.Clock:Disable()
+ if ( not db.enabled ) then
+ frame:SetScript("OnUpdate", nil)
+ end
+ self:Refresh()
+end
+
+function SLDT.Clock:Refresh()
+ if ( db.enabled or SLDT.db.profile.configMode ) then
+ if ( not self.firstRun ) then self.firstRun = true; SLDT:UpdateBaseText(self, db) end
+
+ if ( TimeManagerClockButton:IsShown() ) then TimeManagerClockButton:Hide() end
+
+ if db.customString then
+ local timeString = db.timeString
+ local hr12String,hr24String,amString
+ local hour,mns = GetGameTime()
+ -- Coding for this was found in the UIParent.lua beginning with the function on line 3854 'BetterDate'.
+ local function amFind()
+ if db.realmTime then
+ if ( hour > 11 ) then return "pm" else return "am" end
+ else
+ return strlower(tostring(date("%p")))
+ end
+ end
+ amString = string.format("|cff%s%s|r", SLDT.db.profile.cCol and SLDT.classColor or "ffffff", amFind())
+ timeString = gsub(timeString, "^%%p", amString)
+ timeString = gsub(timeString, "([^%%])%%p", "%1"..amString); -- Fix any other within the string.
+
+ local hour12
+ if ( hour == 0 ) then
+ hour12 = hour + 12
+ elseif hour > 12 then
+ hour12 = hour - 12
+ else
+ hour12 = hour
+ end
+
+ if db.hourCorrect then
+ if db.realmTime then
+ if strfind(tostring(hour12),0) == 1 then -- If first character is a 0 then replace 0 with ""
+ hr12String = gsub(tostring(hour12), 0, "", 1)
+ else
+ hr12String = hour12
+ end
+ if strfind(tostring(hour),0) == 1 then
+ hr24String = gsub(tostring(hour), 0, "", 1)
+ else
+ hr24String = hour
+ end
+ else
+ if strfind(tostring(date("%I")),0) == 1 then
+ hr12String = gsub(tostring(date("%I")), 0, "", 1)
+ else
+ hr12String = date("%I")
+ end
+ if strfind(tostring(date("%H")),0) == 1 then
+ hr24String = gsub(tostring(date("%H")), 0, "", 1)
+ else
+ hr24String = date("%H")
+ end
+ end
+ else
+ if db.realmTime then
+ hr12String = hour12
+ hr24String = hour
+ else
+ hr12String = date("%I")
+ hr24String = date("%H")
+ end
+ end
+ timeString = gsub(timeString, "^%%I", hr12String)
+ timeString = gsub(timeString, "([^%%])%%I", "%1"..hr12String);
+
+ timeString = gsub(timeString, "^%%H", hr24String)
+ timeString = gsub(timeString, "([^%%])%%H", "%1"..hr24String);
+
+ text:SetText(date(timeString))
+ else
+ rlmTime = string.format("%s|cff%s%s|r", select(1, getGameTime()), SLDT.db.profile.cCol and SLDT.classColor or "ffffff", select(2, getGameTime()))
+ locTime = string.format("%s|cff%s%s|r", select(1, getLocalTime()), SLDT.db.profile.cCol and SLDT.classColor or "ffffff", select(2, getLocalTime()))
+ if db.realmTime and rlmTime then
+ text:SetText(rlmTime)
+ elseif not db.realmTime and locTime then
+ text:SetText(locTime)
+ end
+ end
+
+ if ( not self.Moving) then SLDT:UpdateBaseFrame(self, db) end
+ else
+ if ( not TimeManagerClockButton:IsShown() ) then TimeManagerClockButton:Show() end
+ if ( frame:IsShown() and not SLDataText.db.profile.configMode ) then frame:Hide() end
+ end
+end
+
+SLDT.Clock.optsTbl = {
+ [1] = { [1] = "toggle", [2] = L["Enabled"], [3] = "enabled" },
+ [2] = { [1] = "toggle", [2] = L["Global Font"], [3] = "gfont" },
+ [3] = { [1] = "toggle", [2] = L["Outline"], [3] = "outline" },
+ [4] = { [1] = "toggle", [2] = L["Force Shown"], [3] = "forceShow" },
+ [5] = { [1] = "toggle", [2] = L["Tooltip On"], [3] = "tooltipOn" },
+ [6] = { [1] = "toggle", [2] = L["PvP Info"], [3] = "showPVP" },
+ [7] = { [1] = "toggle", [2] = L["CorrHour"], [3] = "hourCorrect" },
+ [8] = { [1] = "toggle", [2] = "Custom Time Format", [3] = "customString" }, -- Needs localization
+ [9] = { [1] = "desc", [2] = L["ClockDesc"], [3] = L["ClockDesc"] },
+ [10] = { [1] = "text", [2] = L["Time String"], [3] = "timeString" },
+ [11] = { [1] = "toggle", [2] = L["Realm Time"], [3] = "realmTime" },
+ [12] = { [1] = "toggle", [2] = "Military Time", [3] = "format24" }, -- Needs localization
+ [13] = { [1] = "toggle", [2] = L["PvP Info"], [3] = "showPVP" },
+ [14] = { [1] = "range", [2] = L["Font Size"], [3] = "fontSize", [4] = 6, [5] = 40, [6] = 1 },
+ [15] = { [1] = "select", [2] = L["Font"], [3] = "font", [4] = SLDT.fontTbl },
+ [16] = { [1] = "select", [2] = L["Justify"], [3] = "aP", [4] = SLDT.justTbl },
+ [17] = { [1] = "text", [2] = L["Parent"], [3] = "anch" },
+ [18] = { [1] = "select", [2] = L["Anchor"], [3] = "aF", [4] = SLDT.anchTbl },
+ [19] = { [1] = "text", [2] = L["X Offset"], [3] = "xOff" },
+ [20] = { [1] = "text", [2] = L["Y Offset"], [3] = "yOff" },
+ [21] = { [1] = "select", [2] = L["Frame Strata"], [3] = "strata", [4] = SLDT.stratTbl },
+}
+
+local function OnInit()
+ SLDT.Clock.db = SLDT.db:RegisterNamespace(MODNAME)
+ SLDT.Clock.db:RegisterDefaults({
+ profile = {
+ name = "Clock",
+ enabled = true,
+ forceShow = false,
+ aP = "CENTER",
+ anch = "UIParent",
+ aF = "BOTTOMLEFT",
+ xOff = 0,
+ yOff = 7,
+ strata = "MEDIUM",
+ gfont = false,
+ fontSize = 14,
+ font = "Arial Narrow",
+ outline = false,
+ tooltipOn = true,
+ showPVP = true,
+ hourCorrect = true,
+ realmTime = false,
+ customString = false,
+ timeString = "%a, %b, %d %I:%M %p",
+ },
+ })
+ db = SLDT.Clock.db.profile
+
+ SLDT.Modules = SLDT.Modules or {}
+ if ( not SLDT.Modules[MODNAME] ) then table.insert(SLDT.Modules, { MODNAME, db }) end
+ frame, text, tool = SLDT:SetupBaseFrame(SLDT.Clock)
+ SetupToolTip()
+
+ SLDT.Clock:UnregisterEvent("PLAYER_ENTERING_WORLD")
+ SLDT.Clock:Enable()
+end
+
+SLDT.Clock:RegisterEvent("PLAYER_ENTERING_WORLD")
+SLDT.Clock:SetScript("OnEvent", OnInit)
+
+--[[ WORKING TIME ESCAPES
+%a abbreviated weekday name (e.g., Wed)
+%A full weekday name (e.g., Wednesday)
+%b abbreviated month name (e.g., Sep)
+%B full month name (e.g., September)
+%c date and time (e.g., 09/16/98 23:48:10)
+%d day of the month (16) [01-31]
+%H hour, using a 24-hour clock (23) [00-23]
+%I hour, using a 12-hour clock (11) [01-12]
+%M minute (48) [00-59]
+%m month (09) [01-12]
+%p either "am" or "pm" (pm)
+%S second (10) [00-61]
+%w weekday (3) [0-6 = Sunday-Saturday]
+%x date (e.g., 09/16/98)
+%X time (e.g., 23:48:10)
+%Y full year (1998)
+%y two-digit year (98) [00-99]
+%% the character `%
+]]
\ No newline at end of file
diff --git a/Elements/currency.lua b/Elements/currency.lua
new file mode 100644
index 0000000..d6ff42c
--- /dev/null
+++ b/Elements/currency.lua
@@ -0,0 +1,144 @@
+--[[ SLDataText Module: Currency ]]
+--[[ Author: Taffu RevDate: 01/21/2018 Version: 7.3.1 ]]
+
+local SLDT, MODNAME, SLT = SLDataText, "Currency", LibStub("LibSLTip-1.0")
+if ( SLDT ) then SLDT.Currency = CreateFrame("Frame") end
+local L = SLDT.Locale
+local db, frame, text, tool, tip
+
+local function SetupToolTip()
+ tool:SetScript("OnEnter", function(this)
+ tip = SLT:GetTooltip("SLDT_Currency", true)
+ SLT:AddHeader("SLDT_Currency", L["Currency"])
+
+ for k, v in pairs(SLDT.Currency.currTbl) do
+ local buttonFunc = function(self, button)
+ db["display"] = k
+ SLDT.Currency:Refresh()
+ end
+
+ SLT:AddDoubleLine("SLDT_Currency", k, tostring(v), nil, nil, true, buttonFunc)
+ end
+
+ SLT:AddFooter("SLDT_Currency", L["Click to set display currency."], nil)
+ if ( select(2, GetNumGuildMembers()) > 1 and not InCombatLockdown() ) then SLT:ShowTooltip("SLDT_Currency", frame) end
+ end)
+ tool:SetScript("OnLeave", function(this) SLT:ClearTooltip("SLDT_Currency") end)
+ tool:SetScript("OnMouseDown", function(this, button)
+ ToggleCharacter("TokenFrame")
+ end)
+end
+
+local function TruncateName(name)
+ local first, second = string.split(" ", name)
+ return first
+end
+
+function SLDT.Currency:Enable()
+ if ( db.enabled ) then
+ SLDT:UpdateBaseText(self, db)
+ self:RegisterEvent("CURRENCY_DISPLAY_UPDATE")
+ self:SetScript("OnEvent", function() self:Refresh() end)
+ end
+ self:Refresh()
+end
+
+function SLDT.Currency:Disable()
+ if ( not db.enabled ) then
+ self:UnregisterEvent("CURRENCY_DISPLAY_UPDATE")
+ self:SetScript("OnEvent", nil)
+ end
+ self:Refresh()
+end
+
+function SLDT.Currency:Refresh()
+ if ( db.enabled or SLDataText.db.profile.configMode ) then
+ if ( not self.firstRun ) then self.firstRun = true; SLDT:UpdateBaseText(self, db) end
+
+ SLDT.Currency.currTbl = {}
+ for i = 1, C_CurrencyInfo.GetCurrencyListSize() do
+ local currencyListInfo = C_CurrencyInfo.GetCurrencyListInfo(i)
+ -- local name, isHeader, isExpanded, isUnused, isWatched, count, extraCurrencyType, icon, itemID = GetCurrencyListInfo(i)
+ if ( not currencyListInfo.isHeader ) and ( not currencyListInfo.isTypeUnused ) then
+ SLDT.Currency.currTbl[currencyListInfo.name] = currencyListInfo.quantity
+ end
+ end
+
+ if ( SLDT.Currency.currTbl[db.display] ) then
+ local line = TruncateName(db.display)
+ text:SetFormattedText("|cff%s%s:|r %i", SLDT.db.profile.cCol and SLDT.classColor or "ffffff", line, SLDT.Currency.currTbl[db.display])
+ else
+ text:SetText(L["No Currency"])
+ end
+
+ SLDT:UpdateBaseFrame(SLDT.Currency, db)
+ else
+ if ( frame:IsShown() and not SLDataText.db.profile.configMode ) then frame:Hide() end
+ end
+end
+
+local function GetCurrList()
+ local list = {}
+ table.insert(list, "None")
+ for i = 1, C_CurrencyInfo.GetCurrencyListSize() do
+ local currencyListInfo = C_CurrencyInfo.GetCurrencyListInfo(i)
+
+ if ( not currencyListInfo.isHeader ) and ( not currencyListInfo.isTypeUnused ) then
+ table.insert(list, currencyListInfo.name)
+ end
+ end
+ return list
+end
+
+SLDT.Currency.optsTbl = {
+ [1] = { [1] = "toggle", [2] = L["Enabled"], [3] = "enabled" },
+ [2] = { [1] = "toggle", [2] = L["Global Font"], [3] = "gfont" },
+ [3] = { [1] = "toggle", [2] = L["Outline"], [3] = "outline" },
+ [4] = { [1] = "toggle", [2] = L["Force Shown"], [3] = "forceShow" },
+ [5] = { [1] = "toggle", [2] = L["Tooltip On"], [3] = "tooltipOn" },
+ [6] = { [1] = "range", [2] = L["Font Size"], [3] = "fontSize", [4] = 6, [5] = 40, [6] = 1 },
+ [7] = { [1] = "select", [2] = L["Display Currency"], [3] = "display", [4] = GetCurrList() },
+ [8] = { [1] = "select", [2] = L["Font"], [3] = "font", [4] = SLDT.fontTbl },
+ [9] = { [1] = "select", [2] = L["Justify"], [3] = "aP", [4] = SLDT.justTbl },
+ [10] = { [1] = "text", [2] = L["Parent"], [3] = "anch" },
+ [11] = { [1] = "select", [2] = L["Anchor"], [3] = "aF", [4] = SLDT.anchTbl },
+ [12] = { [1] = "text", [2] = L["X Offset"], [3] = "xOff" },
+ [13] = { [1] = "text", [2] = L["Y Offset"], [3] = "yOff" },
+ [14] = { [1] = "select", [2] = L["Frame Strata"], [3] = "strata", [4] = SLDT.stratTbl },
+}
+
+local function OnInit()
+ SLDT.Currency.db = SLDT.db:RegisterNamespace(MODNAME)
+ SLDT.Currency.db:RegisterDefaults({
+ profile = {
+ name = "Currency",
+ enabled = true,
+ display = "None",
+ forceShow = false,
+ aP = "CENTER",
+ anch = "UIParent",
+ aF = "BOTTOM",
+ xOff = -84,
+ yOff = 7,
+ strata = "LOW",
+ gfont = false,
+ fontSize = 14,
+ font = "Arial Narrow",
+ outline = false,
+ interval = 10,
+ tooltipOn = true,
+ },
+ })
+ db = SLDT.Currency.db.profile
+
+ SLDT.Modules = SLDT.Modules or {}
+ if ( not SLDT.Modules[MODNAME] ) then table.insert(SLDT.Modules, { MODNAME, db }) end
+ frame, text, tool = SLDT:SetupBaseFrame(SLDT.Currency)
+ SetupToolTip()
+
+ SLDT.Currency:UnregisterEvent("PLAYER_ENTERING_WORLD")
+ SLDT.Currency:Enable()
+end
+
+SLDT.Currency:RegisterEvent("PLAYER_ENTERING_WORLD")
+SLDT.Currency:SetScript("OnEvent", OnInit)
\ No newline at end of file
diff --git a/Elements/exp.lua b/Elements/exp.lua
new file mode 100644
index 0000000..8a5e20d
--- /dev/null
+++ b/Elements/exp.lua
@@ -0,0 +1,175 @@
+--[[ SLDataText Module: Exp ]]
+--[[ Author: Taffu RevDate: 01/21/2018 Version: 7.3.1 ]]
+
+-- Rev: Added tooltip
+
+local SLDT, MODNAME, SLT = SLDataText, "Exp", LibStub("LibSLTip-1.0")
+if ( SLDT ) then SLDT.Exp = CreateFrame("Frame") end
+local L = SLDT.Locale
+local db, frame, text, tool
+
+local tags = {
+ ["Cur"] = function()
+ local curXP = UnitXP("player")
+ if ( curXP > 9999 ) then
+ return string.format("|cffffffff%.0fk|r|cff%s", curXP / 1000, SLDT.db.profile.cCol and SLDT.classColor or "ffffff")
+ else
+ return string.format("|cffffffff%.0f|r|cff%s", curXP, SLDT.db.profile.cCol and SLDT.classColor or "ffffff")
+ end
+ end,
+ ["Max"] = function()
+ local maxXP = UnitXPMax("player")
+ if ( maxXP > 9999 ) then
+ return string.format("|cffffffff%.0fk|r|cff%s", maxXP / 1000, SLDT.db.profile.cCol and SLDT.classColor or "ffffff")
+ else
+ return string.format("|cffffffff%.0f|r|cff%s", maxXP, SLDT.db.profile.cCol and SLDT.classColor or "ffffff")
+ end
+ end,
+ ["MaxRaw"] = function()
+ local maxXP = UnitXPMax("player")
+ return string.format("|cffffffff%.0f|r|cff%s", maxXP, SLDT.db.profile.cCol and SLDT.classColor or "ffffff")
+ end,
+ ["Rem"] = function()
+ local remXP = UnitXPMax("player") - UnitXP("player")
+ if ( remXP > 9999 ) then
+ return string.format("|cffffffff%.0fk|r|cff%s", remXP / 1000, SLDT.db.profile.cCol and SLDT.classColor or "ffffff")
+ else
+ return string.format("|cffffffff%.0f|r|cff%s", remXP, SLDT.db.profile.cCol and SLDT.classColor or "ffffff")
+ end
+ end,
+ ["Per"] = function()
+ local perXP = UnitXP("player") * (100 / UnitXPMax("player"))
+ return string.format("|cffffffff%.1f%%|r|cff%s", perXP, SLDT.db.profile.cCol and SLDT.classColor or "ffffff")
+ end,
+ ["PerR"] = function()
+ local perRemXP = 100 - (UnitXP("player") * (100 / UnitXPMax("player")))
+ return string.format("|cffffffff%.1f%%|r|cff%s", perRemXP, SLDT.db.profile.cCol and SLDT.classColor or "ffffff")
+ end,
+ ["R"] = function()
+ local rest = GetXPExhaustion() or 0
+ if ( rest > 9999 ) then
+ return string.format("|cffffffff%.0fk|r|cff%s", rest / 1000, SLDT.db.profile.cCol and SLDT.classColor or "ffffff")
+ else
+ return string.format("|cffffffff%.0f|r|cff%s", rest, SLDT.db.profile.cCol and SLDT.classColor or "ffffff")
+ end
+ end,
+ ["RP"] = function()
+ local rem, rest = UnitXPMax("player") - UnitXP("player"), GetXPExhaustion() or 0
+ local restPer = (100 / rem) * rest
+ return string.format("|cffffffff%.1f%%|r|cff%s", restPer, SLDT.db.profile.cCol and SLDT.classColor or "ffffff")
+ end,
+}
+
+local function SetupToolTip()
+ tool:SetScript("OnEnter", function(this)
+ if ( db.tooltipOn ) then
+ tip = SLT:GetTooltip("SLDT_Exp", false)
+ SLT:AddHeader("SLDT_Exp", UnitName("player"), "Level " .. UnitLevel("player"), {1, 1, 1})
+
+ SLT:AddDoubleLine("SLDT_Exp", "Current", tags["Cur"]() .. " (" .. tags["Per"]() .. ")")
+ SLT:AddDoubleLine("SLDT_Exp", "Needed", tags["MaxRaw"]())
+ SLT:AddDoubleLine("SLDT_Exp", "Remaining", tags["Rem"]() .. " (" .. tags["PerR"]() .. ")")
+
+ if ( GetXPExhaustion() ) then
+ SLT:AddDoubleLine("SLDT_Exp", "Rested", tags["R"]() .. " (" .. tags["RP"]() .. ")")
+ end
+
+ if ( not InCombatLockdown() ) then SLT:ShowTooltip("SLDT_Exp", frame) end
+ end
+ end)
+ tool:SetScript("OnLeave", function(this) if ( db.tooltipOn ) then SLT:ClearTooltip("SLDT_Exp") end end)
+end
+
+function SLDT.Exp:Enable()
+ if ( db.enabled ) then
+ SLDT:UpdateBaseText(self, db)
+ self:RegisterEvent("PLAYER_XP_UPDATE")
+ self:RegisterEvent("DISABLE_XP_GAIN")
+ self:RegisterEvent("ENABLE_XP_GAIN")
+ self:SetScript("OnEvent", function(self, event) self:Refresh() end)
+ end
+ self:Refresh()
+end
+
+function SLDT.Exp:Disable()
+ if ( not db.enabled ) then
+ self:UnregisterEvent("PLAYER_XP_UPDATE")
+ self:UnregisterEvent("DISABLE_XP_GAIN")
+ self:UnregisterEvent("ENABLE_XP_GAIN")
+ self:SetScript("OnEvent", nil)
+ end
+ self:Refresh()
+end
+
+function SLDT.Exp:Refresh()
+ if ( db.enabled or SLDataText.db.profile.configMode ) then
+ if ( not self.firstRun ) then self.firstRun = true; SLDT:UpdateBaseText(self, db) end
+
+ if ( db.hideMaxLvl and ( UnitLevel("player") == 110 ) ) then
+ text:SetText("")
+ else
+ local str = db.textDisplay
+ str = string.gsub(str, "%[(%w+)%]", function(w) return tags[w]() end)
+ text:SetFormattedText("|cff%s%s|r", SLDT.db.profile.cCol and SLDT.classColor or "ffffff", str)
+ end
+
+ SLDT:UpdateBaseFrame(self, db)
+ else
+ if ( frame:IsShown() and not SLDataText.db.profile.configMode ) then frame:Hide() end
+ end
+end
+
+SLDT.Exp.optsTbl = {
+ [1] = { [1] = "toggle", [2] = L["Enabled"], [3] = "enabled" },
+ [2] = { [1] = "toggle", [2] = L["Global Font"], [3] = "gfont" },
+ [3] = { [1] = "toggle", [2] = L["Outline"], [3] = "outline" },
+ [4] = { [1] = "toggle", [2] = L["Force Shown"], [3] = "forceShow" },
+ [5] = { [1] = "toggle", [2] = L["Tooltip On"], [3] = "tooltipOn" },
+ [6] = { [1] = "toggle", [2] = L["Max Level Hide"], [3] = "hideMaxLvl" },
+ [7] = { [1] = "text", [2] = L["Text Display"], [3] = "textDisplay" },
+ [8] = { [1] = "desc", [2] = "ExpTextDesc", [3] = L["ExpTextDesc"] },
+ [9] = { [1] = "range", [2] = L["Font Size"], [3] = "fontSize", [4] = 6, [5] = 40, [6] = 1 },
+ [10] = { [1] = "select", [2] = L["Font"], [3] = "font", [4] = SLDT.fontTbl },
+ [11] = { [1] = "select", [2] = L["Justify"], [3] = "aP", [4] = SLDT.justTbl },
+ [12] = { [1] = "text", [2] = L["Parent"], [3] = "anch" },
+ [13] = { [1] = "select", [2] = L["Anchor"], [3] = "aF", [4] = SLDT.anchTbl },
+ [14] = { [1] = "text", [2] = L["X Offset"], [3] = "xOff" },
+ [15] = { [1] = "text", [2] = L["Y Offset"], [3] = "yOff" },
+ [16] = { [1] = "select", [2] = L["Frame Strata"], [3] = "strata", [4] = SLDT.stratTbl },
+}
+
+local function OnInit()
+ SLDT.Exp.db = SLDT.db:RegisterNamespace(MODNAME)
+ SLDT.Exp.db:RegisterDefaults({
+ profile = {
+ name = "Exp",
+ enabled = true,
+ hideMaxLvl = false,
+ forceShow = false,
+ aP = "CENTER",
+ anch = "UIParent",
+ aF = "BOTTOM",
+ xOff = 51,
+ yOff = 7,
+ strata = "LOW",
+ gfont = false,
+ fontSize = 14,
+ font = "Arial Narrow",
+ outline = false,
+ tooltipOn = true,
+ textDisplay = "Exp [Cur]/[Max] ([Per])",
+ },
+ })
+ db = SLDT.Exp.db.profile
+
+ SLDT.Modules = SLDT.Modules or {}
+ if ( not SLDT.Modules[MODNAME] ) then table.insert(SLDT.Modules, { MODNAME, db }) end
+ frame, text, tool = SLDT:SetupBaseFrame(SLDT.Exp)
+ SetupToolTip()
+
+ SLDT.Exp:UnregisterEvent("PLAYER_ENTERING_WORLD")
+ SLDT.Exp:Enable()
+end
+
+SLDT.Exp:RegisterEvent("PLAYER_ENTERING_WORLD")
+SLDT.Exp:SetScript("OnEvent", OnInit)
\ No newline at end of file
diff --git a/Elements/fps.lua b/Elements/fps.lua
new file mode 100644
index 0000000..75efdfb
--- /dev/null
+++ b/Elements/fps.lua
@@ -0,0 +1,100 @@
+--[[ SLDataText Module: FPS ]]
+--[[ Author: Taffu RevDate: 01/21/2018 Version: 7.3.1 ]]
+
+local SLDT, MODNAME = SLDataText, "FPS"
+if ( SLDT ) then SLDT.FPS = CreateFrame("Frame") end
+local L = SLDT.Locale
+local db, frame, text, tool
+
+function SLDT.FPS:Enable()
+ if ( db.enabled ) then
+ SLDT:UpdateBaseText(self, db)
+ local int = db.interval
+ frame:SetScript("OnUpdate", function(_, elapsed)
+ int = int - elapsed
+ if ( int <= 0 ) then self:Refresh(); int = db.interval end
+ end)
+ end
+ self:Refresh()
+end
+
+function SLDT.FPS:Disable()
+ if ( not db.enabled ) then
+ frame:SetScript("OnUpdate", nil)
+ end
+ self:Refresh()
+end
+
+local tags = {
+ ["F"] = function()
+ local fr = GetFramerate()
+ return string.format("|cffffffff%.0f|r|cff%s", fr, SLDT.db.profile.cCol and SLDT.classColor or "ffffff")
+ end,
+}
+
+function SLDT.FPS:Refresh()
+ if ( db.enabled or SLDataText.db.profile.configMode ) then
+ if ( not self.firstRun ) then self.firstRun = true; SLDT:UpdateBaseText(self, db) end
+
+ local str = db.textDisplay
+ str = string.gsub(str, "%[(%w+)%]", function(w) return tags[w]() end)
+ text:SetFormattedText("|cff%s%s|r", SLDT.db.profile.cCol and SLDT.classColor or "ffffff", str)
+
+ SLDT:UpdateBaseFrame(self, db)
+ else
+ if ( frame:IsShown() and not SLDataText.db.profile.configMode ) then frame:Hide() end
+ end
+end
+
+SLDT.FPS.optsTbl = {
+ [1] = { [1] = "toggle", [2] = L["Enabled"], [3] = "enabled" },
+ [2] = { [1] = "toggle", [2] = L["Global Font"], [3] = "gfont" },
+ [3] = { [1] = "toggle", [2] = L["Outline"], [3] = "outline" },
+ [4] = { [1] = "toggle", [2] = L["Force Shown"], [3] = "forceShow" },
+ [5] = { [1] = "text", [2] = L["Text Display"], [3] = "textDisplay" },
+ [6] = { [1] = "desc", [2] = "FPSTextDesc", [3] = L["FPSTextDesc"] },
+ [7] = { [1] = "range", [2] = L["Update Interval"], [3] = "interval", [4] = 10, [5] = 1000, [6] = 10 },
+ [8] = { [1] = "range", [2] = L["Font Size"], [3] = "fontSize", [4] = 6, [5] = 40, [6] = 1 },
+ [9] = { [1] = "select", [2] = L["Font"], [3] = "font", [4] = SLDT.fontTbl },
+ [10] = { [1] = "select", [2] = L["Justify"], [3] = "aP", [4] = SLDT.justTbl },
+ [11] = { [1] = "text", [2] = L["Parent"], [3] = "anch" },
+ [12] = { [1] = "select", [2] = L["Anchor"], [3] = "aF", [4] = SLDT.anchTbl },
+ [13] = { [1] = "text", [2] = L["X Offset"], [3] = "xOff" },
+ [14] = { [1] = "text", [2] = L["Y Offset"], [3] = "yOff" },
+ [15] = { [1] = "select", [2] = L["Frame Strata"], [3] = "strata", [4] = SLDT.stratTbl },
+}
+
+local function OnInit()
+ SLDT.FPS.db = SLDT.db:RegisterNamespace(MODNAME)
+ SLDT.FPS.db:RegisterDefaults({
+ profile = {
+ name = "FPS",
+ enabled = true,
+ forceShow = false,
+ aP = "CENTER",
+ anch = "UIParent",
+ aF = "BOTTOMLEFT",
+ xOff = 517,
+ yOff = 7,
+ strata = "LOW",
+ gfont = false,
+ fontSize = 14,
+ font = "Arial Narrow",
+ outline = false,
+ interval = 10,
+ tooltipOn = false,
+ textDisplay = "[F] fps",
+ },
+ })
+ db = SLDT.FPS.db.profile
+
+ SLDT.Modules = SLDT.Modules or {}
+ if ( not SLDT.Modules[MODNAME] ) then table.insert(SLDT.Modules, { MODNAME, db }) end
+ frame, text, tool = SLDT:SetupBaseFrame(SLDT.FPS)
+
+ SLDT.FPS:UnregisterEvent("PLAYER_ENTERING_WORLD")
+ SLDT.FPS:Enable()
+end
+
+SLDT.FPS:RegisterEvent("PLAYER_ENTERING_WORLD")
+SLDT.FPS:SetScript("OnEvent", OnInit)
\ No newline at end of file
diff --git a/Elements/friends.lua b/Elements/friends.lua
new file mode 100644
index 0000000..73e41df
--- /dev/null
+++ b/Elements/friends.lua
@@ -0,0 +1,193 @@
+--[[ SLDataText Module: Friends ]]
+--[[ Author: Taffu RevDate: 08/02/2018 Version: 8.0.2 ]]
+
+-- Updated by Suicidal Katt
+-- Fixed an issue with on click functions not closing the tooltip.
+-- "InviteUnit" function calls need to be redone.
+
+
+local addon, ns = ...
+local SLDT, MODNAME, SLT, L = SLDataText, "Friends", LibStub("LibSLTip-1.0"), ns.L
+if ( SLDT ) then SLDT.Friends = CreateFrame("Frame") end
+local db, frame, text, tool, tip
+local friendList, BNetList, friendsOn = {}, {}, 0
+
+local function SetupToolTip()
+ tool:SetScript("OnEnter", function(this)
+ tip = SLT:GetTooltip("SLDT_Friends", true)
+ SLT:AddHeader("SLDT_Friends", L["Friend List"], string.format("%s: %i", L["Friends Online"], friendsOn))
+ for k, v in pairs(friendList) do
+ local name, lvl, class, area, status, note = v[1], v[2], v[3], v[4], v[5], v[6]
+ --NOTE: Editing this out until Blizz lets classFileName become available @ Friend API level
+ --if ( class and class == "Death Knight" ) then class = "DEATHKNIGHT" else class = string.upper(class) end
+ --local cCol = string.format("%02X%02X%02X", RAID_CLASS_COLORS[class].r*255, RAID_CLASS_COLORS[class].g*255, RAID_CLASS_COLORS[class].b*255)
+ local lineL = string.format("%s %s %s", lvl, name, status or "")
+ local lineR = string.format("%s", area or "")
+
+ local buttonFunc = function(self, button)
+ if ( IsAltKeyDown() ) then
+ InviteUnit(name)
+ else
+ SetItemRef("player:"..name, "|Hplayer:"..name.."|h["..name.."|h", "LeftButton")
+ end
+ SLT:ClearTooltip("SLDT_Friends")
+ end
+
+ SLT:AddDoubleLine("SLDT_Friends", lineL, lineR, nil, nil, true, buttonFunc)
+ if ( note and db.showNote ) then
+ local noteLine = string.format(" - %s: %s", L["Note"], note)
+ SLT:AddLine("SLDT_Friends", noteLine, nil)
+ end
+ end
+
+ if ( select("#", BNetList) >= 1 and select("#", friendList) >= 1 ) then
+ SLT:AddLine("SLDT_Friends", L["BNet Friends"])
+ SLT:AddSpacer("SLDT_Friends")
+ end
+
+ if ( BNetList and select("#", BNetList) >= 1 ) then
+ for k, v in pairs(BNetList) do
+ local BNid, BNname, battleTag, toonname, client, status, broadcast, note = v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8]
+
+ local lineL = string.format("|cffecd672%s|r", BNname, battleTag, toonname)
+ local lineR = string.format("%s%s", status or "", client or "")
+
+ local buttonFunc = function(self, button)
+ if ( IsAltKeyDown() ) then
+ if ( client == "WoW" ) then InviteUnit(toonname) end
+ else
+ local nameLine = string.format("%s : %s", BNname, BNid)
+ SetItemRef("BNplayer:"..nameLine, "|Hplayer:"..nameLine.."|h["..nameLine.."|h", "LeftButton")
+ end
+ SLT:ClearTooltip("SLDT_Friends")
+ end
+
+ SLT:AddDoubleLine("SLDT_Friends", lineL, lineR, nil, nil, true, buttonFunc)
+ if ( note and db.showNote ) then
+ local noteLine = string.format(" - Note: %s", note)
+ SLT:AddLine("SLDT_Friends", noteLine, nil)
+ end
+ end
+ end
+
+ SLT:AddFooter("SLDT_Friends", L["ClickDesc"], nil)
+ SLT:AddFooter("SLDT_Friends", L["AltClickDesc"], nil)
+ if ( friendsOn > 0 and not InCombatLockdown() ) then SLT:ShowTooltip("SLDT_Friends", frame) end
+ end)
+ tool:SetScript("OnLeave", function(this) SLT:ClearTooltip("SLDT_Friends") end)
+ tool:SetScript("OnMouseDown", function(this, button)
+ ToggleFriendsFrame(1)
+ end)
+end
+
+function SLDT.Friends:Enable()
+ if ( db.enabled ) then
+ self:RegisterEvent("FRIENDLIST_UPDATE")
+ self:RegisterEvent("BN_FRIEND_ACCOUNT_ONLINE")
+ self:RegisterEvent("BN_FRIEND_ACCOUNT_OFFLINE")
+ self:SetScript("OnEvent", function() self:Refresh() end)
+ end
+ self:Refresh()
+end
+
+function SLDT.Friends:Disable()
+ if ( not db.enabled ) then
+ self:UnregisterEvent("FRIENDLIST_UPDATE")
+ self:UnregisterEvent("BN_FRIEND_ACCOUNT_ONLINE")
+ self:UnregisterEvent("BN_FRIEND_ACCOUNT_OFFLINE")
+ end
+ self:Refresh()
+end
+
+function SLDT.Friends:Refresh()
+ if ( db.enabled or SLDataText.db.profile.configMode ) then
+ if ( not self.firstRun ) then self.firstRun = true; SLDT:UpdateBaseText(self, db) end
+
+ friendList, BNetList, friendsOn = {}, {}, 0
+ for i = 1, C_FriendList.GetNumFriends() do
+ local name, lvl, class, area, online, status, note = C_FriendList.GetFriendInfoByIndex(i)
+ if ( online ) then
+ friendsOn = friendsOn + 1
+ friendList = friendList or {}
+ table.insert(friendList, { name, lvl, class, area, status, note })
+ end
+ end
+
+ for j = 1, BNGetNumFriends() do
+ local friendAccountInfo = C_BattleNet.GetFriendAccountInfo(j)
+ local battleTag = friendAccountInfo.battleTag
+
+ if (friendAccountInfo.gameAccountInfo.isOnline) then
+ -- local _,name, _, realmName, _, faction, race, class, guild, area, lvl = BNGetToonInfo(toonid)
+ friendsOn = friendsOn + 1
+ if (not battleTag) then battleTag = "[noTag]" end
+ friendList = friendList or {}
+ local status = ""
+ if (friendAccountInfo.isAFK) then status = L["(AFK)"] end; if ( friendAccountInfo.isDND ) then status = L["(DND)"] end
+ -- table.insert(BNetList, { BNid, BNname, battleTag, toonname, client, status, broadcast, note })
+ table.insert(BNetList, { friendAccountInfo.bnetAccountID, friendAccountInfo.accountName, battleTag, friendAccountInfo.gameAccountInfo.characterName, friendAccountInfo.gameAccountInfo.clientProgram, status, friendAccountInfo.customMessage, friendAccountInfo.note })
+ end
+ end
+
+ local txstr = string.format("|T%s:0|t ", "Interface\\Icons\\Inv_cask_04")
+ text:SetFormattedText("%s|cff%s%s:|r %s", db.showIcon and txstr or "", SLDT.db.profile.cCol and SLDT.classColor or "ffffff", L["Friends"], friendsOn)
+ SLDT:UpdateBaseFrame(self, db)
+ else
+ if ( frame:IsShown() and not SLDataText.db.profile.configMode ) then frame:Hide() end
+ end
+end
+
+SLDT.Friends.optsTbl = {
+ [1] = { [1] = "toggle", [2] = L["Enabled"], [3] = "enabled" },
+ [2] = { [1] = "toggle", [2] = L["Global Font"], [3] = "gfont" },
+ [3] = { [1] = "toggle", [2] = L["Outline"], [3] = "outline" },
+ [4] = { [1] = "toggle", [2] = L["Force Shown"], [3] = "forceShow" },
+ [5] = { [1] = "toggle", [2] = L["Tooltip On"], [3] = "tooltipOn" },
+ [6] = { [1] = "toggle", [2] = L["Show Icon"], [3] = "showIcon" },
+ [7] = { [1] = "toggle", [2] = L["Show Note"], [3] = "showNote" },
+ [8] = { [1] = "range", [2] = L["Font Size"], [3] = "fontSize", [4] = 6, [5] = 40, [6] = 1 },
+ [9] = { [1] = "select", [2] = L["Font"], [3] = "font", [4] = SLDT.fontTbl },
+ [10] = { [1] = "select", [2] = L["Justify"], [3] = "aP", [4] = SLDT.justTbl },
+ [11] = { [1] = "text", [2] = L["Parent"], [3] = "anch" },
+ [12] = { [1] = "select", [2] = L["Anchor"], [3] = "aF", [4] = SLDT.anchTbl },
+ [13] = { [1] = "text", [2] = L["X Offset"], [3] = "xOff" },
+ [14] = { [1] = "text", [2] = L["Y Offset"], [3] = "yOff" },
+ [15] = { [1] = "select", [2] = L["Frame Strata"], [3] = "strata", [4] = SLDT.stratTbl },
+}
+
+local function OnInit()
+ SLDT.Friends.db = SLDT.db:RegisterNamespace(MODNAME)
+ SLDT.Friends.db:RegisterDefaults({
+ profile = {
+ name = "Friends",
+ enabled = true,
+ showNote = false,
+ aP = "CENTER",
+ anch = "UIParent",
+ aF = "BOTTOMLEFT",
+ xOff = 189,
+ yOff = 7,
+ strata = "LOW",
+ gfont = false,
+ fontSize = 14,
+ font = "Arial Narrow",
+ outline = false,
+ tooltipOn = true,
+ forceShow = false,
+ showIcon = true,
+ },
+ })
+ db = SLDT.Friends.db.profile
+
+ SLDT:AddModule(MODNAME, db)
+ frame, text, tool = SLDT:SetupBaseFrame(SLDT.Friends)
+ SetupToolTip()
+
+ SLDT.Friends:UnregisterEvent("PLAYER_ENTERING_WORLD")
+ SLDT.Friends:Enable()
+end
+
+if ( IsAddOnLoaded("SLDataText") ) then
+ SLDT.Friends:RegisterEvent("PLAYER_ENTERING_WORLD")
+ SLDT.Friends:SetScript("OnEvent", OnInit)
+end
\ No newline at end of file
diff --git a/Elements/gold.lua b/Elements/gold.lua
new file mode 100644
index 0000000..91fffe1
--- /dev/null
+++ b/Elements/gold.lua
@@ -0,0 +1,220 @@
+--[[ SLDataText Module: Gold ]]
+--[[ Author: Taffu RevDate: 01/21/2018 Version: 7.3.1 ]]
+
+local SLDT, MODNAME = SLDataText, "Gold"
+if ( SLDT ) then SLDT.Gold = CreateFrame("Frame") end
+local L = SLDT.Locale
+local db, realmDB, frame, text, tool
+
+local goldStart, goldEarned, loggedOn, curGold = 0, 0, true, 0
+local function convertMoney(moolah, display)
+ local g, s, c = abs(moolah/10000), abs(mod(moolah/100, 100)), abs(mod(moolah, 100))
+ local cash
+ if ( display ) then -- True = Long display
+ if ( g < 1 ) then g = "" else g = string.format("%d|cffffd700g|r ", g) end
+ if ( s < 1 ) then s = "" else s = string.format("%d|cffc7c7cfs|r ", s) end
+ c = string.format("%d|cffeda55fc|r", c)
+ cash = string.format("%s%s%s", g, s, c)
+ else
+ cash = string.format("%.1f|cffffd700g|r", g)
+ end
+ return cash
+end
+
+local function otherFaction(f)
+ if ( f == "Horde" ) then return "Alliance" else return "Horde" end
+end
+
+local function SetupToolTip()
+ tool:SetScript("OnEnter", function(this)
+ GameTooltip:SetOwner(this, db.aF)
+ local current, sessStart, sessEarn = convertMoney(curGold, true), convertMoney(goldStart, true), convertMoney(goldEarned, true)
+ GameTooltip:AddLine(string.format("|cffffffff%s's "..L["Wallet"].."|r", UnitName("player")))
+ GameTooltip:AddDoubleLine(L["Current"], current, 1,1,0,1,1,1)
+ GameTooltip:AddDoubleLine(L["Session Start"], sessStart, 1,1,0,1,1,1)
+ if ( curGold < goldStart ) then sessEarn = string.format("|cffffff00-(|r%s|cffffff00)|r", sessEarn) end
+ GameTooltip:AddDoubleLine(L["Session Earned"], sessEarn, 1,1,0,1,1,1)
+
+ if ( db.altMoney ) then
+ local lined = false
+ for key, val in pairs(realmDB["Horde"]) do
+ if ( key ~= UnitName("player") ) then
+ if ( not lined ) then
+ GameTooltip:AddLine(" ")
+ GameTooltip:AddLine("|cffffff00"..L["Server Gold"].."|r")
+ GameTooltip:AddLine("-------------------------", 1, 1, 1)
+ GameTooltip:AddLine("|cffff0000"..L["Horde"].."|r")
+ lined = true
+ end
+
+ local name, gold = key, 0
+ for k, v in pairs(val) do
+ gold = v
+ end
+ GameTooltip:AddDoubleLine(name, convertMoney(gold, true), 1, 1, 1, 1, 1, 1)
+ end
+ end
+ local lined = false
+ for key, val in pairs(realmDB["Alliance"]) do
+ if ( key ~= UnitName("player") ) then
+ if ( not lined ) then
+ GameTooltip:AddLine(" ")
+ GameTooltip:AddLine("|cff0000ff"..L["Alliance"].."|r")
+ lined = true
+ end
+
+ local name, gold = key, 0
+ for k, v in pairs(val) do
+ gold = v
+ end
+ GameTooltip:AddDoubleLine(name, convertMoney(gold, true), 1, 1, 1, 1, 1, 1)
+ end
+ end
+
+ local totalGold = 0
+ local totalGoldH = 0
+ local totalGoldA = 0
+ for key, val in pairs(realmDB["Horde"]) do
+ for k, v in pairs(val) do
+ totalGold = totalGold + v
+ totalGoldH =totalGoldH + v
+ end
+ end
+ for key, val in pairs(realmDB["Alliance"]) do
+ for k, v in pairs(val) do
+ totalGold = totalGold + v
+ totalGoldA = totalGoldA +v
+ end
+ end
+ if ( totalGold > 0 ) then
+ GameTooltip:AddLine(" ")
+ GameTooltip:AddLine("-------------------------", 1, 1, 1)
+ GameTooltip:AddDoubleLine(L["Total Gold"], convertMoney(totalGold, true), 1, 1, 1, 1, 1, 1)
+ if( totalGoldH > 0 and totalGoldA > 0) then
+ GameTooltip:AddDoubleLine(L["Total Gold"].." |cffff0000"..L["Horde"].."|r", convertMoney(totalGoldH, true), 1, 1, 1, 1, 1, 1)
+ GameTooltip:AddDoubleLine(L["Total Gold"].." |cff0000ff"..L["Alliance"].."|r", convertMoney(totalGoldA, true), 1, 1, 1, 1, 1, 1)
+ end
+ end
+ end
+
+ GameTooltip:Show()
+ end)
+ tool:SetScript("OnLeave", function(this) if ( GameTooltip:IsShown() ) then GameTooltip:Hide() end end)
+end
+
+function SLDT.Gold:Enable()
+ if ( db.enabled ) then
+ SLDT:UpdateBaseText(self, db)
+ self:RegisterEvent("PLAYER_MONEY")
+ self:RegisterEvent("SEND_MAIL_MONEY_CHANGED")
+ self:RegisterEvent("SEND_MAIL_COD_CHANGED")
+ self:RegisterEvent("PLAYER_TRADE_MONEY")
+ self:RegisterEvent("TRADE_MONEY_CHANGED")
+ self:SetScript("OnEvent", function(self, event) self:Refresh() end)
+ end
+ self:Refresh()
+end
+
+function SLDT.Gold:Disable()
+ if ( not db.enabled ) then
+ self:UnregisterEvent("PLAYER_MONEY")
+ self:UnregisterEvent("SEND_MAIL_MONEY_CHANGED")
+ self:UnregisterEvent("SEND_MAIL_COD_CHANGED")
+ self:UnregisterEvent("PLAYER_TRADE_MONEY")
+ self:UnregisterEvent("TRADE_MONEY_CHANGED")
+ self:SetScript("OnEvent", nil)
+ end
+ self:Refresh()
+end
+
+function SLDT.Gold:Refresh()
+ if ( db.enabled or SLDataText.db.profile.configMode ) then
+ if ( not self.firstRun ) then self.firstRun = true; SLDT:UpdateBaseText(self, db) end
+
+ curGold = GetMoney()
+ realmDB[UnitFactionGroup("player")][UnitName("player")].gold = curGold
+
+ local moneyTxt = convertMoney(curGold, db.display)
+ if ( loggedOn ) then
+ goldStart = curGold; loggedOn = false
+ else
+ if ( curGold - goldStart ~= 0 ) then goldEarned = curGold - goldStart end
+ end
+ text:SetText(moneyTxt)
+
+ SLDT:UpdateBaseFrame(SLDT.Gold, db)
+ else
+ if ( frame:IsShown() and not SLDataText.db.profile.configMode ) then frame:Hide() end
+ end
+end
+
+local resetPlayerData = function()
+ for k, v in pairs(realmDB[UnitFactionGroup("player")]) do
+ realmDB[UnitFactionGroup("player")][k] = nil
+ end
+end
+
+SLDT.Gold.optsTbl = {
+ [1] = { [1] = "toggle", [2] = L["Enabled"], [3] = "enabled" },
+ [2] = { [1] = "toggle", [2] = L["Global Font"], [3] = "gfont" },
+ [3] = { [1] = "toggle", [2] = L["Outline"], [3] = "outline" },
+ [4] = { [1] = "toggle", [2] = L["Force Shown"], [3] = "forceShow" },
+ [5] = { [1] = "toggle", [2] = L["Tooltip On"], [3] = "tooltipOn" },
+ [6] = { [1] = "toggle", [2] = L["Display Style"], [3] = "display" },
+ [7] = { [1] = "toggle", [2] = L["Alt Money"], [3] = "altMoney" },
+ [8] = { [1] = "range", [2] = L["Font Size"], [3] = "fontSize", [4] = 6, [5] = 40, [6] = 1 },
+ [9] = { [1] = "select", [2] = L["Font"], [3] = "font", [4] = SLDT.fontTbl },
+ [10] = { [1] = "select", [2] = L["Justify"], [3] = "aP", [4] = SLDT.justTbl },
+ [11] = { [1] = "text", [2] = L["Parent"], [3] = "anch" },
+ [12] = { [1] = "select", [2] = L["Anchor"], [3] = "aF", [4] = SLDT.anchTbl },
+ [13] = { [1] = "text", [2] = L["X Offset"], [3] = "xOff" },
+ [14] = { [1] = "text", [2] = L["Y Offset"], [3] = "yOff" },
+ [15] = { [1] = "select", [2] = L["Frame Strata"], [3] = "strata", [4] = SLDT.stratTbl },
+ [16] = { [1] = "button", [2] = L["ResetData"], [3] = resetPlayerData },
+}
+
+local function OnInit()
+ SLDT.Gold.db = SLDT.db:RegisterNamespace(MODNAME)
+ SLDT.Gold.db:RegisterDefaults({
+ profile = {
+ name = "Gold",
+ enabled = true,
+ display = false,
+ forceShow = false,
+ altMoney = true,
+ aP = "CENTER",
+ anch = "UIParent",
+ aF = "BOTTOMLEFT",
+ xOff = 282,
+ yOff = 7,
+ strata = "LOW",
+ gfont = false,
+ fontSize = 14,
+ font = "Arial Narrow",
+ outline = false,
+ tooltipOn = true,
+ },
+ realm = {
+ [UnitFactionGroup("player")] = {
+ [UnitName("player")] = {
+ gold = 0,
+ },
+ },
+ [otherFaction(UnitFactionGroup("player"))] = {
+ },
+ },
+ })
+ db = SLDT.Gold.db.profile
+ realmDB = SLDT.Gold.db.realm
+
+ SLDT.Modules = SLDT.Modules or {}
+ if ( not SLDT.Modules[MODNAME] ) then table.insert(SLDT.Modules, { MODNAME, db }) end
+ frame, text, tool = SLDT:SetupBaseFrame(SLDT.Gold)
+ SetupToolTip()
+
+ SLDT.Gold:UnregisterEvent("PLAYER_ENTERING_WORLD")
+ SLDT.Gold:Enable()
+end
+
+SLDT.Gold:RegisterEvent("PLAYER_ENTERING_WORLD")
+SLDT.Gold:SetScript("OnEvent", OnInit)
\ No newline at end of file
diff --git a/Elements/guild.lua b/Elements/guild.lua
new file mode 100644
index 0000000..39e7a3c
--- /dev/null
+++ b/Elements/guild.lua
@@ -0,0 +1,198 @@
+ --[[ SLDataText Module: Guild ]]
+--[[ Author: Taffu RevDate: 08/02/2018 Version: 8.0.2 ]]
+
+-- Updated by Suicidal Katt
+-- Class coloring returns in this version.
+-- Player names are now using the Ambiguate function to remove realm info.
+-- Guild Level now replaced with Guild Achievement Points as level was removed in patch 6.0.2
+-- Guild Tab reference has been removed - 8.0.2
+
+local addon, ns = ...
+local SLDT, MODNAME, SLT, L = SLDataText, "Guild", LibStub("LibSLTip-1.0"), ns.L
+if ( SLDT ) then SLDT.Guild = CreateFrame("Frame") end
+local db, frame, text, tool, tip
+local guildName, guildMotto, guildRank, guildPoints, guildList
+
+local function SetupToolTip()
+ if ( not IsInGuild() ) then return end
+ tool:SetScript("OnEnter", function(this)
+ C_GuildInfo.GuildRoster()
+ SLDT.Guild:Refresh()
+ tip = SLT:GetTooltip("SLDT_Guild", true)
+ SLT:AddHeader("SLDT_Guild", string.format("%s (%s)", guildName or L["No Guild"], guildPoints or ""), guildMotto)
+ if select(2, GetNumGuildMembers()) >= 2 then
+ for key, val in pairs(guildList) do
+ local name, rank, level, class, zone, status, isMobile, note, oNote = val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8], val[9]
+
+ if ( name ~= UnitName("player") ) then
+ local cCol = string.format("%02X%02X%02X", RAID_CLASS_COLORS[class].r*255, RAID_CLASS_COLORS[class].g*255, RAID_CLASS_COLORS[class].b*255)
+ local lineL = string.format("%s |cff%s%s|r %s", level, cCol, name, status or "")
+ local lineR = string.format("%s%s", isMobile and "|cffffff00[M]|r " or "", zone or "")
+
+ local buttonFunc = function(self, button)
+ if ( IsAltKeyDown() ) then
+ InviteUnit(name)
+ else
+ SetItemRef("player:"..name, "|Hplayer:"..name.."|h["..name.."|h", "LeftButton")
+ end
+ end
+
+ SLT:AddDoubleLine("SLDT_Guild", lineL, lineR, nil, nil, true, buttonFunc)
+ if ( note and note ~= "" and db.showNote ) then
+ local noteLine = string.format(" - Note: %s", note)
+ SLT:AddLine("SLDT_Guild", noteLine, nil)
+ end
+ if ( oNote and oNote ~= "" and db.showONote ) then
+ local noteLine = string.format(" - Officer: %s", oNote)
+ SLT:AddLine("SLDT_Guild", noteLine, nil)
+ end
+ else
+
+ end
+ end
+ end
+
+ SLT:AddFooter("SLDT_Guild", L["ClickDesc"], nil)
+ SLT:AddFooter("SLDT_Guild", L["AltClickDesc"], nil)
+
+ if ( not db.showTTCombat and select(2, GetNumGuildMembers()) > 1 ) then
+ if ( not InCombatLockdown() ) then SLT:ShowTooltip("SLDT_Guild", frame) end
+ else
+ SLT:ShowTooltip("SLDT_Guild", frame)
+ end
+ end)
+ tool:SetScript("OnLeave", function(this) SLT:ClearTooltip("SLDT_Guild") end)
+ tool:SetScript("OnMouseDown", function(this, button)
+ ToggleGuildFrame()
+ --[[if ( IsInGuild() ) then
+ GuildFrameTab2:Click()
+ end]]--
+ end)
+end
+
+local int = 10
+function SLDT.Guild:RefreshTimer()
+ self:SetScript("OnUpdate", function(self, elapsed)
+ int = int - elapsed
+ if ( int <= 0 ) then
+ int = 10; self:Refresh()
+ self:SetScript("OnUpdate", nil)
+ end
+ end)
+end
+
+function SLDT.Guild:Enable()
+ if ( db.enabled ) then
+ self:RegisterEvent("GUILD_ROSTER_UPDATE")
+ self:RegisterEvent("GUILD_TRADESKILL_UPDATE")
+ self:RegisterEvent("GUILD_MOTD")
+ self:RegisterEvent("GUILD_NEWS_UPDATE")
+ self:RegisterEvent("PLAYER_GUILD_UPDATE")
+ end
+ self:Refresh()
+end
+
+function SLDT.Guild:Disable()
+ if ( not db.enabled ) then
+ self:UnregisterEvent("GUILD_ROSTER_UPDATE")
+ self:UnregisterEvent("GUILD_TRADESKILL_UPDATE")
+ self:UnregisterEvent("GUILD_MOTD")
+ self:UnregisterEvent("GUILD_NEWS_UPDATE")
+ self:UnregisterEvent("PLAYER_GUILD_UPDATE")
+ end
+ self:Refresh()
+end
+
+function SLDT.Guild:Refresh()
+ if ( db.enabled or SLDataText.db.profile.configMode ) then
+ if ( not self.firstRun ) then self.firstRun = true; SLDT:UpdateBaseText(self, db) end
+
+ if ( IsInGuild() ) then
+ guildList = {}
+ guildName, guildRank, _ = GetGuildInfo("player")
+ guildMotto, guildPoints = GetGuildRosterMOTD(), GetTotalAchievementPoints(true)
+
+ for i = 0, select(1, GetNumGuildMembers()) do
+ local name, rank, rankIndex, level, class, zone, note, officernote, online, status, classFileName, achievementPoints, achievementRank, isMobile, canSoR = GetGuildRosterInfo(i)
+ if ( online ) then
+ if ( status ~= nil and status == 0 ) then status = nil else status = L["(AFK)"] end
+ table.insert(guildList, { Ambiguate(name, "guild"), rank, level, classFileName, zone, status, isMobile, note, officernote })
+ end
+ end
+
+ local txstr
+ if ( UnitFactionGroup("player") == "Alliance" ) then
+ txstr = string.format("|T%s:0|t ", "Interface\\Icons\\Inv_bannerpvp_02")
+ else
+ txstr = string.format("|T%s:0|t ", "Interface\\Icons\\Inv_bannerpvp_01")
+ end
+ text:SetFormattedText("%s|cff%s%s:|r %s", db.showIcon and txstr or "", SLDT.db.profile.cCol and SLDT.classColor or "ffffff", L["Guild"], select(2, GetNumGuildMembers()))
+ else
+ text:SetText(L["No Guild"])
+ end
+
+ SLDT:UpdateBaseFrame(SLDT.Guild, db)
+ else
+ if ( frame:IsShown() and not SLDataText.db.profile.configMode ) then frame:Hide() end
+ end
+end
+
+SLDT.Guild.optsTbl = {
+ [1] = { [1] = "toggle", [2] = L["Enabled"], [3] = "enabled" },
+ [2] = { [1] = "toggle", [2] = L["Global Font"], [3] = "gfont" },
+ [3] = { [1] = "toggle", [2] = L["Outline"], [3] = "outline" },
+ [4] = { [1] = "toggle", [2] = L["Force Shown"], [3] = "forceShow" },
+ [5] = { [1] = "toggle", [2] = L["Tooltip On"], [3] = "tooltipOn" },
+ [6] = { [1] = "toggle", [2] = L["Show Tooltip (Combat)"], [3] = "showTTCombat" },
+ [7] = { [1] = "toggle", [2] = L["Show Icon"], [3] = "showIcon" },
+ [8] = { [1] = "toggle", [2] = L["Show Note"], [3] = "showNote" },
+ [9] = { [1] = "toggle", [2] = L["Show Officer Note"], [3] = "showONote" },
+ [10] = { [1] = "range", [2] = L["Font Size"], [3] = "fontSize", [4] = 6, [5] = 40, [6] = 1 },
+ [11] = { [1] = "select", [2] = L["Font"], [3] = "font", [4] = SLDT.fontTbl },
+ [12] = { [1] = "select", [2] = L["Justify"], [3] = "aP", [4] = SLDT.justTbl },
+ [13] = { [1] = "text", [2] = L["Parent"], [3] = "anch" },
+ [14] = { [1] = "select", [2] = L["Anchor"], [3] = "aF", [4] = SLDT.anchTbl },
+ [15] = { [1] = "text", [2] = L["X Offset"], [3] = "xOff" },
+ [16] = { [1] = "text", [2] = L["Y Offset"], [3] = "yOff" },
+ [17] = { [1] = "select", [2] = L["Frame Strata"], [3] = "strata", [4] = SLDT.stratTbl },
+}
+
+local function OnInit()
+ SLDT.Guild.db = SLDT.db:RegisterNamespace(MODNAME)
+ SLDT.Guild.db:RegisterDefaults({
+ profile = {
+ name = "Guild",
+ enabled = true,
+ showNote = false,
+ showONote = false,
+ showTTCombat = false,
+ aP = "CENTER",
+ anch = "UIParent",
+ aF = "BOTTOMLEFT",
+ xOff = 88,
+ yOff = 7,
+ strata = "LOW",
+ gfont = false,
+ fontSize = 14,
+ font = "Arial Narrow",
+ outline = false,
+ tooltipOn = true,
+ forceShow = false,
+ showIcon = true,
+ },
+ })
+ db = SLDT.Guild.db.profile
+
+ SLDT:AddModule(MODNAME, db)
+ frame, text, tool = SLDT:SetupBaseFrame(SLDT.Guild)
+ SetupToolTip()
+
+ SLDT.Guild:UnregisterEvent("PLAYER_ENTERING_WORLD")
+ SLDT.Guild:SetScript("OnEvent", function() SLDT.Guild:Refresh() end)
+ SLDT.Guild:Enable()
+end
+
+if ( IsAddOnLoaded("SLDataText") ) then
+ SLDT.Guild:RegisterEvent("PLAYER_ENTERING_WORLD")
+ SLDT.Guild:SetScript("OnEvent", OnInit)
+end
\ No newline at end of file
diff --git a/Elements/latency.lua b/Elements/latency.lua
new file mode 100644
index 0000000..fa1ca2d
--- /dev/null
+++ b/Elements/latency.lua
@@ -0,0 +1,116 @@
+--[[ SLDataText Module: Latency ]]
+--[[ Author: Taffu RevDate: 01/21/2018 Version: 7.3.1 ]]
+
+local SLDT, MODNAME = SLDataText, "Latency"
+if ( SLDT ) then SLDT.Latency = CreateFrame("Frame") end
+local L = SLDT.Locale
+local db, frame, text, tool
+
+local bandIn, bandOut, lagHome, lagWorld
+local function SetupToolTip()
+ tool:SetScript("OnEnter", function(this)
+ GameTooltip:SetOwner(this, db.aF)
+ GameTooltip:AddLine("|cffffffff"..L["Latency"].."|r")
+ GameTooltip:AddDoubleLine(L["Bandwidth In"], string.format("%.2fkb", bandIn), 1,1,0,1,1,1)
+ GameTooltip:AddDoubleLine(L["Bandwidth Out"], string.format("%.2fkb", bandOut), 1,1,0,1,1,1)
+ GameTooltip:AddDoubleLine(L["Latency (Home)"], string.format("%ims", lagHome), 1,1,0,1,1,1)
+ GameTooltip:AddDoubleLine(L["Latency (World)"], string.format("%ims", lagWorld), 1,1,0,1,1,1)
+ GameTooltip:Show()
+ end)
+ tool:SetScript("OnLeave", function(this) if ( GameTooltip:IsShown() ) then GameTooltip:Hide() end end)
+end
+
+function SLDT.Latency:Enable()
+ if ( db.enabled ) then
+ SLDT:UpdateBaseText(self, db)
+ local int = db.interval
+ frame:SetScript("OnUpdate", function(_, elapsed)
+ int = int - elapsed
+ if ( int <= 0 ) then self:Refresh(); int = db.interval end
+ end)
+ end
+ self:Refresh()
+end
+
+function SLDT.Latency:Disable()
+ if ( not db.enabled ) then
+ frame:SetScript("OnUpdate", nil)
+ end
+ self:Refresh()
+end
+
+local tags = {
+ ["L"] = function()
+ bandIn, bandOut, lagHome, lagWorld = GetNetStats()
+ return string.format("|cffffffff%i|r|cff%s", lagHome, SLDT.db.profile.cCol and SLDT.classColor or "ffffff")
+ end,
+}
+
+function SLDT.Latency:Refresh()
+ if ( db.enabled or SLDataText.db.profile.configMode ) then
+ if ( not self.firstRun ) then self.firstRun = true; SLDT:UpdateBaseText(self, db) end
+
+ local str = db.textDisplay
+ str = string.gsub(str, "%[(%w+)%]", function(w) return tags[w]() end)
+ text:SetFormattedText("|cff%s%s|r", SLDT.db.profile.cCol and SLDT.classColor or "ffffff", str)
+
+ SLDT:UpdateBaseFrame(self, db)
+ else
+ if ( frame:IsShown() and not SLDataText.db.profile.configMode ) then frame:Hide() end
+ end
+end
+
+SLDT.Latency.optsTbl = {
+ [1] = { [1] = "toggle", [2] = L["Enabled"], [3] = "enabled" },
+ [2] = { [1] = "toggle", [2] = L["Global Font"], [3] = "gfont" },
+ [3] = { [1] = "toggle", [2] = L["Outline"], [3] = "outline" },
+ [4] = { [1] = "toggle", [2] = L["Force Shown"], [3] = "forceShow" },
+ [5] = { [1] = "toggle", [2] = L["Tooltip On"], [3] = "tooltipOn" },
+ [6] = { [1] = "text", [2] = L["Text Display"], [3] = "textDisplay" },
+ [7] = { [1] = "desc", [2] = "LagTextDesc", [3] = L["LagTextDesc"] },
+ [8] = { [1] = "range", [2] = L["Update Interval"], [3] = "interval", [4] = 10, [5] = 1000, [6] = 10 },
+ [9] = { [1] = "range", [2] = L["Font Size"], [3] = "fontSize", [4] = 6, [5] = 40, [6] = 1 },
+ [10] = { [1] = "select", [2] = L["Font"], [3] = "font", [4] = SLDT.fontTbl },
+ [11] = { [1] = "select", [2] = L["Justify"], [3] = "aP", [4] = SLDT.justTbl },
+ [12] = { [1] = "text", [2] = L["Parent"], [3] = "anch" },
+ [13] = { [1] = "select", [2] = L["Anchor"], [3] = "aF", [4] = SLDT.anchTbl },
+ [14] = { [1] = "text", [2] = L["X Offset"], [3] = "xOff" },
+ [15] = { [1] = "text", [2] = L["Y Offset"], [3] = "yOff" },
+ [16] = { [1] = "select", [2] = L["Frame Strata"], [3] = "strata", [4] = SLDT.stratTbl },
+}
+
+local function OnInit()
+ SLDT.Latency.db = SLDT.db:RegisterNamespace(MODNAME)
+ SLDT.Latency.db:RegisterDefaults({
+ profile = {
+ name = "Latency",
+ enabled = true,
+ forceShow = false,
+ aP = "CENTER",
+ anch = "UIParent",
+ aF = "BOTTOM",
+ xOff = -498,
+ yOff = 7,
+ strata = "LOW",
+ gfont = false,
+ fontSize = 14,
+ font = "Arial Narrow",
+ outline = false,
+ interval = 10,
+ tooltipOn = true,
+ textDisplay = "[L]ms",
+ },
+ })
+ db = SLDT.Latency.db.profile
+
+ SLDT.Modules = SLDT.Modules or {}
+ if ( not SLDT.Modules[MODNAME] ) then table.insert(SLDT.Modules, { MODNAME, db }) end
+ frame, text, tool = SLDT:SetupBaseFrame(SLDT.Latency)
+ SetupToolTip()
+
+ SLDT.Latency:UnregisterEvent("PLAYER_ENTERING_WORLD")
+ SLDT.Latency:Enable()
+end
+
+SLDT.Latency:RegisterEvent("PLAYER_ENTERING_WORLD")
+SLDT.Latency:SetScript("OnEvent", OnInit)
\ No newline at end of file
diff --git a/Elements/mail.lua b/Elements/mail.lua
new file mode 100644
index 0000000..2603d41
--- /dev/null
+++ b/Elements/mail.lua
@@ -0,0 +1,231 @@
+--[[ SLDataText Module: Mail ]]
+--[[ Author: Taffu RevDate: 08/02/2018 Version: 8.0.2 ]]
+
+-- Updated by Suicidal Katt
+-- Fixed an issue with PlaySound call incorrectly argumented
+-- Removed the "count" value if no mail has been counted.
+
+local SLDT, MODNAME = SLDataText, "Mail"
+if ( SLDT ) then SLDT.Mail = CreateFrame("Frame") end
+local L = SLDT.Locale
+local db, frame, text, tool
+
+local handler = {
+ NOMAILICON = "Interface\\CURSOR\\UnableMail",
+ NEWMAILICON = "Interface\\Icons\\INV_Letter_09",
+ AHICON = "Interface\\Icons\\Ability_Paladin_JudgementofthePure",
+ MAILSOUND = "Interface\\AddOns\\SLDataText\\Media\\mail.mp3",
+ AHSOUND = 5274,
+ new = 0,
+ total = 0,
+ lastClose = 0,
+ ignoreNext = false,
+ mailChecked = false,
+ iconString = "|TInterface\\CURSOR\\UnableMail:0|t",
+ textString = L["No Mail"],
+}
+
+local function SetupToolTip()
+ tool:SetScript("OnEnter", function(this)
+ if ( not HasNewMail() ) then return end
+ GameTooltip:SetOwner(this, db.aF)
+ MinimapMailFrameUpdate()
+ GameTooltip:Show()
+ end)
+ tool:SetScript("OnLeave", function(this) if ( GameTooltip:IsVisible() ) then GameTooltip:Hide() end end)
+end
+
+local function UpdateDisplay()
+ if ( MiniMapMailFrame:IsVisible() ) then MiniMapMailFrame:Hide() end
+
+ if ( db["ahAlert"] ) then
+ -- Change icon to AHAlert icon
+ handler.iconString = string.format("|T%s:0|t", handler.AHICON)
+ handler.textString = L["AH Alert!"]
+ elseif ( db["total"] and db["total"] > 0 ) or ( HasNewMail() and not handler.mailChecked ) then
+ -- Change icon to Mail icon
+ handler.iconString = string.format("|T%s:0|t", handler.NEWMAILICON)
+ handler.textString = L["Mail!"]
+ else
+ -- Change icon to No Mail icon
+ handler.iconString = string.format("|T%s:0|t", handler.NOMAILICON)
+ handler.textString = L["No Mail"]
+ end
+end
+
+local function IncomingMail()
+ if ( handler.ignoreNext ) then
+ handler.ignoreNext = false
+ else
+ handler.new = 0
+ if ( db["new"] ~= nil ) then
+ handler.new = db["new"] + (1 * .5)
+ end
+
+ handler.total = 0
+ if ( db["total"] ~= nil ) then
+ handler.total = db["total"] + .5
+ end
+
+ if ( handler.mailChecked ) then
+ handler.total = GetInboxNumItems() + handler.new
+ end
+
+ db["new"] = handler.new
+ db["total"] = handler.total
+
+ if ( db.playSounds ) then PlaySoundFile(handler.MAILSOUND) end
+ end
+end
+
+local function ReadMsg(msg)
+ local ahEvents = {
+ [ERR_AUCTION_WON_S] = false,
+ [ERR_AUCTION_SOLD_S] = false,
+ [ERR_AUCTION_OUTBID_S] = true,
+ [ERR_AUCTION_EXPIRED_S] = false,
+ [ERR_AUCTION_REMOVED_S] = false,
+ }
+
+ for k, _ in pairs(ahEvents) do
+ local search = string.gsub(k, "%%[^%s]+", "(.+)")
+ local _, _, item = string.find(msg, search)
+
+ if ( item ) then
+ db["ahAlert"] = true
+
+ if ( ahEvents[k[1]] ) then
+ IncomingMail()
+ end
+
+ PlaySound(handler.AHSOUND)
+ end
+ end
+end
+
+function SLDT.Mail:Enable()
+ if ( db.enabled ) then
+ SLDT:UpdateBaseText(self, db)
+ self:RegisterEvent("PLAYER_ENTERING_WORLD")
+ self:RegisterEvent("UPDATE_PENDING_MAIL")
+ self:RegisterEvent("MAIL_INBOX_UPDATE")
+ self:RegisterEvent("CHAT_MSG_SYSTEM")
+ self:RegisterEvent("MAIL_SHOW")
+ self:RegisterEvent("MAIL_CLOSED")
+ self:SetScript("OnEvent", function(self, event, ...)
+ if ( event == "PLAYER_ENTERING_WORLD" ) then
+ handler.ignoreNext = true
+ elseif ( event == "CHAT_MSG_SYSTEM" ) then
+ local arg = ...
+ ReadMsg(arg)
+ elseif ( event == "UPDATE_PENDING_MAIL" ) then
+ if ( (handler.lastClose + 5) > time() ) then
+ handler.ignoreNext = true
+ end
+ IncomingMail()
+ UpdateDisplay()
+ elseif ( event == "MAIL_INBOX_UPDATE" ) then
+ db["new"], db["total"] = 0, GetInboxNumItems()
+ UpdateDisplay()
+ elseif ( event == "MAIL_SHOW" ) then
+ handler.mailChecked = true
+ db["ahAlert"] = false
+ UpdateDisplay()
+ elseif ( event == "MAIL_CLOSED" ) then
+ handler.lastClose = time()
+ end
+ self:Refresh()
+ end)
+ end
+ handler.ignoreNext = true
+ self:Refresh()
+end
+
+function SLDT.Mail:Disable()
+ if ( not db.enabled ) then
+ self:UnregisterEvent("UPDATE_PENDING_MAIL")
+ self:UnregisterEvent("MAIL_INBOX_UPDATE")
+ self:UnregisterEvent("CHAT_MSG_SYSTEM")
+ self:UnregisterEvent("MAIL_SHOW")
+ self:UnregisterEvent("MAIL_CLOSED")
+ self:SetScript("OnEvent", nil)
+ end
+ self:Refresh()
+end
+
+function SLDT.Mail:Refresh()
+ if ( db.enabled or SLDataText.db.profile.configMode ) then
+ if ( not self.firstRun ) then self.firstRun = true; SLDT:UpdateBaseText(self, db) end
+
+ local count = ""
+ if ( db["total"] and db["total"] > 0 ) then
+ count = string.format("%u/%u", db["new"], db["total"])
+ elseif ( HasNewMail() and not handler.mailChecked ) then
+ count = "" --L["Mail!"]
+ end
+
+ text:SetFormattedText("%s%s%s", db.showIcon and handler.iconString.." " or "", db.showText and handler.textString.." " or "", count)
+ SLDT:UpdateBaseFrame(self, db)
+ else
+ if ( frame:IsVisible() and not SLDataText.db.profile.configMode ) then frame:Hide() end
+ end
+end
+
+SLDT.Mail.optsTbl = {
+ [1] = { [1] = "toggle", [2] = L["Enabled"], [3] = "enabled" },
+ [2] = { [1] = "toggle", [2] = L["Global Font"], [3] = "gfont" },
+ [3] = { [1] = "toggle", [2] = L["Outline"], [3] = "outline" },
+ [4] = { [1] = "toggle", [2] = L["Force Shown"], [3] = "forceShow" },
+ [5] = { [1] = "toggle", [2] = L["Tooltip On"], [3] = "tooltipOn" },
+ [6] = { [1] = "toggle", [2] = L["Show Icon"], [3] = "showIcon" },
+ [7] = { [1] = "toggle", [2] = L["Show Text"], [3] = "showText" },
+ [8] = { [1] = "toggle", [2] = L["Play Sounds"], [3] = "playSounds" },
+ [9] = { [1] = "range", [2] = L["Font Size"], [3] = "fontSize", [4] = 6, [5] = 40, [6] = 1 },
+ [10] = { [1] = "select", [2] = L["Font"], [3] = "font", [4] = SLDT.fontTbl },
+ [11] = { [1] = "select", [2] = L["Justify"], [3] = "aP", [4] = SLDT.justTbl },
+ [12] = { [1] = "text", [2] = L["Parent"], [3] = "anch" },
+ [13] = { [1] = "select", [2] = L["Anchor"], [3] = "aF", [4] = SLDT.anchTbl },
+ [14] = { [1] = "text", [2] = L["X Offset"], [3] = "xOff" },
+ [15] = { [1] = "text", [2] = L["Y Offset"], [3] = "yOff" },
+ [16] = { [1] = "select", [2] = L["Frame Strata"], [3] = "strata", [4] = SLDT.stratTbl },
+}
+
+local function OnInit()
+ SLDT.Mail.db = SLDT.db:RegisterNamespace(MODNAME)
+ SLDT.Mail.db:RegisterDefaults({
+ profile = {
+ name = "Mail",
+ enabled = true,
+ gfont = false,
+ outline = false,
+ forceShow = false,
+ tooltipOn = true,
+ showIcon = true,
+ showText = true,
+ playSounds = true,
+ fontSize = 14,
+ font = "Arial Narrow",
+ aP = "CENTER",
+ anch = "UIParent",
+ aF = "BOTTOM",
+ xOff = -375,
+ yOff = 7,
+ strata = "LOW",
+ new = 0,
+ total = 0,
+ ahAlert = false,
+ },
+ })
+ db = SLDT.Mail.db.profile
+
+ SLDT.Modules = SLDT.Modules or {}
+ if ( not SLDT.Modules[MODNAME] ) then table.insert(SLDT.Modules, { MODNAME, db }) end
+ frame, text, tool = SLDT:SetupBaseFrame(SLDT.Mail)
+ SetupToolTip()
+
+ SLDT.Mail:UnregisterEvent("PLAYER_ENTERING_WORLD")
+ SLDT.Mail:Enable()
+end
+
+SLDT.Mail:RegisterEvent("PLAYER_ENTERING_WORLD")
+SLDT.Mail:SetScript("OnEvent", OnInit)
\ No newline at end of file
diff --git a/Elements/memory.lua b/Elements/memory.lua
new file mode 100644
index 0000000..e04a404
--- /dev/null
+++ b/Elements/memory.lua
@@ -0,0 +1,158 @@
+--[[ SLDataText Module: Memory ]]
+--[[ Author: Taffu RevDate: 01/21/2018 Version: 7.3.1 ]]
+
+local SLDT, MODNAME = SLDataText, "Memory"
+if ( SLDT ) then SLDT.Memory = CreateFrame("Frame") end
+local L = SLDT.Locale
+local db, frame, text, tool
+
+local function SetupToolTip()
+ tool:SetScript("OnEnter", function(this)
+ local function sortdesc(a, b) return a[2] > b[2] end
+ GameTooltip:SetOwner(this, db.aF)
+ UpdateAddOnMemoryUsage()
+ local addons, total = {}, 0
+ for i = 1, GetNumAddOns() do
+ if ( IsAddOnLoaded(i) ) then
+ local memUse = GetAddOnMemoryUsage(i)
+ table.insert(addons, { GetAddOnInfo(i), memUse })
+ total = total + memUse
+ end
+ end
+ table.sort(addons, sortdesc)
+ GameTooltip:AddLine(string.format("|cffffffff"..L["AddOn Memory"]..":|r %.1fmb", total/1024))
+ if ( not IsAltKeyDown() ) then GameTooltip:AddLine(L["Showing Top 15 AddOns"]) end
+ GameTooltip:AddLine(" ")
+ for i = 1, #addons do
+ if ( i <= 15 and not IsAltKeyDown() ) then
+ local v = addons[i]
+ local tag, memAmt
+ if ( v[2]/1024 < 1 ) then tag = "kb"; memAmt = v[2] else tag = "mb"; memAmt = v[2]/1024 end
+ GameTooltip:AddDoubleLine(v[1], string.format("%.1f%s", memAmt, tag), 1,1,0,1,1,1)
+ elseif ( IsAltKeyDown() ) then
+ local v = addons[i]
+ local tag, memAmt
+ if ( v[2]/1024 < 1 ) then tag = "kb"; memAmt = v[2] else tag = "mb"; memAmt = v[2]/1024 end
+ GameTooltip:AddDoubleLine(v[1], string.format("%.1f%s", memAmt, tag), 1,1,0,1,1,1)
+ end
+ end
+ GameTooltip:AddDoubleLine("", "----------", 1,1,1,1,1,1)
+ GameTooltip:AddDoubleLine(L["Total AddOn Memory"], string.format("%.1fmb", total/1024), 1,1,0,1,1,1)
+ GameTooltip:AddDoubleLine(L["Total UI Memory Usage"], string.format("%.1fmb", gcinfo()/1024), 1,1,0,1,1,1)
+ GameTooltip:AddLine(" ")
+ GameTooltip:AddDoubleLine(L["Hover"], L["Show only top AddOns"], 1,1,0,1,1,1)
+ GameTooltip:AddDoubleLine(L["Alt+Hover"], L["Show all AddOns"], 1,1,0,1,1,1)
+ GameTooltip:AddDoubleLine(L["Right-Click"], L["Collect Garbage"], 1,1,0,1,1,1)
+ GameTooltip:Show()
+ end)
+ tool:SetScript("OnLeave", function(this)
+ if ( GameTooltip:IsShown() ) then GameTooltip:Hide() end
+ end)
+ tool:SetScript("OnMouseDown", function(self, button)
+ if ( button == "RightButton" ) then
+ collectgarbage()
+ end
+ end)
+end
+
+function SLDT.Memory:Enable()
+ if ( db.enabled ) then
+ SLDT:UpdateBaseText(self, db)
+ local int = db.interval
+ frame:SetScript("OnUpdate", function(_, elapsed)
+ int = int - elapsed
+ if ( int <= 0 ) then SLDT.Memory:Refresh(); int = db.interval end
+ end)
+ end
+ self:Refresh()
+end
+
+function SLDT.Memory:Disable()
+ if ( not db.enabled ) then
+ frame:SetScript("OnUpdate", nil)
+ end
+ self:Refresh()
+end
+
+local tags = {
+ ["MA"] = function()
+ local total = 0
+ for i = 1, GetNumAddOns() do
+ if ( IsAddOnLoaded(i) ) then total = total + GetAddOnMemoryUsage(i) end
+ end
+ return string.format("|cffffffff%.1f|r|cff%s", total/1024, SLDT.db.profile.cCol and SLDT.classColor or "ffffff")
+ end,
+ ["MT"] = function()
+ return string.format("|cffffffff%.1f|r|cff%s", gcinfo()/1024, SLDT.db.profile.cCol and SLDT.classColor or "ffffff")
+ end,
+}
+
+function SLDT.Memory:Refresh()
+ if ( db.enabled or SLDT.db.profile.configMode ) then
+ if ( not self.firstRun ) then self.firstRun = true; SLDT:UpdateBaseText(self, db) end
+
+ UpdateAddOnMemoryUsage()
+ local str = db.textDisplay
+ str = string.gsub(str, "%[(%w+)%]", function(w) return tags[w]() end)
+ text:SetFormattedText("|cff%s%s|r", SLDT.db.profile.cCol and SLDT.classColor or "ffffff", str)
+
+ SLDT:UpdateBaseFrame(self, db)
+ else
+ if ( frame:IsShown() and not SLDataText.db.profile.configMode ) then frame:Hide() end
+ end
+end
+
+SLDT.Memory.optsTbl = {
+ [1] = { [1] = "toggle", [2] = L["Enabled"], [3] = "enabled" },
+ [2] = { [1] = "toggle", [2] = L["Global Font"], [3] = "gfont" },
+ [3] = { [1] = "toggle", [2] = L["Outline"], [3] = "outline" },
+ [4] = { [1] = "toggle", [2] = L["Force Shown"], [3] = "forceShow" },
+ [5] = { [1] = "toggle", [2] = L["Tooltip On"], [3] = "tooltipOn" },
+ [6] = { [1] = "text", [2] = L["Text Display"], [3] = "textDisplay" },
+ [7] = { [1] = "desc", [2] = "MemTextDesc", [3] = L["MemTextDesc"] },
+ [8] = { [1] = "range", [2] = L["Update Interval"], [3] = "interval", [4] = 10, [5] = 1000, [6] = 10 },
+ [9] = { [1] = "range", [2] = L["Font Size"], [3] = "fontSize", [4] = 6, [5] = 40, [6] = 1 },
+ [10] = { [1] = "select", [2] = L["Font"], [3] = "font", [4] = SLDT.fontTbl },
+ [11] = { [1] = "select", [2] = L["Justify"], [3] = "aP", [4] = SLDT.justTbl },
+ [12] = { [1] = "text", [2] = L["Parent"], [3] = "anch" },
+ [13] = { [1] = "select", [2] = L["Anchor"], [3] = "aF", [4] = SLDT.anchTbl },
+ [14] = { [1] = "text", [2] = L["X Offset"], [3] = "xOff" },
+ [15] = { [1] = "text", [2] = L["Y Offset"], [3] = "yOff" },
+ [16] = { [1] = "select", [2] = L["Frame Strata"], [3] = "strata", [4] = SLDT.stratTbl },
+}
+
+local function OnInit()
+ SLDT.Memory.db = SLDT.db:RegisterNamespace(MODNAME)
+ SLDT.Memory.db:RegisterDefaults({
+ profile = {
+ name = "Memory",
+ enabled = true,
+ forceShow = false,
+ aP = "CENTER",
+ anch = "UIParent",
+ aF = "BOTTOM",
+ xOff = -443,
+ yOff = 7,
+ strata = "MEDIUM",
+ gfont = false,
+ fontSize = 14,
+ font = "Arial Narrow",
+ outline = false,
+ interval = 10,
+ tooltipOn = true,
+ textDisplay = "[MA]mb",
+ },
+ })
+ db = SLDT.Memory.db.profile
+
+ SLDT.Modules = SLDT.Modules or {}
+ if ( not SLDT.Modules[MODNAME] ) then table.insert(SLDT.Modules, { MODNAME, db }) end
+ frame, text, tool = SLDT:SetupBaseFrame(SLDT.Memory)
+ SetupToolTip()
+
+ SLDT.Memory:UnregisterEvent("PLAYER_ENTERING_WORLD")
+ SLDT.Memory:Enable()
+end
+
+SLDT.Memory:RegisterEvent("PLAYER_ENTERING_WORLD")
+SLDT.Memory:SetScript("OnEvent", OnInit)
\ No newline at end of file
diff --git a/Elements/reputation.lua b/Elements/reputation.lua
new file mode 100644
index 0000000..5318991
--- /dev/null
+++ b/Elements/reputation.lua
@@ -0,0 +1,169 @@
+--[[ SLDataText Module: Reputation ]]
+--[[ Author: Taffu RevDate: 01/21/2018 Version: 7.3.1 ]]
+
+-- Rev: Added proper "Tooltip On" check
+
+local SLDT, MODNAME, SLT = SLDataText, "Reputation", LibStub("LibSLTip-1.0")
+if ( SLDT ) then SLDT.Reputation = CreateFrame("Frame") end
+local L = SLDT.Locale
+local db, frame, text, tool, tip, noWatch
+
+local standingTbl = {
+ [1] = L["Hated"],
+ [2] = L["Hostile"],
+ [3] = L["Unfriendly"],
+ [4] = L["Neutral"],
+ [5] = L["Friendly"],
+ [6] = L["Honored"],
+ [7] = L["Revered"],
+ [8] = L["Exalted"],
+ [9] = L["Paragon"],
+}
+
+local stdCol = {
+ [1] = { r = 0.8, g = 0.3, b = 0.22 },
+ [2] = { r = 0.8, g = 0.3, b = 0.22 },
+ [3] = { r = 0.75, g = 0.27, b = 0 },
+ [4] = { r = 0.9, g = 0.7, b = 0 },
+ [5] = { r = 0, g = 0.6, b = 0.1 },
+ [6] = { r = 0, g = 0.6, b = 0.1 },
+ [7] = { r = 0, g = 0.6, b = 0.1 },
+ [8] = { r = 0, g = 0, b = 1 },
+}
+
+local function SetupToolTip()
+ tool:SetScript("OnEnter", function(this)
+ if ( SLDT.Reputation.repTbl and noWatch ~= true and db.tooltipOn ) then
+ local repTbl = SLDT.Reputation.repTbl
+
+ tip = SLT:GetTooltip("SLDT_Reputation", false)
+ SLT:AddHeader("SLDT_Reputation", repTbl[1], repTbl[2], { 1, 1, 1 })
+ SLT:AddDoubleLine("SLDT_Reputation", standingTbl[repTbl[3]], string.format("%i/%i", repTbl[6]-repTbl[4], repTbl[5]-repTbl[4]), { stdCol[repTbl[3]].r, stdCol[repTbl[3]].g, stdCol[repTbl[3]].b }, nil)
+
+ if ( not InCombatLockdown() ) then SLT:ShowTooltip("SLDT_Reputation", frame) end
+ end
+ end)
+ tool:SetScript("OnLeave", function(this) if ( SLDT.Reputation.repTbl and db.tooltipOn ) then SLT:ClearTooltip("SLDT_Reputation") end end)
+ tool:SetScript("OnMouseDown", function(this, button)
+ ToggleCharacter("ReputationFrame")
+ end)
+end
+
+local function TruncateName(name)
+ local first, second = string.split(" ", name)
+ return first
+end
+
+function SLDT.Reputation:Enable()
+ if ( db.enabled ) then
+ SLDT:UpdateBaseText(self, db)
+ self:RegisterEvent("CHAT_MSG_COMBAT_FACTION_CHANGE")
+ self:RegisterEvent("UPDATE_FACTION")
+ self:SetScript("OnEvent", function() self:Refresh() end)
+ end
+ self:Refresh()
+end
+
+function SLDT.Reputation:Disable()
+ if ( not db.enabled ) then
+ self:UnregisterEvent("CHAT_MSG_COMBAT_FACTION_CHANGE")
+ self:UnregisterEvent("UPDATE_FACTION")
+ self:SetScript("OnEvent", nil)
+ end
+ self:Refresh()
+end
+
+local repCheckTimer = function()
+ SLDT.Reputation:SetScript("OnUpdate", function(self, elapsed)
+ if ( GetNumFactions() > 0 ) then
+ self:SetScript("OnUpdate", nil)
+ self:Refresh()
+ end
+ end)
+end
+
+function SLDT.Reputation:Refresh()
+ if ( db.enabled or SLDataText.db.profile.configMode ) then
+ if ( not self.firstRun ) then self.firstRun = true; SLDT:UpdateBaseText(self, db) end
+ if ( GetNumFactions() == 0 ) then repCheckTimer(); return end
+
+ noWatch = true
+ SLDT.Reputation.repTbl = {}
+ for i = 1, GetNumFactions() do
+ local name, desc, sID, barMin, barMax, barVal, _, _, isHeader, _, hasRep, isWatched, _ = GetFactionInfo(i)
+ if ( not isHeader ) then
+ if ( isWatched ) then
+ -- Store for tooltip use
+ SLDT.Reputation.repTbl = { name, desc, sID, barMin, barMax, barVal }
+
+ local repPer = (100/(barMax-barMin))*(barVal-barMin)
+ text:SetFormattedText("|cff%s%s:|r %.0f%%", SLDT.db.profile.cCol and SLDT.classColor or "ffffff", name, repPer)
+ text:SetTextColor(stdCol[sID].r, stdCol[sID].g, stdCol[sID].b)
+ noWatch = false
+ end
+ end
+ end
+
+ if ( noWatch ) then
+ SLDT.Reputation.repTbl = nil
+ text:SetText(L["No Reputation"])
+ text:SetTextColor(1, 1, 1)
+ end
+
+ SLDT:UpdateBaseFrame(SLDT.Reputation, db)
+ else
+ if ( frame:IsShown() and not SLDataText.db.profile.configMode ) then frame:Hide() end
+ end
+end
+
+SLDT.Reputation.optsTbl = {
+ [1] = { [1] = "toggle", [2] = L["Enabled"], [3] = "enabled" },
+ [2] = { [1] = "toggle", [2] = L["Global Font"], [3] = "gfont" },
+ [3] = { [1] = "toggle", [2] = L["Outline"], [3] = "outline" },
+ [4] = { [1] = "toggle", [2] = L["Force Shown"], [3] = "forceShow" },
+ [5] = { [1] = "toggle", [2] = L["Tooltip On"], [3] = "tooltipOn" },
+ [6] = { [1] = "range", [2] = L["Font Size"], [3] = "fontSize", [4] = 6, [5] = 40, [6] = 1 },
+ [7] = { [1] = "select", [2] = L["Font"], [3] = "font", [4] = SLDT.fontTbl },
+ [8] = { [1] = "select", [2] = L["Justify"], [3] = "aP", [4] = SLDT.justTbl },
+ [9] = { [1] = "text", [2] = L["Parent"], [3] = "anch" },
+ [10] = { [1] = "select", [2] = L["Anchor"], [3] = "aF", [4] = SLDT.anchTbl },
+ [11] = { [1] = "text", [2] = L["X Offset"], [3] = "xOff" },
+ [12] = { [1] = "text", [2] = L["Y Offset"], [3] = "yOff" },
+ [13] = { [1] = "select", [2] = L["Frame Strata"], [3] = "strata", [4] = SLDT.stratTbl },
+}
+
+local function OnInit()
+ SLDT.Reputation.db = SLDT.db:RegisterNamespace(MODNAME)
+ SLDT.Reputation.db:RegisterDefaults({
+ profile = {
+ name = "Reputation",
+ enabled = true,
+ display = "None",
+ forceShow = false,
+ aP = "CENTER",
+ anch = "UIParent",
+ aF = "BOTTOM",
+ xOff = -247,
+ yOff = 7,
+ strata = "LOW",
+ gfont = false,
+ fontSize = 14,
+ font = "Arial Narrow",
+ outline = false,
+ interval = 10,
+ tooltipOn = true,
+ },
+ })
+ db = SLDT.Reputation.db.profile
+
+ SLDT.Modules = SLDT.Modules or {}
+ if ( not SLDT.Modules[MODNAME] ) then table.insert(SLDT.Modules, { MODNAME, db }) end
+ frame, text, tool = SLDT:SetupBaseFrame(SLDT.Reputation)
+ SetupToolTip()
+
+ SLDT.Reputation:UnregisterEvent("PLAYER_ENTERING_WORLD")
+ SLDT.Reputation:Enable()
+end
+
+SLDT.Reputation:RegisterEvent("PLAYER_ENTERING_WORLD")
+SLDT.Reputation:SetScript("OnEvent", OnInit)
\ No newline at end of file
diff --git a/Elements/zonetext.lua b/Elements/zonetext.lua
new file mode 100644
index 0000000..379ed38
--- /dev/null
+++ b/Elements/zonetext.lua
@@ -0,0 +1,164 @@
+--[[ SLDataText Module: Zone Text ]]
+--[[ Author: Taffu RevDate: 01/21/2018 Version: 7.3.1 ]]
+
+local SLDT, MODNAME = SLDataText, "ZoneText"
+if ( SLDT ) then SLDT.ZoneText = CreateFrame("Frame") end
+local L = SLDT.Locale
+local db, frame, text, tool
+
+local zoneName, subZoneName, pvpType, factionName
+local zCol = {
+ ["sanctuary"] = { r = 0.41, b = 0.8, g = 0.94 },
+ ["arena"] = { r = 1.0, b = 0.1, g = 0.1 },
+ ["friendly"] = { r = 0.1, b = 1.0, g = 0.1 },
+ ["hostile"] = { r = 1.0, b = 0.1, g = 0.1 },
+ ["contested"] = { r = 1.0, b = 0.7, g = 0 },
+
+}
+
+local function SetupToolTip()
+ tool:SetScript("OnEnter", function(this)
+ GameTooltip:SetOwner(this, db.aF)
+ GameTooltip:AddLine(zoneName, zCol[pvpType] and { zCol[pvpType].r, zCol[pvpType].b, zCol[pvpType].g } or { 1, 1, 1 })
+ if ( subZoneName and subZoneName ~= "" ) then
+ GameTooltip:AddLine(subZoneName, 1, 1, 1)
+ end
+ if ( zCol[pvpType] ) then
+ if ( pvpType == "sanctuary" ) then
+ GameTooltip:AddLine(SANCTUARY_TERRITORY, zCol[pvpType].r, zCol[pvpType].b, zCol[pvpType].g)
+ elseif ( pvpType == "arena" ) then
+ GameTooltip:AddLine(FREE_FOR_ALL_TERRITORY, zCol[pvpType].r, zCol[pvpType].b, zCol[pvpType].g)
+ elseif ( pvpType == "friendly" ) then
+ GameTooltip:AddLine(format(FACTION_CONTROLLED_TERRITORY, factionName), zCol[pvpType].r, zCol[pvpType].b, zCol[pvpType].g)
+ elseif ( pvpType == "hostile" ) then
+ GameTooltip:AddLine(format(FACTION_CONTROLLED_TERRITORY, factionName), zCol[pvpType].r, zCol[pvpType].b, zCol[pvpType].g)
+ elseif ( pvpType == "contested" ) then
+ GameTooltip:AddLine(CONTESTED_TERRITORY, zCol[pvpType].r, zCol[pvpType].b, zCol[pvpType].g)
+ end
+ end
+ GameTooltip:Show()
+ end)
+ tool:SetScript("OnLeave", function(this) if ( GameTooltip:IsShown() ) then GameTooltip:Hide() end end)
+ tool:SetScript("OnMouseDown", function()
+ ToggleFrame(WorldMapFrame)
+ end)
+end
+
+local function FixFrames(t)
+ if ( t ) then
+ -- MinimapZoneTextButton.Show = MiniMapWorldMapButton.Hide
+ -- MinimapBorderTop.Show = MiniMapWorldMapButton.Hide
+ -- MiniMapWorldMapButton.Show = MiniMapWorldMapButton.Hide
+
+ if ( IsAddOnLoaded("Chinchilla") ) then
+ if ( Chinchilla_Location_Frame and Chinchilla_Location_Frame:IsShown() ) then
+ Chinchilla_Location_Frame:Hide()
+ end
+ end
+ else
+ -- MinimapZoneTextButton.Show = MiniMapWorldMapButton.Show
+ -- MinimapBorderTop.Show = MiniMapWorldMapButton.Show
+ -- MiniMapWorldMapButton.Show = MiniMapWorldMapButton.Show
+
+ if ( IsAddOnLoaded("Chinchilla") ) then
+ if ( Chinchilla_Location_Frame and not Chinchilla_Location_Frame:IsShown() ) then
+ Chinchilla_Location_Frame:Show()
+ end
+ end
+ end
+end
+
+function SLDT.ZoneText:Enable()
+ if ( db.enabled ) then
+ SLDT:UpdateBaseText(self, db)
+ self:RegisterEvent("ZONE_CHANGED")
+ self:RegisterEvent("ZONE_CHANGED_INDOORS")
+ self:RegisterEvent("ZONE_CHANGED_NEW_AREA")
+ self:SetScript("OnEvent", function() self:Refresh() end)
+ end
+ self:Refresh()
+end
+
+function SLDT.ZoneText:Disable()
+ if ( not db.enabled ) then
+ self:UnregisterEvent("ZONE_CHANGED")
+ self:UnregisterEvent("ZONE_CHANGED_INDOORS")
+ self:UnregisterEvent("ZONE_CHANGED_NEW_AREA")
+ self:SetScript("OnEvent", nil)
+ end
+ self:Refresh()
+end
+
+function SLDT.ZoneText:Refresh()
+ if ( db.enabled or SLDataText.db.profile.configMode ) then
+ if ( not self.firstRun ) then self.firstRun = true; SLDT:UpdateBaseText(self, db) end
+
+ zoneName = GetZoneText()
+ subZoneName = GetSubZoneText()
+ pvpType, _, factionName = GetZonePVPInfo()
+
+ if ( subZoneName == zoneName or subZoneName == "" ) then text:SetText(zoneName) else text:SetText(subZoneName) end
+
+ if ( zCol[pvpType] ) then
+ text:SetTextColor(zCol[pvpType].r, zCol[pvpType].b, zCol[pvpType].g)
+ else
+ text:SetTextColor(1.0, 0.9294, 0.7607)
+ end
+
+ SLDT:UpdateBaseFrame(self, db)
+ FixFrames(db.enabled)
+ else
+ if ( frame:IsShown() and not SLDataText.db.profile.configMode ) then frame:Hide() end
+ FixFrames(db.enabled)
+ end
+end
+
+SLDT.ZoneText.optsTbl = {
+ [1] = { [1] = "toggle", [2] = L["Enabled"], [3] = "enabled" },
+ [2] = { [1] = "toggle", [2] = L["Global Font"], [3] = "gfont" },
+ [3] = { [1] = "toggle", [2] = L["Outline"], [3] = "outline" },
+ [4] = { [1] = "toggle", [2] = L["Force Shown"], [3] = "forceShow" },
+ [5] = { [1] = "toggle", [2] = L["Tooltip On"], [3] = "tooltipOn" },
+ [6] = { [1] = "range", [2] = L["Font Size"], [3] = "fontSize", [4] = 6, [5] = 40, [6] = 1 },
+ [7] = { [1] = "select", [2] = L["Font"], [3] = "font", [4] = SLDT.fontTbl },
+ [8] = { [1] = "select", [2] = L["Justify"], [3] = "aP", [4] = SLDT.justTbl },
+ [9] = { [1] = "text", [2] = L["Parent"], [3] = "anch" },
+ [10] = { [1] = "select", [2] = L["Anchor"], [3] = "aF", [4] = SLDT.anchTbl },
+ [11] = { [1] = "text", [2] = L["X Offset"], [3] = "xOff" },
+ [12] = { [1] = "text", [2] = L["Y Offset"], [3] = "yOff" },
+ [13] = { [1] = "select", [2] = L["Frame Strata"], [3] = "strata", [4] = SLDT.stratTbl },
+}
+
+local function OnInit()
+ SLDT.ZoneText.db = SLDT.db:RegisterNamespace(MODNAME)
+ SLDT.ZoneText.db:RegisterDefaults({
+ profile = {
+ name = "ZoneText",
+ enabled = true,
+ forceShow = false,
+ aP = "CENTER",
+ anch = "Minimap",
+ aF = "BOTTOM",
+ xOff = 0,
+ yOff = -10,
+ strata = "LOW",
+ gfont = false,
+ fontSize = 14,
+ font = "Arial Narrow",
+ outline = false,
+ tooltipOn = true,
+ },
+ })
+ db = SLDT.ZoneText.db.profile
+
+ SLDT.Modules = SLDT.Modules or {}
+ if ( not SLDT.Modules[MODNAME] ) then table.insert(SLDT.Modules, { MODNAME, db }) end
+ frame, text, tool = SLDT:SetupBaseFrame(SLDT.ZoneText)
+ SetupToolTip()
+
+ SLDT.ZoneText:UnregisterEvent("PLAYER_ENTERING_WORLD")
+ SLDT.ZoneText:Enable()
+end
+
+SLDT.ZoneText:RegisterEvent("PLAYER_ENTERING_WORLD")
+SLDT.ZoneText:SetScript("OnEvent", OnInit)
\ No newline at end of file
diff --git a/Libs/AceDB-3.0/AceDB-3.0.lua b/Libs/AceDB-3.0/AceDB-3.0.lua
new file mode 100644
index 0000000..9e84705
--- /dev/null
+++ b/Libs/AceDB-3.0/AceDB-3.0.lua
@@ -0,0 +1,740 @@
+--- **AceDB-3.0** manages the SavedVariables of your addon.
+-- It offers profile management, smart defaults and namespaces for modules.\\
+-- Data can be saved in different data-types, depending on its intended usage.
+-- The most common data-type is the `profile` type, which allows the user to choose
+-- the active profile, and manage the profiles of all of his characters.\\
+-- The following data types are available:
+-- * **char** Character-specific data. Every character has its own database.
+-- * **realm** Realm-specific data. All of the players characters on the same realm share this database.
+-- * **class** Class-specific data. All of the players characters of the same class share this database.
+-- * **race** Race-specific data. All of the players characters of the same race share this database.
+-- * **faction** Faction-specific data. All of the players characters of the same faction share this database.
+-- * **factionrealm** Faction and realm specific data. All of the players characters on the same realm and of the same faction share this database.
+-- * **locale** Locale specific data, based on the locale of the players game client.
+-- * **global** Global Data. All characters on the same account share this database.
+-- * **profile** Profile-specific data. All characters using the same profile share this database. The user can control which profile should be used.
+--
+-- Creating a new Database using the `:New` function will return a new DBObject. A database will inherit all functions
+-- of the DBObjectLib listed here. \\
+-- If you create a new namespaced child-database (`:RegisterNamespace`), you'll get a DBObject as well, but note
+-- that the child-databases cannot individually change their profile, and are linked to their parents profile - and because of that,
+-- the profile related APIs are not available. Only `:RegisterDefaults` and `:ResetProfile` are available on child-databases.
+--
+-- For more details on how to use AceDB-3.0, see the [[AceDB-3.0 Tutorial]].
+--
+-- You may also be interested in [[libdualspec-1-0|LibDualSpec-1.0]] to do profile switching automatically when switching specs.
+--
+-- @usage
+-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("DBExample")
+--
+-- -- declare defaults to be used in the DB
+-- local defaults = {
+-- profile = {
+-- setting = true,
+-- }
+-- }
+--
+-- function MyAddon:OnInitialize()
+-- -- Assuming the .toc says ## SavedVariables: MyAddonDB
+-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB", defaults, true)
+-- end
+-- @class file
+-- @name AceDB-3.0.lua
+-- @release $Id: AceDB-3.0.lua 1284 2022-09-25 09:15:30Z nevcairiel $
+local ACEDB_MAJOR, ACEDB_MINOR = "AceDB-3.0", 27
+local AceDB = LibStub:NewLibrary(ACEDB_MAJOR, ACEDB_MINOR)
+
+if not AceDB then return end -- No upgrade needed
+
+-- Lua APIs
+local type, pairs, next, error = type, pairs, next, error
+local setmetatable, rawset, rawget = setmetatable, rawset, rawget
+
+-- WoW APIs
+local _G = _G
+
+AceDB.db_registry = AceDB.db_registry or {}
+AceDB.frame = AceDB.frame or CreateFrame("Frame")
+
+local CallbackHandler
+local CallbackDummy = { Fire = function() end }
+
+local DBObjectLib = {}
+
+--[[-------------------------------------------------------------------------
+ AceDB Utility Functions
+---------------------------------------------------------------------------]]
+
+-- Simple shallow copy for copying defaults
+local function copyTable(src, dest)
+ if type(dest) ~= "table" then dest = {} end
+ if type(src) == "table" then
+ for k,v in pairs(src) do
+ if type(v) == "table" then
+ -- try to index the key first so that the metatable creates the defaults, if set, and use that table
+ v = copyTable(v, dest[k])
+ end
+ dest[k] = v
+ end
+ end
+ return dest
+end
+
+-- Called to add defaults to a section of the database
+--
+-- When a ["*"] default section is indexed with a new key, a table is returned
+-- and set in the host table. These tables must be cleaned up by removeDefaults
+-- in order to ensure we don't write empty default tables.
+local function copyDefaults(dest, src)
+ -- this happens if some value in the SV overwrites our default value with a non-table
+ --if type(dest) ~= "table" then return end
+ for k, v in pairs(src) do
+ if k == "*" or k == "**" then
+ if type(v) == "table" then
+ -- This is a metatable used for table defaults
+ local mt = {
+ -- This handles the lookup and creation of new subtables
+ __index = function(t,k2)
+ if k2 == nil then return nil end
+ local tbl = {}
+ copyDefaults(tbl, v)
+ rawset(t, k2, tbl)
+ return tbl
+ end,
+ }
+ setmetatable(dest, mt)
+ -- handle already existing tables in the SV
+ for dk, dv in pairs(dest) do
+ if not rawget(src, dk) and type(dv) == "table" then
+ copyDefaults(dv, v)
+ end
+ end
+ else
+ -- Values are not tables, so this is just a simple return
+ local mt = {__index = function(t,k2) return k2~=nil and v or nil end}
+ setmetatable(dest, mt)
+ end
+ elseif type(v) == "table" then
+ if not rawget(dest, k) then rawset(dest, k, {}) end
+ if type(dest[k]) == "table" then
+ copyDefaults(dest[k], v)
+ if src['**'] then
+ copyDefaults(dest[k], src['**'])
+ end
+ end
+ else
+ if rawget(dest, k) == nil then
+ rawset(dest, k, v)
+ end
+ end
+ end
+end
+
+-- Called to remove all defaults in the default table from the database
+local function removeDefaults(db, defaults, blocker)
+ -- remove all metatables from the db, so we don't accidentally create new sub-tables through them
+ setmetatable(db, nil)
+ -- loop through the defaults and remove their content
+ for k,v in pairs(defaults) do
+ if k == "*" or k == "**" then
+ if type(v) == "table" then
+ -- Loop through all the actual k,v pairs and remove
+ for key, value in pairs(db) do
+ if type(value) == "table" then
+ -- if the key was not explicitly specified in the defaults table, just strip everything from * and ** tables
+ if defaults[key] == nil and (not blocker or blocker[key] == nil) then
+ removeDefaults(value, v)
+ -- if the table is empty afterwards, remove it
+ if next(value) == nil then
+ db[key] = nil
+ end
+ -- if it was specified, only strip ** content, but block values which were set in the key table
+ elseif k == "**" then
+ removeDefaults(value, v, defaults[key])
+ end
+ end
+ end
+ elseif k == "*" then
+ -- check for non-table default
+ for key, value in pairs(db) do
+ if defaults[key] == nil and v == value then
+ db[key] = nil
+ end
+ end
+ end
+ elseif type(v) == "table" and type(db[k]) == "table" then
+ -- if a blocker was set, dive into it, to allow multi-level defaults
+ removeDefaults(db[k], v, blocker and blocker[k])
+ if next(db[k]) == nil then
+ db[k] = nil
+ end
+ else
+ -- check if the current value matches the default, and that its not blocked by another defaults table
+ if db[k] == defaults[k] and (not blocker or blocker[k] == nil) then
+ db[k] = nil
+ end
+ end
+ end
+end
+
+-- This is called when a table section is first accessed, to set up the defaults
+local function initSection(db, section, svstore, key, defaults)
+ local sv = rawget(db, "sv")
+
+ local tableCreated
+ if not sv[svstore] then sv[svstore] = {} end
+ if not sv[svstore][key] then
+ sv[svstore][key] = {}
+ tableCreated = true
+ end
+
+ local tbl = sv[svstore][key]
+
+ if defaults then
+ copyDefaults(tbl, defaults)
+ end
+ rawset(db, section, tbl)
+
+ return tableCreated, tbl
+end
+
+-- Metatable to handle the dynamic creation of sections and copying of sections.
+local dbmt = {
+ __index = function(t, section)
+ local keys = rawget(t, "keys")
+ local key = keys[section]
+ if key then
+ local defaultTbl = rawget(t, "defaults")
+ local defaults = defaultTbl and defaultTbl[section]
+
+ if section == "profile" then
+ local new = initSection(t, section, "profiles", key, defaults)
+ if new then
+ -- Callback: OnNewProfile, database, newProfileKey
+ t.callbacks:Fire("OnNewProfile", t, key)
+ end
+ elseif section == "profiles" then
+ local sv = rawget(t, "sv")
+ if not sv.profiles then sv.profiles = {} end
+ rawset(t, "profiles", sv.profiles)
+ elseif section == "global" then
+ local sv = rawget(t, "sv")
+ if not sv.global then sv.global = {} end
+ if defaults then
+ copyDefaults(sv.global, defaults)
+ end
+ rawset(t, section, sv.global)
+ else
+ initSection(t, section, section, key, defaults)
+ end
+ end
+
+ return rawget(t, section)
+ end
+}
+
+local function validateDefaults(defaults, keyTbl, offset)
+ if not defaults then return end
+ offset = offset or 0
+ for k in pairs(defaults) do
+ if not keyTbl[k] or k == "profiles" then
+ error(("Usage: AceDBObject:RegisterDefaults(defaults): '%s' is not a valid datatype."):format(k), 3 + offset)
+ end
+ end
+end
+
+local preserve_keys = {
+ ["callbacks"] = true,
+ ["RegisterCallback"] = true,
+ ["UnregisterCallback"] = true,
+ ["UnregisterAllCallbacks"] = true,
+ ["children"] = true,
+}
+
+local realmKey = GetRealmName()
+local charKey = UnitName("player") .. " - " .. realmKey
+local _, classKey = UnitClass("player")
+local _, raceKey = UnitRace("player")
+local factionKey = UnitFactionGroup("player")
+local factionrealmKey = factionKey .. " - " .. realmKey
+local localeKey = GetLocale():lower()
+
+local regionTable = { "US", "KR", "EU", "TW", "CN" }
+local regionKey = regionTable[GetCurrentRegion()]
+local factionrealmregionKey = factionrealmKey .. " - " .. regionKey
+
+-- Actual database initialization function
+local function initdb(sv, defaults, defaultProfile, olddb, parent)
+ -- Generate the database keys for each section
+
+ -- map "true" to our "Default" profile
+ if defaultProfile == true then defaultProfile = "Default" end
+
+ local profileKey
+ if not parent then
+ -- Make a container for profile keys
+ if not sv.profileKeys then sv.profileKeys = {} end
+
+ -- Try to get the profile selected from the char db
+ profileKey = sv.profileKeys[charKey] or defaultProfile or charKey
+
+ -- save the selected profile for later
+ sv.profileKeys[charKey] = profileKey
+ else
+ -- Use the profile of the parents DB
+ profileKey = parent.keys.profile or defaultProfile or charKey
+
+ -- clear the profileKeys in the DB, namespaces don't need to store them
+ sv.profileKeys = nil
+ end
+
+ -- This table contains keys that enable the dynamic creation
+ -- of each section of the table. The 'global' and 'profiles'
+ -- have a key of true, since they are handled in a special case
+ local keyTbl= {
+ ["char"] = charKey,
+ ["realm"] = realmKey,
+ ["class"] = classKey,
+ ["race"] = raceKey,
+ ["faction"] = factionKey,
+ ["factionrealm"] = factionrealmKey,
+ ["factionrealmregion"] = factionrealmregionKey,
+ ["profile"] = profileKey,
+ ["locale"] = localeKey,
+ ["global"] = true,
+ ["profiles"] = true,
+ }
+
+ validateDefaults(defaults, keyTbl, 1)
+
+ -- This allows us to use this function to reset an entire database
+ -- Clear out the old database
+ if olddb then
+ for k,v in pairs(olddb) do if not preserve_keys[k] then olddb[k] = nil end end
+ end
+
+ -- Give this database the metatable so it initializes dynamically
+ local db = setmetatable(olddb or {}, dbmt)
+
+ if not rawget(db, "callbacks") then
+ -- try to load CallbackHandler-1.0 if it loaded after our library
+ if not CallbackHandler then CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0", true) end
+ db.callbacks = CallbackHandler and CallbackHandler:New(db) or CallbackDummy
+ end
+
+ -- Copy methods locally into the database object, to avoid hitting
+ -- the metatable when calling methods
+
+ if not parent then
+ for name, func in pairs(DBObjectLib) do
+ db[name] = func
+ end
+ else
+ -- hack this one in
+ db.RegisterDefaults = DBObjectLib.RegisterDefaults
+ db.ResetProfile = DBObjectLib.ResetProfile
+ end
+
+ -- Set some properties in the database object
+ db.profiles = sv.profiles
+ db.keys = keyTbl
+ db.sv = sv
+ --db.sv_name = name
+ db.defaults = defaults
+ db.parent = parent
+
+ -- store the DB in the registry
+ AceDB.db_registry[db] = true
+
+ return db
+end
+
+-- handle PLAYER_LOGOUT
+-- strip all defaults from all databases
+-- and cleans up empty sections
+local function logoutHandler(frame, event)
+ if event == "PLAYER_LOGOUT" then
+ for db in pairs(AceDB.db_registry) do
+ db.callbacks:Fire("OnDatabaseShutdown", db)
+ db:RegisterDefaults(nil)
+
+ -- cleanup sections that are empty without defaults
+ local sv = rawget(db, "sv")
+ for section in pairs(db.keys) do
+ if rawget(sv, section) then
+ -- global is special, all other sections have sub-entrys
+ -- also don't delete empty profiles on main dbs, only on namespaces
+ if section ~= "global" and (section ~= "profiles" or rawget(db, "parent")) then
+ for key in pairs(sv[section]) do
+ if not next(sv[section][key]) then
+ sv[section][key] = nil
+ end
+ end
+ end
+ if not next(sv[section]) then
+ sv[section] = nil
+ end
+ end
+ end
+ end
+ end
+end
+
+AceDB.frame:RegisterEvent("PLAYER_LOGOUT")
+AceDB.frame:SetScript("OnEvent", logoutHandler)
+
+
+--[[-------------------------------------------------------------------------
+ AceDB Object Method Definitions
+---------------------------------------------------------------------------]]
+
+--- Sets the defaults table for the given database object by clearing any
+-- that are currently set, and then setting the new defaults.
+-- @param defaults A table of defaults for this database
+function DBObjectLib:RegisterDefaults(defaults)
+ if defaults and type(defaults) ~= "table" then
+ error(("Usage: AceDBObject:RegisterDefaults(defaults): 'defaults' - table or nil expected, got %q."):format(type(defaults)), 2)
+ end
+
+ validateDefaults(defaults, self.keys)
+
+ -- Remove any currently set defaults
+ if self.defaults then
+ for section,key in pairs(self.keys) do
+ if self.defaults[section] and rawget(self, section) then
+ removeDefaults(self[section], self.defaults[section])
+ end
+ end
+ end
+
+ -- Set the DBObject.defaults table
+ self.defaults = defaults
+
+ -- Copy in any defaults, only touching those sections already created
+ if defaults then
+ for section,key in pairs(self.keys) do
+ if defaults[section] and rawget(self, section) then
+ copyDefaults(self[section], defaults[section])
+ end
+ end
+ end
+end
+
+--- Changes the profile of the database and all of it's namespaces to the
+-- supplied named profile
+-- @param name The name of the profile to set as the current profile
+function DBObjectLib:SetProfile(name)
+ if type(name) ~= "string" then
+ error(("Usage: AceDBObject:SetProfile(name): 'name' - string expected, got %q."):format(type(name)), 2)
+ end
+
+ -- changing to the same profile, dont do anything
+ if name == self.keys.profile then return end
+
+ local oldProfile = self.profile
+ local defaults = self.defaults and self.defaults.profile
+
+ -- Callback: OnProfileShutdown, database
+ self.callbacks:Fire("OnProfileShutdown", self)
+
+ if oldProfile and defaults then
+ -- Remove the defaults from the old profile
+ removeDefaults(oldProfile, defaults)
+ end
+
+ self.profile = nil
+ self.keys["profile"] = name
+
+ -- if the storage exists, save the new profile
+ -- this won't exist on namespaces.
+ if self.sv.profileKeys then
+ self.sv.profileKeys[charKey] = name
+ end
+
+ -- populate to child namespaces
+ if self.children then
+ for _, db in pairs(self.children) do
+ DBObjectLib.SetProfile(db, name)
+ end
+ end
+
+ -- Callback: OnProfileChanged, database, newProfileKey
+ self.callbacks:Fire("OnProfileChanged", self, name)
+end
+
+--- Returns a table with the names of the existing profiles in the database.
+-- You can optionally supply a table to re-use for this purpose.
+-- @param tbl A table to store the profile names in (optional)
+function DBObjectLib:GetProfiles(tbl)
+ if tbl and type(tbl) ~= "table" then
+ error(("Usage: AceDBObject:GetProfiles(tbl): 'tbl' - table or nil expected, got %q."):format(type(tbl)), 2)
+ end
+
+ -- Clear the container table
+ if tbl then
+ for k,v in pairs(tbl) do tbl[k] = nil end
+ else
+ tbl = {}
+ end
+
+ local curProfile = self.keys.profile
+
+ local i = 0
+ for profileKey in pairs(self.profiles) do
+ i = i + 1
+ tbl[i] = profileKey
+ if curProfile and profileKey == curProfile then curProfile = nil end
+ end
+
+ -- Add the current profile, if it hasn't been created yet
+ if curProfile then
+ i = i + 1
+ tbl[i] = curProfile
+ end
+
+ return tbl, i
+end
+
+--- Returns the current profile name used by the database
+function DBObjectLib:GetCurrentProfile()
+ return self.keys.profile
+end
+
+--- Deletes a named profile. This profile must not be the active profile.
+-- @param name The name of the profile to be deleted
+-- @param silent If true, do not raise an error when the profile does not exist
+function DBObjectLib:DeleteProfile(name, silent)
+ if type(name) ~= "string" then
+ error(("Usage: AceDBObject:DeleteProfile(name): 'name' - string expected, got %q."):format(type(name)), 2)
+ end
+
+ if self.keys.profile == name then
+ error(("Cannot delete the active profile (%q) in an AceDBObject."):format(name), 2)
+ end
+
+ if not rawget(self.profiles, name) and not silent then
+ error(("Cannot delete profile %q as it does not exist."):format(name), 2)
+ end
+
+ self.profiles[name] = nil
+
+ -- populate to child namespaces
+ if self.children then
+ for _, db in pairs(self.children) do
+ DBObjectLib.DeleteProfile(db, name, true)
+ end
+ end
+
+ -- switch all characters that use this profile back to the default
+ if self.sv.profileKeys then
+ for key, profile in pairs(self.sv.profileKeys) do
+ if profile == name then
+ self.sv.profileKeys[key] = nil
+ end
+ end
+ end
+
+ -- Callback: OnProfileDeleted, database, profileKey
+ self.callbacks:Fire("OnProfileDeleted", self, name)
+end
+
+--- Copies a named profile into the current profile, overwriting any conflicting
+-- settings.
+-- @param name The name of the profile to be copied into the current profile
+-- @param silent If true, do not raise an error when the profile does not exist
+function DBObjectLib:CopyProfile(name, silent)
+ if type(name) ~= "string" then
+ error(("Usage: AceDBObject:CopyProfile(name): 'name' - string expected, got %q."):format(type(name)), 2)
+ end
+
+ if name == self.keys.profile then
+ error(("Cannot have the same source and destination profiles (%q)."):format(name), 2)
+ end
+
+ if not rawget(self.profiles, name) and not silent then
+ error(("Cannot copy profile %q as it does not exist."):format(name), 2)
+ end
+
+ -- Reset the profile before copying
+ DBObjectLib.ResetProfile(self, nil, true)
+
+ local profile = self.profile
+ local source = self.profiles[name]
+
+ copyTable(source, profile)
+
+ -- populate to child namespaces
+ if self.children then
+ for _, db in pairs(self.children) do
+ DBObjectLib.CopyProfile(db, name, true)
+ end
+ end
+
+ -- Callback: OnProfileCopied, database, sourceProfileKey
+ self.callbacks:Fire("OnProfileCopied", self, name)
+end
+
+--- Resets the current profile to the default values (if specified).
+-- @param noChildren if set to true, the reset will not be populated to the child namespaces of this DB object
+-- @param noCallbacks if set to true, won't fire the OnProfileReset callback
+function DBObjectLib:ResetProfile(noChildren, noCallbacks)
+ local profile = self.profile
+
+ for k,v in pairs(profile) do
+ profile[k] = nil
+ end
+
+ local defaults = self.defaults and self.defaults.profile
+ if defaults then
+ copyDefaults(profile, defaults)
+ end
+
+ -- populate to child namespaces
+ if self.children and not noChildren then
+ for _, db in pairs(self.children) do
+ DBObjectLib.ResetProfile(db, nil, noCallbacks)
+ end
+ end
+
+ -- Callback: OnProfileReset, database
+ if not noCallbacks then
+ self.callbacks:Fire("OnProfileReset", self)
+ end
+end
+
+--- Resets the entire database, using the string defaultProfile as the new default
+-- profile.
+-- @param defaultProfile The profile name to use as the default
+function DBObjectLib:ResetDB(defaultProfile)
+ if defaultProfile and type(defaultProfile) ~= "string" then
+ error(("Usage: AceDBObject:ResetDB(defaultProfile): 'defaultProfile' - string or nil expected, got %q."):format(type(defaultProfile)), 2)
+ end
+
+ local sv = self.sv
+ for k,v in pairs(sv) do
+ sv[k] = nil
+ end
+
+ initdb(sv, self.defaults, defaultProfile, self)
+
+ -- fix the child namespaces
+ if self.children then
+ if not sv.namespaces then sv.namespaces = {} end
+ for name, db in pairs(self.children) do
+ if not sv.namespaces[name] then sv.namespaces[name] = {} end
+ initdb(sv.namespaces[name], db.defaults, self.keys.profile, db, self)
+ end
+ end
+
+ -- Callback: OnDatabaseReset, database
+ self.callbacks:Fire("OnDatabaseReset", self)
+ -- Callback: OnProfileChanged, database, profileKey
+ self.callbacks:Fire("OnProfileChanged", self, self.keys["profile"])
+
+ return self
+end
+
+--- Creates a new database namespace, directly tied to the database. This
+-- is a full scale database in it's own rights other than the fact that
+-- it cannot control its profile individually
+-- @param name The name of the new namespace
+-- @param defaults A table of values to use as defaults
+function DBObjectLib:RegisterNamespace(name, defaults)
+ if type(name) ~= "string" then
+ error(("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - string expected, got %q."):format(type(name)), 2)
+ end
+ if defaults and type(defaults) ~= "table" then
+ error(("Usage: AceDBObject:RegisterNamespace(name, defaults): 'defaults' - table or nil expected, got %q."):format(type(defaults)), 2)
+ end
+ if self.children and self.children[name] then
+ error(("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - a namespace called %q already exists."):format(name), 2)
+ end
+
+ local sv = self.sv
+ if not sv.namespaces then sv.namespaces = {} end
+ if not sv.namespaces[name] then
+ sv.namespaces[name] = {}
+ end
+
+ local newDB = initdb(sv.namespaces[name], defaults, self.keys.profile, nil, self)
+
+ if not self.children then self.children = {} end
+ self.children[name] = newDB
+ return newDB
+end
+
+--- Returns an already existing namespace from the database object.
+-- @param name The name of the new namespace
+-- @param silent if true, the addon is optional, silently return nil if its not found
+-- @usage
+-- local namespace = self.db:GetNamespace('namespace')
+-- @return the namespace object if found
+function DBObjectLib:GetNamespace(name, silent)
+ if type(name) ~= "string" then
+ error(("Usage: AceDBObject:GetNamespace(name): 'name' - string expected, got %q."):format(type(name)), 2)
+ end
+ if not silent and not (self.children and self.children[name]) then
+ error(("Usage: AceDBObject:GetNamespace(name): 'name' - namespace %q does not exist."):format(name), 2)
+ end
+ if not self.children then self.children = {} end
+ return self.children[name]
+end
+
+--[[-------------------------------------------------------------------------
+ AceDB Exposed Methods
+---------------------------------------------------------------------------]]
+
+--- Creates a new database object that can be used to handle database settings and profiles.
+-- By default, an empty DB is created, using a character specific profile.
+--
+-- You can override the default profile used by passing any profile name as the third argument,
+-- or by passing //true// as the third argument to use a globally shared profile called "Default".
+--
+-- Note that there is no token replacement in the default profile name, passing a defaultProfile as "char"
+-- will use a profile named "char", and not a character-specific profile.
+-- @param tbl The name of variable, or table to use for the database
+-- @param defaults A table of database defaults
+-- @param defaultProfile The name of the default profile. If not set, a character specific profile will be used as the default.
+-- You can also pass //true// to use a shared global profile called "Default".
+-- @usage
+-- -- Create an empty DB using a character-specific default profile.
+-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB")
+-- @usage
+-- -- Create a DB using defaults and using a shared default profile
+-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB", defaults, true)
+function AceDB:New(tbl, defaults, defaultProfile)
+ if type(tbl) == "string" then
+ local name = tbl
+ tbl = _G[name]
+ if not tbl then
+ tbl = {}
+ _G[name] = tbl
+ end
+ end
+
+ if type(tbl) ~= "table" then
+ error(("Usage: AceDB:New(tbl, defaults, defaultProfile): 'tbl' - table expected, got %q."):format(type(tbl)), 2)
+ end
+
+ if defaults and type(defaults) ~= "table" then
+ error(("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaults' - table expected, got %q."):format(type(defaults)), 2)
+ end
+
+ if defaultProfile and type(defaultProfile) ~= "string" and defaultProfile ~= true then
+ error(("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaultProfile' - string or true expected, got %q."):format(type(defaultProfile)), 2)
+ end
+
+ return initdb(tbl, defaults, defaultProfile)
+end
+
+-- upgrade existing databases
+for db in pairs(AceDB.db_registry) do
+ if not db.parent then
+ for name,func in pairs(DBObjectLib) do
+ db[name] = func
+ end
+ else
+ db.RegisterDefaults = DBObjectLib.RegisterDefaults
+ db.ResetProfile = DBObjectLib.ResetProfile
+ end
+end
diff --git a/Libs/AceDB-3.0/AceDB-3.0.xml b/Libs/AceDB-3.0/AceDB-3.0.xml
new file mode 100644
index 0000000..28998e5
--- /dev/null
+++ b/Libs/AceDB-3.0/AceDB-3.0.xml
@@ -0,0 +1,4 @@
+
+
+
diff --git a/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua b/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua
new file mode 100644
index 0000000..bd04241
--- /dev/null
+++ b/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua
@@ -0,0 +1,207 @@
+--[[ $Id: CallbackHandler-1.0.lua 1284 2022-09-25 09:15:30Z nevcairiel $ ]]
+local MAJOR, MINOR = "CallbackHandler-1.0", 7
+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 error = error
+local setmetatable, rawget = setmetatable, 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
+
+--------------------------------------------------------------------------
+-- 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(_self, target, RegisterName, UnregisterName, UnregisterAllName)
+
+ 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
+
+ Dispatch(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 event,callbacks in pairs(registry.insertQueue) do
+ local first = not rawget(events, event) or not next(events[event]) -- test for empty before. not test for one member after. that one member may have been overwritten.
+ for object,func in pairs(callbacks) do
+ events[event][object] = func
+ -- fire OnUsed callback?
+ if first and registry.OnUsed then
+ registry.OnUsed(registry, target, event)
+ 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.
+
diff --git a/Libs/CallbackHandler-1.0/CallbackHandler-1.0.xml b/Libs/CallbackHandler-1.0/CallbackHandler-1.0.xml
new file mode 100644
index 0000000..a5b22a7
--- /dev/null
+++ b/Libs/CallbackHandler-1.0/CallbackHandler-1.0.xml
@@ -0,0 +1,4 @@
+
+
+
diff --git a/Libs/LibSL-1.0/LibSL-1.0.lua b/Libs/LibSL-1.0/LibSL-1.0.lua
new file mode 100644
index 0000000..6b10f49
--- /dev/null
+++ b/Libs/LibSL-1.0/LibSL-1.0.lua
@@ -0,0 +1,515 @@
+--[[ LibSL-1.0 - Simple Light Library ]]
+--[[ Use to create & manage SLDT Modules without complication ]]
+
+local MAJOR, MINOR = "LibSL-1.0", 4
+local lib = LibStub:NewLibrary(MAJOR, MINOR)
+if ( not lib ) then return end
+local function err(msg) ChatFrame1:AddMessage(string.format("LibSL: %s", msg)) end
+
+local diaBG, diaBor = "Interface\\DialogFrame\\UI-DialogBox-Background", "Interface\\DialogFrame\\UI-DialogBox-Border"
+local toolBG, toolBor = "Interface\\Tooltips\\UI-Tooltip-Background", "Interface\\Tooltips\\UI-Tooltip-Border"
+local solidBG = "Interface\\BUTTONS\\WHITE8X8"
+
+local BGDia = { bgFile = diaBG, edgeFile = diaBor, insets = {left=4,right=4,top=4,bottom=4}, tile = true, tileSize = 16, edgeSize = 16, }
+local BGSol = { bgFile = solidBG, edgeFile = diaBor, insets = {left=4,right=4,top=4,bottom=4}, tile = true, tileSize = 16, edgeSize = 16, }
+local anchTbl = { [1] = "TOPLEFT", [2] = "TOP", [3] = "TOPRIGHT", [4] = "LEFT", [5] = "CENTER", [6] = "RIGHT", [7] = "BOTTOMLEFT", [8] = "BOTTOM", [9] = "BOTTOMRIGHT" }
+
+
+--[[ ----------------------------------------------- ]]
+--[[ Frame Movement Functions ---------------------- ]]
+--[[ ----------------------------------------------- ]]
+local function TransCoords(frame, aF, aP, x, y)
+ local y1, x1
+ -- Handle Y-axis
+ if ( aF == "TOP" or aF == "TOPLEFT" or aF == "TOPRIGHT" ) then y1 = frame:GetHeight()/2; y = y - y1
+ elseif ( aF == "BOTTOM" or aF == "BOTTOMLEFT" or aF == "BOTTOMRIGHT" ) then y1 = frame:GetHeight()/2; y = y + y1 end
+ -- Handle X-axis
+ if ( aP == "RIGHT" and (aF == "TOPRIGHT" or aF == "RIGHT" or aF == "BOTTOMRIGHT") ) then x = x
+ elseif ( aP == "RIGHT" and (aF == "TOPLEFT" or aF == "LEFT" or aF == "BOTTOMLEFT") ) then x1 = frame:GetWidth(); x = x + x1
+ elseif ( aP == "RIGHT" and (aF == "CENTER" or aF == "TOP" or aF == "BOTTOM") ) then x1 = frame:GetWidth()/2; x = x + x1
+ elseif ( aP == "LEFT" and (aF == "TOPRIGHT" or aF == "RIGHT" or aF == "BOTTOMRIGHT") ) then x1 = frame:GetWidth(); x = x - x1
+ elseif ( aP == "LEFT" and (aF == "TOPLEFT" or aF == "LEFT" or aF == "BOTTOMLEFT") ) then x = x
+ elseif ( aP == "LEFT" and (aF == "CENTER" or aF == "TOP" or aF == "BOTTOM") ) then x1 = frame:GetWidth()/2; x = x - x1
+ elseif ( aP == "CENTER" and (aF == "TOPLEFT" or aF == "LEFT" or aF == "BOTTOMLEFT") ) then x1 = frame:GetWidth()/2; x = x + x1
+ elseif ( aP == "CENTER" and (aF == "TOPRIGHT" or aF == "RIGHT" or aF == "BOTTOMRIGHT") ) then x1 = frame:GetWidth()/2; x = x - x1
+ elseif ( aP == "CENTER" and (aF == "CENTER" or aF == "TOP" or aF == "BOTTOM") ) then x = x end
+ return x, y
+end
+function lib:MoveSLFrame(frame, db)
+ frame:SetPoint(db.aP, db.anch, db.aF, db.xOff, db.yOff)
+ frame:StartMoving()
+end
+function lib:StopSLFrame(frame, db, opt, title)
+ frame:StopMovingOrSizing()
+ local _, _, aF, x, y = frame:GetPoint()
+ local anch = frame:GetParent():GetName()
+ local xOff, yOff = TransCoords(frame, aF, db.aP, x, y)
+ db["aP"], db["anch"], db["aF"], db["xOff"], db["yOff"] = db.aP, anch, aF, floor(xOff), floor(yOff)
+ frame:ClearAllPoints(); frame:SetPoint(db.aP, db.anch, db.aF, db.xOff, db.yOff)
+
+ -- Update applicable module menu accordingly
+ local id
+ for k, v in pairs(anchTbl) do if ( db["aF"] == v ) then id = k end end
+ if ( opt ) then
+ UIDropDownMenu_SetSelectedID(opt["aF"], id)
+ opt["anch"]:SetText(db.anch); opt["xOff"]:SetText(db.xOff); opt["yOff"]:SetText(db.yOff)
+ end
+end
+--[[ ----------------------------------------------- ]]
+
+--[[ ----------------------------------------------- ]]
+--[[ Configuration Menu Functions ------------------ ]]
+--[[ ----------------------------------------------- ]]
+local function SliderMouse(self, delta)
+ local min, max = self:GetMinMaxValues()
+ local step = self:GetValueStep()
+ local value = self:GetValue()
+
+ if (value > min) and (delta < 0) then
+ value = (value - step)
+ if (value > min) then self:SetValue( value ) else self:SetValue( min ) end
+ end
+ if (value < max) and (delta > 0) then
+ value = (value + step)
+ if (value < max) then self:SetValue( value ) else self:SetValue( max ) end
+ end
+end
+
+local function NewCheckBox(owner, label, db, dbval, title, isGlobal)
+ local box = CreateFrame("CheckButton", label.."CheckBox", owner.Opt, "InterfaceOptionsCheckButtonTemplate")
+ box:SetSize(20,20)
+ box:SetChecked(db[dbval])
+ box.Text = box:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
+ box.Text:SetFont(box.Text:GetFont(), 11, "")
+ box.Text:SetPoint("LEFT", box, "RIGHT", 6, 0)
+ box.Text:SetJustifyH("LEFT")
+ box.Text:SetText(title)
+
+ box:SetScript("OnClick", function(self)
+
+ if ( self:GetChecked() ) then
+ db[dbval] = true; self:SetChecked(db[dbval])
+ else
+ db[dbval] = false; self:SetChecked(db[dbval])
+ end
+
+ if ( not isGlobal ) then SLDataText:UpdateBaseText(owner, db) end
+ if ( dbval == "enabled" ) then
+ if ( db[dbval] ) then
+ owner:Enable()
+ else
+ owner:Disable()
+ end
+ else
+ owner:Refresh()
+ end
+ end)
+
+ return box
+end
+
+local function NewSlider(owner, label, db, dbval, title, min, max, step, isGlobal)
+ local slider = CreateFrame("Slider", label.."Slider", owner.Opt, "OptionsSliderTemplate")
+ slider:SetMinMaxValues(min, max)
+ slider:SetOrientation("HORIZONTAL")
+ slider:SetValueStep(step)
+ slider:SetWidth(math.floor(owner.Opt:GetWidth()-30))
+ slider:SetHeight(14)
+ slider:SetValue(db[dbval])
+
+ getglobal(slider:GetName() .. 'Low'):SetText(min)
+ getglobal(slider:GetName() .. 'High'):SetText(max)
+ getglobal(slider:GetName() .. 'Text'):SetFont(getglobal(slider:GetName() .. 'Text'):GetFont(), 11, "")
+ getglobal(slider:GetName() .. 'Text'):SetText(title)
+
+ slider:SetScript("OnValueChanged", function(self)
+ db[dbval] = self:GetValue()
+ self:SetValue(db[dbval]); self.val:SetText(string.format("%.1f", db[dbval]))
+ if ( not isGlobal ) then SLDataText:UpdateBaseText(owner, db) end
+ owner:Refresh()
+ end)
+ slider:SetScript("OnMouseWheel", function(self, delta)
+ SliderMouse(self, delta)
+ end)
+
+ slider.val = CreateFrame("EditBox", label.."SliderValue", slider, "InputBoxTemplate")
+ slider.val:SetFontObject("ChatFontNormal")
+ slider.val:SetFont(slider.val:GetFont(), 11, "")
+ slider.val:SetTextInsets(0, 0, 2, 2)
+ slider.val:SetJustifyH("CENTER")
+ slider.val:SetWidth(35)
+ slider.val:SetHeight(12)
+ slider.val:SetScale(0.8)
+ slider.val:SetAutoFocus(false)
+ slider.val:SetMaxLetters(24)
+ slider.val:SetPoint("CENTER", slider, "CENTER", 0, -16)
+ slider.val:SetText(string.format("%.1f", db[dbval]))
+
+ slider.val:SetScript("OnEnterPressed", function(self)
+ db[dbval] = self:GetText()
+ self:SetText(string.format("%.1f", db[dbval])); slider:SetValue(db[dbval])
+ self:ClearFocus()
+ if ( not isGlobal ) then SLDataText:UpdateBaseText(owner, db) end
+ owner:Refresh()
+ end)
+ slider.val:SetScript("OnEscapePressed", function(self)
+ self:SetText(string.format("%.1f", db[dbval]))
+ self:ClearFocus()
+ end)
+
+ return slider
+end
+
+local function NewEditBox(owner, label, db, dbval, title, isGlobal)
+ local ebox = CreateFrame("EditBox", label, owner.Opt, "InputBoxTemplate")
+ ebox:SetFontObject("ChatFontNormal")
+ ebox:SetTextInsets(0, 0, 3, 3)
+ ebox:SetHeight(18)
+ ebox:SetWidth(math.floor(owner.Opt:GetWidth()-25))
+ ebox:SetAutoFocus(false)
+ ebox:SetMaxLetters(254)
+
+ ebox:SetScript("OnEnterPressed" , function(self)
+ db[dbval] = self:GetText()
+ self:SetText(db[dbval])
+ self:ClearFocus()
+ if ( not isGlobal ) then SLDataText:UpdateBaseText(owner, db) end
+ owner:Refresh()
+ end)
+ ebox:SetScript("OnEscapePressed", function(self)
+ self:SetText(db[dbval])
+ self:ClearFocus()
+ end)
+ ebox:SetText(db[dbval])
+
+ ebox.Text = ebox:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
+ ebox.Text:SetPoint("BOTTOMLEFT", ebox, "TOPLEFT", 0, 2)
+ ebox.Text:SetFont(ebox.Text:GetFont(), 11, "")
+ ebox.Text:SetJustifyH("LEFT")
+ ebox.Text:SetText(title)
+
+ return ebox
+end
+
+local function NewSelectBox(owner, label, db, dbval, title, items, isGlobal)
+ local select = CreateFrame("Button", label, owner.Opt, "UIDropDownMenuTemplate")
+ local function OnClick(self)
+ local selectedId = self:GetID()
+ UIDropDownMenu_SetSelectedID(select, selectedId)
+ for k, v in pairs(items) do
+ if ( k == selectedId ) then
+ db[dbval] = v
+ if ( not isGlobal ) then SLDataText:UpdateBaseText(owner, db) end
+ owner:Refresh()
+ end
+ end
+ end
+ local function Initialize(self, level)
+ local info = UIDropDownMenu_CreateInfo()
+ for k, v in ipairs(items) do
+ info = UIDropDownMenu_CreateInfo()
+ info.text = v
+ info.value = v
+ info.func = OnClick
+ UIDropDownMenu_AddButton(info, level)
+ end
+ end
+
+ local id = 1
+ for k, v in pairs(items) do
+ if ( db[dbval] == v ) then id = k end
+ end
+
+ UIDropDownMenu_Initialize(select, Initialize)
+ UIDropDownMenu_SetWidth(select, math.floor(owner.Opt:GetWidth()-37))
+ UIDropDownMenu_SetButtonWidth(select, math.floor(owner.Opt:GetWidth()-51))
+ UIDropDownMenu_SetSelectedID(select, id)
+ UIDropDownMenu_JustifyText(select, "LEFT")
+
+ select.Text = select:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
+ select.Text:SetPoint("BOTTOMLEFT", select, "TOPLEFT", 23, 1)
+ select.Text:SetFont(select.Text:GetFont(), 11, "")
+ select.Text:SetJustifyH("LEFT")
+ select.Text:SetText(title)
+
+ return select
+end
+
+local function NewDesc(owner, label, str)
+ local desc = owner.Opt:CreateFontString(label, "OVERLAY", "GameFontHighlightSmall")
+ desc:SetFont(desc:GetFont(), 11, "")
+ desc:SetWidth(math.floor(owner.Opt:GetWidth()-30))
+ desc:SetWordWrap(true)
+ desc:SetNonSpaceWrap(false)
+ desc:SetJustifyH("LEFT")
+ desc:SetText(str)
+
+ return desc
+end
+
+local function NewButton(owner, label, name, func)
+ local button = CreateFrame("Button", label, owner.Opt, "GameMenuButtonTemplate")
+ button:SetText(name)
+ button:SetWidth(math.floor(owner.Opt:GetWidth()-30))
+ button:SetHeight(20)
+ button:SetScript("OnClick", func)
+
+ return button
+end
+
+local function ProfileDesc(owner, label)
+ local desc = owner.Opt:CreateFontString(label, "OVERLAY", "GameFontHighlightSmall")
+ desc:SetFont(desc:GetFont(), 11, "")
+ desc:SetWidth(math.floor(owner.Opt:GetWidth()-30))
+ desc:SetWordWrap(true)
+ desc:SetNonSpaceWrap(false)
+ desc:SetJustifyH("LEFT")
+ desc:SetText(string.format("Current Profile: %s", owner.db:GetCurrentProfile()))
+
+ return desc
+end
+
+local function ProfileNewBox(owner, label)
+ local ebox = CreateFrame("EditBox", label, owner.Opt, "InputBoxTemplate")
+ ebox:SetFontObject("ChatFontNormal")
+ ebox:SetTextInsets(0, 0, 3, 3)
+ ebox:SetHeight(18)
+ ebox:SetWidth(math.floor(owner.Opt:GetWidth()-25))
+ ebox:SetAutoFocus(false)
+ ebox:SetMaxLetters(254)
+
+ ebox:SetScript("OnEnterPressed" , function(self)
+ local newProfile = self:GetText()
+ self:SetText(""); self:ClearFocus()
+ owner.db:SetProfile(newProfile)
+
+ owner:Refresh()
+ ReloadUI()
+ end)
+ ebox:SetScript("OnEscapePressed", function(self)
+ self:SetText("")
+ self:ClearFocus()
+ end)
+ ebox:SetText("")
+
+ ebox.Text = ebox:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
+ ebox.Text:SetPoint("BOTTOMLEFT", ebox, "TOPLEFT", 0, 2)
+ ebox.Text:SetFont(ebox.Text:GetFont(), 11, "")
+ ebox.Text:SetJustifyH("LEFT")
+ ebox.Text:SetText("New Profile")
+
+ return ebox
+end
+
+local function ProfileCopyBox(owner, label)
+ local select = CreateFrame("Button", label, owner.Opt, "UIDropDownMenuTemplate")
+ local items = owner.db:GetProfiles()
+ local function OnClick(self)
+ UIDropDownMenu_SetSelectedID(select, self:GetID())
+ for k, v in pairs(items) do
+ if ( self:GetID() == k ) then
+ owner.db:CopyProfile(v, true)
+ owner.Opt["Profile".."Current"]:SetText(v)
+ owner:Refresh()
+ end
+ end
+ end
+ local function Initialize(self, level)
+ local info = UIDropDownMenu_CreateInfo()
+ for k, v in ipairs(items) do
+ info = UIDropDownMenu_CreateInfo()
+ info.text = v
+ info.value = v
+ info.func = OnClick
+ UIDropDownMenu_AddButton(info, level)
+ end
+ end
+
+ local id = 1
+ for k, v in pairs(items) do
+ if ( owner.db:GetCurrentProfile() == v ) then id = k end
+ end
+
+ UIDropDownMenu_Initialize(select, Initialize)
+ UIDropDownMenu_SetWidth(select, math.floor(owner.Opt:GetWidth()-37))
+ UIDropDownMenu_SetButtonWidth(select, math.floor(owner.Opt:GetWidth()-51))
+ UIDropDownMenu_SetSelectedID(select, id)
+ UIDropDownMenu_JustifyText(select, "LEFT")
+
+ select.Text = select:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
+ select.Text:SetPoint("BOTTOMLEFT", select, "TOPLEFT", 23, 1)
+ select.Text:SetFont(select.Text:GetFont(), 11, "")
+ select.Text:SetJustifyH("LEFT")
+ select.Text:SetText("Copy Profile")
+
+ return select
+end
+
+local function ProfileReset(owner, label, title)
+ local button = CreateFrame("Button", label, owner.Opt, "GameMenuButtonTemplate")
+ button:SetText(title)
+ button:SetWidth(math.floor(owner.Opt:GetWidth()-30))
+ button:SetHeight(20)
+
+ local func = function()
+ owner.db:ResetProfile()
+ end
+
+ button:SetScript("OnClick", func)
+
+ return button
+end
+
+local function ProfileDeleteBox(owner, label)
+ local select = CreateFrame("Button", label, owner.Opt, "UIDropDownMenuTemplate")
+ local items = owner.db:GetProfiles()
+ local function OnClick(self)
+ UIDropDownMenu_SetSelectedID(select, self:GetID())
+ for k, v in pairs(items) do
+ if ( self:GetID() == k ) then
+ owner.db:DeleteProfile(v, true)
+ owner:Refresh()
+ ReloadUI()
+ end
+ end
+ end
+ local function Initialize(self, level)
+ local info = UIDropDownMenu_CreateInfo()
+ for k, v in ipairs(items) do
+ info = UIDropDownMenu_CreateInfo()
+ info.text = v
+ info.value = v
+ info.func = OnClick
+ UIDropDownMenu_AddButton(info, level)
+ end
+ end
+
+ local id = 1
+ for k, v in pairs(items) do
+ if ( owner.db:GetCurrentProfile() == v ) then id = k end
+ end
+
+ UIDropDownMenu_Initialize(select, Initialize)
+ UIDropDownMenu_SetWidth(select, math.floor(owner.Opt:GetWidth()-37))
+ UIDropDownMenu_SetButtonWidth(select, math.floor(owner.Opt:GetWidth()-51))
+ UIDropDownMenu_SetSelectedID(select, id)
+ UIDropDownMenu_JustifyText(select, "LEFT")
+
+ select.Text = select:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
+ select.Text:SetPoint("BOTTOMLEFT", select, "TOPLEFT", 23, 1)
+ select.Text:SetFont(select.Text:GetFont(), 11, "")
+ select.Text:SetJustifyH("LEFT")
+ select.Text:SetText("Delete Profile")
+
+ return select
+end
+
+local function BuildOpt(module, db, title, width)
+ module.Opt = module.Opt or CreateFrame("Frame", nil, UIParent, BackdropTemplateMixin and "BackdropTemplate")
+ module.Opt:SetBackdrop(BGDia)
+ module.Opt:SetWidth(width)
+ module.Opt:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
+ module.Opt:EnableMouse(true)
+ module.Opt:SetMovable(true)
+ module.Opt:SetClampedToScreen(true)
+ module.Opt:SetUserPlaced(true)
+ module.Opt:SetScript("OnMouseDown", function() module.Opt:StartMoving() end)
+ module.Opt:SetScript("OnMouseUp", function() module.Opt:StopMovingOrSizing() end)
+
+ module.Opt.hdr = module.Opt.hdr or CreateFrame("Frame", nil, module.Opt or module.Frame, BackdropTemplateMixin and "BackdropTemplate")
+ module.Opt.hdr:SetBackdrop(BGSol)
+ module.Opt.hdr:SetBackdropColor(0,0,0,1)
+ module.Opt.hdr:SetPoint("CENTER", module.Opt, "TOP", 0, -4)
+
+ module.Opt.text = module.Opt.hdr:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
+ module.Opt.text:SetFont(module.Opt.text:GetFont(), 14, "")
+ module.Opt.text:SetText(title)
+ module.Opt.text:SetPoint("CENTER", 0, 0)
+
+ module.Opt.hdr:SetWidth(125)
+ module.Opt.hdr:SetHeight(30)
+
+ module.Opt.close = CreateFrame("Button", nil, module.Opt, "UIPanelCloseButton")
+ module.Opt.close:SetScale(0.9)
+ module.Opt.close:SetPoint("TOPRIGHT", -3, -3)
+
+ module.Opt:Hide()
+end
+
+function lib:CreateMenu(title, module, options, width)
+ local db, width, height, isGlobal = module.db.profile, width or 250, 30, nil
+ if ( not module.Opt ) then BuildOpt(module, db, title, width) end
+ if ( title == "SLDataText" ) then isGlobal = true end
+
+ for k, v in ipairs(options) do
+ local type, name, dbval = v[1], v[2], v[3]
+ if ( type == "toggle" ) then
+ module.Opt[dbval] = NewCheckBox(module, "SLDT"..title..name, db, dbval, name, isGlobal)
+ module.Opt[dbval]:SetPoint("TOPLEFT", module.Opt, "TOPLEFT", 15, math.floor(0-height))
+ height = math.floor(height+20)
+ elseif ( type == "button" ) then
+ local func = dbval
+ module.Opt[name] = NewButton(module, "SLDT"..title..name, name, func)
+ height = math.floor(height+8)
+ module.Opt[name]:SetPoint("TOPLEFT", module.Opt, "TOPLEFT", 15, math.floor(0-height))
+ height = math.floor(height+20)
+ elseif ( type == "select" ) then
+ local items = v[4]
+ module.Opt[dbval] = NewSelectBox(module, "SLDT"..title..name, db, dbval, name, items, isGlobal)
+ height = math.floor(height+16)
+ module.Opt[dbval]:SetPoint("TOPLEFT", module.Opt, "TOPLEFT", -7, math.floor(0-height))
+ height = math.floor(height+28)
+ elseif ( type == "range" ) then
+ local min, max, step = v[4], v[5], v[6]
+ module.Opt[dbval] = NewSlider(module, "SLDT"..title..name, db, dbval, name, min, max, step, isGlobal)
+ height = math.floor(height+16)
+ module.Opt[dbval]:SetPoint("TOPLEFT", module.Opt, "TOPLEFT", 15, math.floor(0-height))
+ height = math.floor(height+26)
+ elseif ( type == "text" ) then
+ module.Opt[dbval] = NewEditBox(module, "SLDT"..title..name, db, dbval, name, isGlobal)
+ height = math.floor(height+16)
+ module.Opt[dbval]:SetPoint("TOPLEFT", module.Opt, "TOPLEFT", 15, math.floor(0-height))
+ height = math.floor(height+20)
+ elseif ( type == "desc" ) then
+ module.Opt[name] = NewDesc(module, "SLDT"..title..name, dbval)
+ height = math.floor(height+6)
+ module.Opt[name]:SetPoint("TOPLEFT", module.Opt, "TOPLEFT", 15, math.floor(0-height))
+ height = math.floor((height+module.Opt[name]:GetHeight())+6)
+ elseif ( type == "profile" ) then
+ if ( dbval == "Current" ) then
+ module.Opt["Profile"..name] = ProfileDesc(module, "SLDT_Profile"..name)
+ height = math.floor(height+2)
+ module.Opt["Profile"..name]:SetPoint("TOPLEFT", module.Opt, "TOPLEFT", 15, math.floor(0-height))
+ height = math.floor((height+module.Opt["Profile"..name]:GetHeight())+6)
+ elseif ( dbval == "New" ) then
+ module.Opt["Profile"..name] = ProfileNewBox(module, "SLDT_Profile"..name)
+ height = math.floor(height+16)
+ module.Opt["Profile"..name]:SetPoint("TOPLEFT", module.Opt, "TOPLEFT", 15, math.floor(0-height))
+ height = math.floor(height+20)
+ elseif ( dbval == "Copy" ) then
+ module.Opt["Profile"..name] = ProfileCopyBox(module, "SLDT_Profile"..name)
+ height = math.floor(height+16)
+ module.Opt["Profile"..name]:SetPoint("TOPLEFT", module.Opt, "TOPLEFT", -7, math.floor(0-height))
+ height = math.floor(height+28)
+ elseif ( dbval == "Reset" ) then
+ module.Opt["Profile"..name] = ProfileReset(module, "SLDT_Profile"..name, v[4])
+ height = math.floor(height+12)
+ module.Opt["Profile"..name]:SetPoint("TOPLEFT", module.Opt, "TOPLEFT", 15, math.floor(0-height))
+ height = math.floor(height+28)
+ elseif ( dbval == "Delete" ) then
+ module.Opt["Profile"..name] = ProfileDeleteBox(module, "SLDT_Profile"..name)
+ height = math.floor(height+16)
+ module.Opt["Profile"..name]:SetPoint("TOPLEFT", module.Opt, "TOPLEFT", -7, math.floor(0-height))
+ height = math.floor(height+28)
+ end
+ end
+ end
+
+ height = math.floor(height+10)
+ module.Opt:SetHeight(height)
+end
+
+function lib:OpenOptBox(module)
+ if ( not module.Opt ) then self:CreateMenu(module.db.profile.name, module, module.optsTbl) end
+ module.Opt:Show()
+end
\ No newline at end of file
diff --git a/Libs/LibSLTip-1.0/LibSLTip-1.0.lua b/Libs/LibSLTip-1.0/LibSLTip-1.0.lua
new file mode 100644
index 0000000..e9cb7a1
--- /dev/null
+++ b/Libs/LibSLTip-1.0/LibSLTip-1.0.lua
@@ -0,0 +1,377 @@
+--[[ LibSLTip-1.0 - Interactive Tooltip Handler ]]
+--[[ Use to create & manage interactive and functional tooltips ]]
+
+-- Rev 9/01/12: Revised Tooltip Max Width
+-- Rev 8/02/18: Fixed issue with depreciated screen resolution functions.
+
+local MAJOR, MINOR = "LibSLTip-1.0", 13
+local lib = LibStub:NewLibrary(MAJOR, MINOR)
+if not lib then return end
+local function err(msg) ChatFrame1:AddMessage(string.format("LibSLTip: %s", msg)) end
+
+local diaBG = {
+ bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
+ edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
+ tile = true, tileSize = 16, edgeSize = 16,
+ insets = { left = 4, right = 4, top = 4, bottom = 4 }
+}
+local solBG = {
+ bgFile = "Interface\\BUTTONS\\WHITE8X8",
+ edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
+ tile = true, tileSize = 16, edgeSize = 16,
+ insets = { left = 4, right = 4, top = 4, bottom = 4 }
+}
+local anchTbl = {
+ ["TOPLEFT"] = "BOTTOMLEFT", ["TOP"] = "BOTTOM", ["TOPRIGHT"] = "BOTTOMRIGHT",
+ ["LEFT"] = "TOPLEFT", ["CENTER"] = "TOP", ["RIGHT"] = "TOPRIGHT",
+ ["BOTTOMLEFT"] = "TOPLEFT", ["BOTTOM"] = "TOP", ["BOTTOMRIGHT"] = "TOPRIGHT",
+}
+local anchFix = { ["LEFT"] = "BOTTOMLEFT", ["CENTER"] = "BOTTOM", ["RIGHT"] = "BOTTOMRIGHT" }
+
+local toolTips, cushion, lspace, resX, resY = {}, 10, 4
+
+do
+ -- I'm not doing this every time I anchor...if the resolution changes, screw it...just ReloadUI
+ local res = ({GetCurrentScaledResolution()}) --({GetCurrentScaledResolution()})[GetCurrentResolution()]
+ resX, resY = res[1], res[2] --string.split("x", res)
+end
+
+local function SmartAnchor(name, anchor)
+ local top, bottom, left, right = anchor:GetTop(), anchor:GetBottom(), anchor:GetLeft(), anchor:GetRight()
+ local xVal, yVal, fix, xBuff, pos = nil, nil, false, floor((resX * 0.3) / 2)
+
+ -- Vertical check
+ if ( top > resY / 2 and bottom > resY / 2 ) then yVal = "TOP"
+ elseif ( top >= resY / 2 and bottom <= resY / 2 ) then yVal = nil
+ elseif ( top < resY / 2 and bottom < resY / 2 ) then yVal = "BOTTOM" end
+ -- Horizontal check
+ if ( right + xBuff > resX / 2 and left - xBuff > resX / 2 ) then xVal = "RIGHT"
+ elseif ( right + xBuff >= resX / 2 and left - xBuff <= resX / 2 ) then xVal = nil
+ elseif ( right + xBuff < resX / 2 and left - xBuff < resX / 2 ) then xVal = "LEFT" end
+
+ -- Put it all together, and what do you get?
+ if ( yVal and xVal ) then
+ pos = string.format("%s%s", yVal, xVal)
+ else
+ if ( xVal and yVal == nil ) then
+ pos = xVal; fix = true
+ elseif ( xVal == nil and yVal ) then
+ pos = yVal -- Don't fix cause we can compensate for TOP or BOTTOM alignment
+ else
+ pos = "CENTER"; fix = true
+ end
+ end
+
+ toolTips[name].frame:ClearAllPoints()
+ toolTips[name].frame:SetPoint(fix and anchFix[pos] or pos, anchor, anchTbl[pos], 0, 0)
+end
+
+local underlineFrame = CreateFrame("Frame", nil)
+underlineFrame.tx = underlineFrame:CreateTexture()
+underlineFrame.tx:SetTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight")
+underlineFrame.tx:SetBlendMode("ADD")
+underlineFrame:SetAlpha(0.75)
+underlineFrame:SetScript("OnHide", function(this) this:Hide(); end)
+underlineFrame:SetScript("OnShow", function(this)
+ underlineFrame.tx:SetPoint("TOPLEFT", 0, 0)
+ underlineFrame.tx:SetPoint("RIGHT", 0, 0)
+end)
+
+local function UpdateFrameSizes(name, width, height, widthDbl)
+ if ( widthDbl ~= nil ) then
+ local line = math.floor((width + widthDbl) + (cushion * 2))
+ width = math.floor(line + (cushion * 2))
+ else
+ width = math.floor(width + (cushion * 2))
+ end
+ height = math.floor(height + lspace)
+
+ -- Adjustments to cap width and ensure long subheaders wrap
+ if ( width > 380 ) then width = 380 end
+
+ toolTips[name].width = max(toolTips[name].width, width)
+ toolTips[name].height = math.floor(toolTips[name].height + height)
+
+ -- if ( toolTips[name].subheader ) then toolTips[name].subheader:SetWidth(toolTips[name].width) end
+
+ if ( toolTips[name].spacers > 0 ) then
+ for i = 1, toolTips[name].spacers do
+ toolTips[name]["Spacer"..i]:SetWidth(math.floor(toolTips[name].width - (cushion * 2)))
+ end
+ end
+end
+
+function lib:GetTooltip(name, interactive)
+ if ( type(name) ~= "string" ) then error("Usage: GetTooltip(name, guild, motto) - 'name': string expected.", 2) end
+
+ toolTips[name] = toolTips[name] or {}
+ toolTips[name].frame = CreateFrame("Frame", name.."Tooltip", UIParent, BackdropTemplateMixin and "BackdropTemplate")
+ toolTips[name].frame:SetBackdrop({
+ edgeSize = 24,
+ edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border", tile = true,
+ bgFile = "Interface\\FrameGeneral\\UI-Background-Marble", tile = true, tileSize = 256,
+ insets = { left = 3, right = 3, top = 3, bottom = 3 }
+ })
+ toolTips[name].frame:EnableMouse(true)
+ toolTips[name].frame:SetClampedToScreen(true)
+ toolTips[name].frame:SetFrameStrata("FULLSCREEN_DIALOG")
+ toolTips[name].frame:Hide()
+
+ if ( interactive ) then
+ toolTips[name].frame:SetHitRectInsets(1, 1, 1, 0)
+ toolTips[name].frame:SetScript("OnEnter", function(this) this:Show() end)
+ toolTips[name].frame:SetScript("OnLeave", function(this) self:ClearTooltip(name) end)
+ end
+
+ toolTips[name].width = 0
+ toolTips[name].height = cushion
+ toolTips[name].spacers = 0
+
+ return toolTips[name].frame
+end
+
+function lib:AddHeader(name, header, subheader, subColor)
+ if ( type(name) ~= "string" ) then error("Usage: AddHeader(name, header, subheader) - 'name': string expected.", 2) end
+ if ( type(header) ~= "string" ) then error("Usage: AddHeader(name, header, subheader) - 'header': string expected.", 2) end
+ if ( subheader and type(subheader) ~= "string" ) then error("Usage: AddHeader(name, header, subheader) - 'subheader': string expected.", 2) end
+ if ( not toolTips[name] ) then error("Tooltip does not exist, cannot create header.", 2) end
+
+ toolTips[name].header = toolTips[name].frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
+ toolTips[name].header:SetFont(toolTips[name].header:GetFont(), 14, "")
+ toolTips[name].header:SetText(header)
+ toolTips[name].header:ClearAllPoints()
+ toolTips[name].header:SetPoint("TOPLEFT", toolTips[name].frame, "TOPLEFT", cushion, math.floor(0 - toolTips[name].height))
+
+ UpdateFrameSizes(name, toolTips[name].header:GetWidth(), toolTips[name].header:GetHeight())
+
+ if ( subheader ) then
+ toolTips[name].subheader = toolTips[name].frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
+ toolTips[name].subheader:SetFont(toolTips[name].subheader:GetFont(), 11, "")
+ toolTips[name].subheader:SetWordWrap(true)
+ toolTips[name].subheader:SetNonSpaceWrap(false)
+ toolTips[name].subheader:SetJustifyH("LEFT")
+ toolTips[name].subheader:SetText(subheader)
+ if ( toolTips[name].subheader:GetWidth() > 300 - (cushion * 2) ) then
+ toolTips[name].subheader:SetWidth(300 - (cushion * 2))
+ end
+ if ( subColor ) then toolTips[name].subheader:SetTextColor(unpack(subColor)) end
+ toolTips[name].subheader:ClearAllPoints()
+ toolTips[name].subheader:SetPoint("TOPLEFT", toolTips[name].frame, "TOPLEFT", cushion, math.floor(0 - toolTips[name].height))
+ toolTips[name].subheader:SetPoint("TOPRIGHT", toolTips[name].frame, "TOPRIGHT", math.floor(0 - cushion), math.floor(0 - toolTips[name].height))
+
+ UpdateFrameSizes(name, toolTips[name].subheader:GetWidth(), toolTips[name].subheader:GetHeight())
+ end
+
+ toolTips[name].spacers = toolTips[name].spacers + 1
+ toolTips[name]["Spacer"..toolTips[name].spacers] = toolTips[name].frame:CreateTexture()
+ toolTips[name]["Spacer"..toolTips[name].spacers]:SetTexture(1,1,0.5,0.75)
+ toolTips[name]["Spacer"..toolTips[name].spacers]:SetHeight(1)
+ toolTips[name]["Spacer"..toolTips[name].spacers]:ClearAllPoints()
+ toolTips[name]["Spacer"..toolTips[name].spacers]:SetPoint("TOPLEFT", toolTips[name].frame, "TOPLEFT", cushion, math.floor(0 - toolTips[name].height))
+
+ UpdateFrameSizes(name, 0, toolTips[name]["Spacer"..toolTips[name].spacers]:GetHeight())
+end
+
+function lib:AddSpacer(name)
+ if ( type(name) ~= "string" ) then error("Usage: AddSpacer(name) - 'name': string expected.", 2) end
+
+ toolTips[name].spacers = toolTips[name].spacers + 1
+ toolTips[name]["Spacer"..toolTips[name].spacers] = toolTips[name].frame:CreateTexture()
+ toolTips[name]["Spacer"..toolTips[name].spacers]:SetTexture(1,1,0.5,0.75)
+ toolTips[name]["Spacer"..toolTips[name].spacers]:SetHeight(1)
+ toolTips[name]["Spacer"..toolTips[name].spacers]:ClearAllPoints()
+ toolTips[name]["Spacer"..toolTips[name].spacers]:SetPoint("TOPLEFT", toolTips[name].frame, "TOPLEFT", cushion, math.floor(0 - toolTips[name].height))
+
+ UpdateFrameSizes(name, 0, toolTips[name]["Spacer"..toolTips[name].spacers]:GetHeight())
+end
+
+function lib:AddLine(name, line, lineColor, interactive, func)
+ if ( type(name) ~= "string" ) then error("Usage: AddLine(name, line, lineColor) - 'name': string expected.", 2) end
+ if ( type(line) ~= "string" ) then error("Usage: AddLine(name, line, lineColor) - 'line': string expected.", 2) end
+ if ( lineColor and type(lineColor) ~= "table" ) then error("Usage: AddLine(name, line, lineColor) - 'lineColor': table expected.", 2) end
+
+ local tline = toolTips[name].frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
+ tline:SetFont(tline:GetFont(), 11, "")
+ tline:SetTextColor(1, 1, 1)
+ tline:SetWordWrap(false)
+ tline:SetText(line)
+ if ( lineColor ) then tline:SetTextColor(unpack(lineColor)) end
+
+ if ( interactive ) then
+ local button = CreateFrame("Button")
+ button:SetParent(toolTips[name].frame)
+ button:ClearAllPoints(); button:SetPoint("TOPLEFT", tline, 0, 0); button:SetPoint("BOTTOMRIGHT", tline, 0, 0)
+
+ button:SetScript("OnClick", func)
+ button:SetScript("OnEnter", function(this)
+ toolTips[name].frame:Show()
+
+ underlineFrame:SetParent(this)
+ underlineFrame:SetHeight(0.6 / this:GetEffectiveScale())
+ underlineFrame:SetPoint("BOTTOMLEFT", this, 0, -2/this:GetEffectiveScale())
+ underlineFrame:SetPoint("TOPRIGHT", this, 0, 1/this:GetEffectiveScale())
+ underlineFrame:SetFrameLevel(1)
+ underlineFrame:Show()
+ end)
+ button:SetScript("OnLeave", function(this)
+ underlineFrame:Hide()
+ toolTips[name].frame:Hide()
+ end)
+ end
+
+ tline:ClearAllPoints()
+ tline:SetPoint("TOPLEFT", toolTips[name].frame, "TOPLEFT", cushion, math.floor(0 - toolTips[name].height))
+
+ UpdateFrameSizes(name, tline:GetWidth(), tline:GetHeight())
+end
+
+function lib:AddDoubleLine(name, line1, line2, lineColor1, lineColor2, interactive, func)
+ if ( type(name) ~= "string" ) then error("Usage: AddDoubleLine(name, line1, line2, [lineColor1, lineColor2, interactive, func]) - 'name': string expected.", 2) end
+ if ( type(line1) ~= "string" ) then error("Usage: AddDoubleLine(name, line1, line2, [lineColor1, lineColor2, interactive, func]) - 'line1': string expected.", 2) end
+ if ( type(line2) ~= "string" ) then error("Usage: AddDoubleLine(name, line1, line2, [lineColor1, lineColor2, interactive, func]) - 'line2': string expected.", 2) end
+ if ( lineColor1 and type(lineColor1) ~= "table" ) then error("Usage: AddDoubleLine(name, line1, line2, [lineColor1, lineColor2, interactive, func]) - 'lineColor1': table expected.", 2) end
+ if ( lineColor2 and type(lineColor2) ~= "table" ) then error("Usage: AddDoubleLine(name, line1, line2, [lineColor1, lineColor2, interactive, func]) - 'lineColor2': table expected.", 2) end
+
+ local tline1 = toolTips[name].frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
+ local tline2 = toolTips[name].frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
+
+ tline1:SetFont(tline1:GetFont(), 11, "");
+ tline2:SetFont(tline2:GetFont(), 11, "")
+ tline1:SetWordWrap(false);
+ tline2:SetWordWrap(false)
+ tline1:SetText(line1);
+ tline2:SetText(line2)
+
+ if ( lineColor1 ) then tline1:SetTextColor(unpack(lineColor1)) else tline1:SetTextColor(1, 1, 1) end
+ if ( lineColor2 ) then tline2:SetTextColor(unpack(lineColor2)) else tline2:SetTextColor(1, 1, 1) end
+
+ if ( interactive ) then
+ local button = CreateFrame("Button")
+ button:SetParent(toolTips[name].frame)
+ button:ClearAllPoints(); button:SetPoint("TOPLEFT", tline1, 0, 0); button:SetPoint("BOTTOMRIGHT", tline2, 0, 0)
+
+ button:SetScript("OnClick", func)
+ button:SetScript("OnEnter", function(this)
+ toolTips[name].frame:Show()
+
+ underlineFrame:SetParent(this)
+ underlineFrame:SetHeight(0.6 / this:GetEffectiveScale())
+ underlineFrame:SetPoint("BOTTOMLEFT", this, 0, -2/this:GetEffectiveScale())
+ underlineFrame:SetPoint("TOPRIGHT", this, 0, 1/this:GetEffectiveScale())
+ underlineFrame:SetFrameLevel(1)
+ underlineFrame:Show()
+ end)
+ button:SetScript("OnLeave", function(this)
+ underlineFrame:Hide(); toolTips[name].frame:Hide()
+ end)
+ end
+
+ tline1:ClearAllPoints()
+ tline1:SetPoint("TOPLEFT", toolTips[name].frame, "TOPLEFT", cushion, math.floor(0 - toolTips[name].height))
+ tline2:ClearAllPoints()
+ tline2:SetPoint("TOPRIGHT", toolTips[name].frame, "TOPRIGHT", math.floor(0 - cushion), math.floor(0 - toolTips[name].height))
+
+ UpdateFrameSizes(name, tline1:GetWidth(), tline1:GetHeight(), tline2:GetWidth())
+end
+
+local firstFoot = true
+function lib:AddFooter(name, line, lineColor)
+ if ( type(name) ~= "string" ) then error("Usage: AddFooter(name, line, lineColor) - 'name': string expected.", 2) end
+ if ( type(line) ~= "string" ) then error("Usage: AddFooter(name, line, lineColor) - 'line': string expected.", 2) end
+ if ( lineColor and type(lineColor) ~= "table" ) then error("Usage: AddFooter(name, line, lineColor) - 'lineColor': table expected.", 2) end
+
+ if ( firstFoot ) then toolTips[name].height = toolTips[name].height + cushion; firstFoot = false end
+
+ local foot = toolTips[name].frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
+ foot:SetFont(foot:GetFont(), 11, "")
+ foot:SetTextColor(1, 1, 0)
+ foot:SetWordWrap(false)
+ foot:SetText(line)
+ if ( lineColor ) then foot:SetTextColor(lineColor) end
+
+ foot:ClearAllPoints()
+ foot:SetPoint("TOPLEFT", toolTips[name].frame, "TOPLEFT", cushion, math.floor(0 - toolTips[name].height))
+
+ UpdateFrameSizes(name, foot:GetWidth(), foot:GetHeight())
+end
+
+function lib:AddStatusBar(name, line, minV, maxV, curV, barColor, texture, isTimer)
+ if ( type(name) ~= "string" ) then error("Usage: AddStatusBar - 'name': string expected.", 2) end
+ if ( type(line) ~= "string" ) then error("Usage: AddStatusBar - 'line': string expected.", 2) end
+ if ( type(minV) ~= "number" ) then error("Usage: AddStatusBar - 'minV': number expected.", 2) end
+ if ( type(maxV) ~= "number" ) then error("Usage: AddStatusBar - 'maxV': number expected.", 2) end
+ if ( curV and type(curV) ~= "number" ) then error("Usage: AddStatusBar - 'curV': number expected.", 2) end
+ if ( barColor and type(barColor) ~= "table" ) then error("Usage: AddStatusBar - 'barColor': table expected.", 2) end
+ if ( texture and type(texture) ~= "string" ) then error("Usage: AddStatusBar - 'texture': table expected.", 2) end
+
+ local tline = toolTips[name].frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
+ local sbar = CreateFrame("StatusBar")
+
+ tline:SetFont(tline:GetFont(), 11, "")
+ tline:SetWordWrap(false)
+ tline:SetText(line)
+
+ sbar:SetParent(toolTips[name].frame)
+ sbar:SetWidth(100)
+ sbar:SetHeight(tline:GetHeight()-2)
+ sbar:SetStatusBarTexture(texture or "Interface\\TargetingFrame\\UI-StatusBar")
+ sbar:SetStatusBarColor(barColor or 1, 0, 1)
+ sbar:SetFrameLevel(2)
+
+ sbar.border = CreateFrame("Frame", nil, nil, BackdropTemplateMixin and "BackdropTemplate")
+ sbar.border:SetParent(sbar)
+ sbar.border:SetWidth(sbar:GetWidth()+2)
+ sbar.border:SetHeight(sbar:GetHeight()+2)
+ sbar.border:SetPoint("CENTER", 0, 0)
+ sbar.border:SetBackdrop({
+ bgFile = "Interface\\BUTTONS\\WHITE8X8",
+ edgeFile = "Interface\\BUTTONS\\WHITE8X8",
+ tile = false, edgeSize = 1,
+ insets = { left = 0, right = 0, top = 0, bottom = 0 }
+ })
+ sbar.border:SetBackdropColor(0,0,0,1)
+ sbar.border:SetBackdropBorderColor(.3,.3,.3,1)
+ sbar.border:SetFrameLevel(1)
+
+ if ( isTimer ) then
+ -- minV becomes start time, maxV becomes end time, curV can becomes nil because we rely on GetTime()
+ sbar:SetScript("OnUpdate", function(self)
+ sbar:SetMinMaxValues(minV, maxV)
+ if ( GetTime() < maxV ) then
+ sbar:SetValue(GetTime())
+ else
+ sbar:SetScript("OnUpdate", nil)
+ end
+ end)
+ else
+ sbar:SetMinMaxValues(minV, maxV)
+ sbar:SetValue(curV)
+ end
+
+ tline:ClearAllPoints()
+ tline:SetPoint("TOPLEFT", toolTips[name].frame, "TOPLEFT", cushion, math.floor(0 - toolTips[name].height))
+ sbar:ClearAllPoints()
+ sbar:SetPoint("TOPRIGHT", toolTips[name].frame, "TOPRIGHT", math.floor(0 - cushion), math.floor(0 - toolTips[name].height))
+
+ UpdateFrameSizes(name, tline:GetWidth(), tline:GetHeight(), sbar:GetWidth())
+end
+
+function lib:ShowTooltip(name, anchor)
+ if ( type(name) ~= "string" ) then error("Usage: ClearTooltip(name) - 'name': string expected.", 2) end
+ if ( not toolTips[name] ) then error("Tooltip does not exist, cannot show.", 2) end
+
+ toolTips[name].frame:SetWidth(toolTips[name].width)
+ -- Add cushion on Show() so we don't have to do running calculations for line spacing.
+ toolTips[name].frame:SetHeight(math.floor(toolTips[name].height + cushion))
+ toolTips[name].frame:SetScale(SLDataText.db.profile.ttScale)
+
+ SmartAnchor(name, anchor)
+ toolTips[name].frame:Show()
+end
+
+function lib:ClearTooltip(name)
+ if ( type(name) ~= "string" ) then error("Usage: ClearTooltip(name) - 'name': string expected.", 2) end
+ if ( not firstFoot ) then firstFoot = true end
+
+ toolTips[name].frame:Hide()
+end
\ No newline at end of file
diff --git a/Libs/LibSharedMedia-3.0/LibSharedMedia-3.0.lua b/Libs/LibSharedMedia-3.0/LibSharedMedia-3.0.lua
new file mode 100644
index 0000000..8129a82
--- /dev/null
+++ b/Libs/LibSharedMedia-3.0/LibSharedMedia-3.0.lua
@@ -0,0 +1,301 @@
+--@curseforge-project-slug: libsharedmedia-3-0@
+--[[
+Name: LibSharedMedia-3.0
+Revision: $Revision: 128 $
+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", 8020003 -- 8.2.0 v3 / 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_sort = _G.table.sort
+
+local RESTRICTED_FILE_ACCESS = WOW_PROJECT_ID == WOW_PROJECT_MAINLINE -- starting with 8.2, some rules for file access have changed; classic still uses the old way
+
+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.MediaTable.statusbar["Solid"] = [[Interface\Buttons\WHITE8X8]]
+lib.DefaultMedia.statusbar = "Blizzard"
+
+-- SOUND
+if not lib.MediaTable.sound then lib.MediaTable.sound = {} end
+lib.MediaTable.sound["None"] = RESTRICTED_FILE_ACCESS and 1 or [[Interface\Quiet.ogg]] -- Relies on the fact that PlaySound[File] doesn't error on these values.
+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
+ -- ignore fonts that aren't flagged as supporting local glyphs on non-western clients
+ 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
+ -- files accessed via path only allowed from interface folder
+ return false
+ end
+ if mediatype == lib.MediaType.SOUND and not (path:find(".ogg", nil, true) or path:find(".mp3", nil, true)) then
+ -- Only ogg and mp3 are valid sounds.
+ 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
diff --git a/Libs/LibSharedMedia-3.0/lib.xml b/Libs/LibSharedMedia-3.0/lib.xml
new file mode 100644
index 0000000..7313228
--- /dev/null
+++ b/Libs/LibSharedMedia-3.0/lib.xml
@@ -0,0 +1,4 @@
+
+
+
diff --git a/Libs/LibStub/LibStub.lua b/Libs/LibStub/LibStub.lua
new file mode 100644
index 0000000..7e7b76d
--- /dev/null
+++ b/Libs/LibStub/LibStub.lua
@@ -0,0 +1,51 @@
+-- $Id: LibStub.lua 103 2014-10-16 03:02:50Z mikk $
+-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/addons/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
diff --git a/Localization/deDE.lua b/Localization/deDE.lua
new file mode 100644
index 0000000..30cacc9
--- /dev/null
+++ b/Localization/deDE.lua
@@ -0,0 +1,178 @@
+if ( GetLocale() ~= "deDE" ) then return end
+
+local addon, ns = ...
+ns.L = {
+ -- Core Globals
+ ["Combat Fade"] = "Im Kampf ausblenden",
+ ["Class Colored"] = "Klassenfarben",
+ ["Global Font Size"] = "Allgemeine Schriftgre",
+ ["ProfDesc"] = "Neues Profil erstellen oder von einem existierenden kopieren. Kopiere die aktuellen Einstellungen in das aktive Profil",
+ ["ProfResDesc"] = "Reset Profile",
+ ["ProfNew"] = "Neues Profil",
+ ["ProfReset"] = "Reset",
+ ["ProfCurrent"] = "Aktuelles Profil",
+ ["ProfCopy"] = "Profil kopieren",
+ ["ProfDel"] = "Delete",
+ ["/sldt"] = "/sldt",
+ ["Command List"] = "Sldt Befehle",
+ ["config"] = "Konfiguration",
+ ["Toggle Configuration Mode"] = "Toggle Configuration Mode",
+ ["Configuration Mode"] = "Konfigurations Modus",
+ ["active"] = "Aktiv",
+ ["inactive"] = "Inaktiv",
+ ["global"] = "Global",
+ ["Open SLDataText Global Menu"] = "Globales Config Men ffnen",
+ [""] = "",
+ ["Open Module Option Menu"] = "Modul Options Men ffnen",
+ ["Loaded Modules"] = "Geladene Module",
+ ["TTScale"] = "SLToolTip Scale",
+
+ -- Common
+ ["Enabled"] = "Enabled",
+ ["Global Font"] = "Global Font",
+ ["Outline"] = "Outline",
+ ["Force Shown"] = "Force Shown",
+ ["Tooltip On"] = "Tooltip On",
+ ["Show Tooltip (Combat)"] = "Show Tooltip (Combat)",
+ ["Font Size"] = "Font Size",
+ ["Font"] = "Font",
+ ["Justify"] = "Justify",
+ ["Parent"] = "Parent",
+ ["Anchor"] = "Anchor",
+ ["X Offset"] = "X Offset",
+ ["Y Offset"] = "Y Offset",
+ ["Frame Strata"] = "Frame Strata",
+ ["Update Interval"] = "Update Interval",
+ ["On"] = "On",
+ ["Off"] = "Off",
+ ["Prefix"] = "Prefix",
+ ["Prefix Text"] = "Prefix Text",
+ ["Suffix"] = "Suffix",
+ ["Suffix Text"] = "Suffix Text",
+ ["Left-Click"] = "Left-Click",
+ ["Right-Click"] = "Right-Click",
+ ["Show Icon"] = "Show Icon",
+ ["Show Text"] = "Show Text",
+ ["Text Display"] = "Text Display",
+
+ -- Armor Module
+ ["Armor"] = "Armor",
+ ["All Items"] = "All Items",
+ ["Auto Repair"] = "Auto Repair",
+ ["Use Guild Bank"] = "Use Guild Bank",
+ ["Armor"] = "Armor",
+ ["AutoRepairLine"] = "Items repaired for",
+ ["GFAutoRepairLine"] = "Items repaired for (Guild Funds)",
+ ["ArmorTextDesc"] = "Tags for Text Display: [Dur] = Current Durability",
+
+ -- Bag Module
+ ["Bag Info"] = "Bag Info",
+ ["Space Used"] = "Space Used",
+ ["Space Avail"] = "Space Avail",
+ ["Space Left"] = "Space Left",
+ ["AutoSell Junk"] = "AutoSell Junk",
+ ["JunkSoldLine"] = "Junk Sold Earned",
+ ["Toggle Bags"] = "Toggle Bags",
+ ["BagTextDesc"] = "Tags for Text Display: [T] = Total, [R] = Remaining, [U] = Used",
+
+ -- Clock Module
+ ["Toggle Calendar"] = "Toggle Calendar",
+ ["Toggle Time Manager"] = "Toggle Time Manager",
+ ["Queued for:"] = "Queued for:",
+ ["Realm Time"] = "Realm Time",
+ ["24 Hour"] = "24 Hour",
+ ["PvP Info"] = "PvP Info",
+ ["Time String"] = "Time String",
+ ["ClockDesc"] = "Visit http://www.lua.org/pil/22.1.html for a full list of clock tags. Turn 'Correct Hour' option off if hour tag is not first in the time string.",
+ ["CorrHour"] = "Correct Hour",
+
+ -- Coords Module
+ ["Precision"] = "Precision",
+
+ -- Currency Module
+ ["Currency"] = "Currency",
+ ["No Currency"] = "No Currency",
+ ["Click to set display currency."] = "Click to set display currency.",
+ ["Display Currency"] = "Display Currency",
+
+ -- Exp Module
+ ["Max Level Hide"] = "Max Level Hide",
+ ["Exp"] = "Exp",
+ ["ExpTextDesc"] = "Tags for Text Display: [Cur] = Current XP, [Max] = Max XP, [Rem] = Remaining XP, [Per] = XP Percent, [PerR] = XP Remaining Percent, [R] = Rest XP, [RP] = Rest XP Percent",
+
+ -- FPS Module
+ ["fps"] = "fps",
+ ["FPSTextDesc"] = "Tags for Text Display: [F] = Current FPS",
+
+ -- Friends Module
+ ["Show Note"] = "Show Note",
+ ["ClickDesc"] = "Click to send tell.",
+ ["AltClickDesc"] = "Alt+Click to invite.",
+ ["Friend List"] = "Friend List",
+ ["Friends"] = "Friends",
+ ["Friends Online"] = "Friends Online",
+ ["BNet Friends"] = "BNet Friends",
+ ["Note"] = "Note",
+ ["(AFK)"] = "(AFK)",
+ ["(DND)"] = "(DND)",
+
+ -- Gold Module
+ ["Wallet"] = "Wallet",
+ ["Current"] = "Current",
+ ["Session Start"] = "Session Start",
+ ["Session Earned"] = "Session Earned",
+ ["Server Gold"] = "Server Gold",
+ ["Horde"] = "Horde",
+ ["Alliance"] = "Alliance",
+ ["Total Gold"] = "Total Gold",
+ ["Display Style"] = "Display Style",
+ ["Alt Money"] = "Alt Money",
+ ["ResetData"] = "Reset Data",
+
+ -- Guild Module
+ ["Show Officer Note"] = "Show Officer Note",
+ ["No Guild"] = "No Guild",
+ ["Guild"] = "Guild",
+
+ -- Latency Module
+ ["Latency"] = "Latency",
+ ["Bandwidth In"] = "Bandwidth In",
+ ["Bandwidth Out"] = "Bandwidth Out",
+ ["Latency (Home)"] = "Latency (Home)",
+ ["Latency (World)"] = "Latency (World)",
+ ["ms"] = "ms",
+ ["LagTextDesc"] = "Tags for Text Display: [L] = Current Latency",
+
+ -- Mail Module
+ ["No Mail"] = "No Mail",
+ ["Mail!"] = "Mail!",
+ ["AH Alert!"] = "AH Alert!",
+ ["Play Sounds"] = "Play Sounds",
+
+ -- Memory Module
+ ["AddOn Memory"] = "AddOn Memory",
+ ["Showing Top 15 AddOns"] = "Showing Top 15 AddOns",
+ ["Total AddOn Memory"] = "Total AddOn Memory",
+ ["Total UI Memory Usage"] = "Total UI Memory Usage",
+ ["Hover"] = "Hover",
+ ["Show only top AddOns"] = "Show only top AddOns",
+ ["Alt+Hover"] = "Alt+Hover",
+ ["Show all AddOns"] = "Show all AddOns",
+ ["Collect Garbage"] = "Collect Garbage",
+ ["mb"] = "mb",
+ ["MemTextDesc"] = "Tags for Text Display: [MA] = Addon Memory, [MT] = Total Memory",
+
+ -- Reputation Module
+ ["Reputation"] = "Reputation",
+ ["No Reputation"] = "No Reputation",
+ ["Click to set display reputation."] = "Click to set display reputation.",
+ ["Display Reputation"] = "Display Reputation",
+ ["Hated"] = "Hated",
+ ["Hostile"] = "Hostile",
+ ["Unfriendly"] = "Unfriendly",
+ ["Neutral"] = "Neutral",
+ ["Friendly"] = "Friendly",
+ ["Honored"] = "Honored",
+ ["Revered"] = "Revered",
+ ["Exalted"] = "Exalted",
+}
\ No newline at end of file
diff --git a/Localization/enUS.lua b/Localization/enUS.lua
new file mode 100644
index 0000000..3722e5f
--- /dev/null
+++ b/Localization/enUS.lua
@@ -0,0 +1,179 @@
+if ( GetLocale() ~= "enUS" ) then return end
+
+local addon, ns = ...
+ns.L = {
+ -- Core Globals
+ ["Combat Fade"] = "Combat Fade",
+ ["Class Colored"] = "Class Colored",
+ ["Global Font Size"] = "Global Font Size",
+ ["ProfDesc"] = "Create new or copy existing profiles. Default profiles set to character.",
+ ["ProfResDesc"] = "Reset Profile",
+ ["ProfNew"] = "New",
+ ["ProfReset"] = "Reset",
+ ["ProfCurrent"] = "Current",
+ ["ProfCopy"] = "Copy",
+ ["ProfDel"] = "Delete",
+ ["/sldt"] = "/sldt",
+ ["Command List"] = "Command List",
+ ["config"] = "config",
+ ["Toggle Configuration Mode"] = "Toggle Configuration Mode",
+ ["Configuration Mode"] = "Configuration Mode",
+ ["active"] = "active",
+ ["inactive"] = "inactive",
+ ["global"] = "global",
+ ["Open SLDataText Global Menu"] = "Open SLDataText Global Menu",
+ [""] = "",
+ ["Open Module Option Menu"] = "Open Module Option Menu",
+ ["Loaded Modules"] = "Loaded Modules",
+ ["TTScale"] = "SLToolTip Scale",
+
+ -- Common
+ ["Enabled"] = "Enabled",
+ ["Global Font"] = "Global Font",
+ ["Outline"] = "Outline",
+ ["Force Shown"] = "Force Shown",
+ ["Tooltip On"] = "Tooltip On",
+ ["Show Tooltip (Combat)"] = "Show Tooltip (Combat)",
+ ["Font Size"] = "Font Size",
+ ["Font"] = "Font",
+ ["Justify"] = "Justify",
+ ["Parent"] = "Parent",
+ ["Anchor"] = "Anchor",
+ ["X Offset"] = "X Offset",
+ ["Y Offset"] = "Y Offset",
+ ["Frame Strata"] = "Frame Strata",
+ ["Update Interval"] = "Update Interval",
+ ["On"] = "On",
+ ["Off"] = "Off",
+ ["Prefix"] = "Prefix",
+ ["Prefix Text"] = "Prefix Text",
+ ["Suffix"] = "Suffix",
+ ["Suffix Text"] = "Suffix Text",
+ ["Left-Click"] = "Left-Click",
+ ["Right-Click"] = "Right-Click",
+ ["Show Icon"] = "Show Icon",
+ ["Show Text"] = "Show Text",
+ ["Text Display"] = "Text Display",
+
+ -- Armor Module
+ ["Armor"] = "Armor",
+ ["All Items"] = "All Items",
+ ["Auto Repair"] = "Auto Repair",
+ ["Use Guild Bank"] = "Use Guild Bank",
+ ["Armor"] = "Armor",
+ ["AutoRepairLine"] = "Items repaired for",
+ ["GFAutoRepairLine"] = "Items repaired for (Guild Funds)",
+ ["ArmorTextDesc"] = "Tags for Text Display: [Dur] = Current Durability",
+
+ -- Bag Module
+ ["Bag Info"] = "Bag Info",
+ ["Space Used"] = "Space Used",
+ ["Space Avail"] = "Space Avail",
+ ["Space Left"] = "Space Left",
+ ["AutoSell Junk"] = "AutoSell Junk",
+ ["JunkSoldLine"] = "Junk Sold Earned",
+ ["Toggle Bags"] = "Toggle Bags",
+ ["BagTextDesc"] = "Tags for Text Display: [T] = Total, [R] = Remaining, [U] = Used",
+
+ -- Clock Module
+ ["Toggle Calendar"] = "Toggle Calendar",
+ ["Toggle Time Manager"] = "Toggle Time Manager",
+ ["Queued for:"] = "Queued for:",
+ ["Realm Time"] = "Realm Time",
+ ["24 Hour"] = "24 Hour",
+ ["PvP Info"] = "PvP Info",
+ ["Time String"] = "Time String",
+ ["ClockDesc"] = "Visit http://www.lua.org/pil/22.1.html for a full list of clock tags. Turn 'Correct Hour' option off if hour tag is not first in the time string.",
+ ["CorrHour"] = "Correct Hour",
+
+ -- Coords Module
+ ["Precision"] = "Precision",
+
+ -- Currency Module
+ ["Currency"] = "Currency",
+ ["No Currency"] = "No Currency",
+ ["Click to set display currency."] = "Click to set display currency.",
+ ["Display Currency"] = "Display Currency",
+
+ -- Exp Module
+ ["Max Level Hide"] = "Max Level Hide",
+ ["Exp"] = "Exp",
+ ["ExpTextDesc"] = "Tags for Text Display: [Cur] = Current XP, [Max] = Max XP, [Rem] = Remaining XP, [Per] = XP Percent, [PerR] = XP Remaining Percent, [R] = Rest XP, [RP] = Rest XP Percent",
+
+ -- FPS Module
+ ["fps"] = "fps",
+ ["FPSTextDesc"] = "Tags for Text Display: [F] = Current FPS",
+
+ -- Friends Module
+ ["Show Note"] = "Show Note",
+ ["ClickDesc"] = "Click to send tell.",
+ ["AltClickDesc"] = "Alt+Click to invite.",
+ ["Show Icon"] = "Show Icon",
+ ["Friend List"] = "Friend List",
+ ["Friends"] = "Friends",
+ ["Friends Online"] = "Friends Online",
+ ["BNet Friends"] = "BNet Friends",
+ ["Note"] = "Note",
+ ["(AFK)"] = "(AFK)",
+ ["(DND)"] = "(DND)",
+
+ -- Gold Module
+ ["Wallet"] = "Wallet",
+ ["Current"] = "Current",
+ ["Session Start"] = "Session Start",
+ ["Session Earned"] = "Session Earned",
+ ["Server Gold"] = "Server Gold",
+ ["Horde"] = "Horde",
+ ["Alliance"] = "Alliance",
+ ["Total Gold"] = "Total Gold",
+ ["Display Style"] = "Display Style",
+ ["Alt Money"] = "Alt Money",
+ ["ResetData"] = "Reset Data",
+
+ -- Guild Module
+ ["Show Officer Note"] = "Show Officer Note",
+ ["No Guild"] = "No Guild",
+ ["Guild"] = "Guild",
+
+ -- Latency Module
+ ["Latency"] = "Latency",
+ ["Bandwidth In"] = "Bandwidth In",
+ ["Bandwidth Out"] = "Bandwidth Out",
+ ["Latency (Home)"] = "Latency (Home)",
+ ["Latency (World)"] = "Latency (World)",
+ ["ms"] = "ms",
+ ["LagTextDesc"] = "Tags for Text Display: [L] = Current Latency",
+
+ -- Mail Module
+ ["No Mail"] = "No Mail",
+ ["Mail!"] = "Mail!",
+ ["AH Alert!"] = "AH Alert!",
+ ["Play Sounds"] = "Play Sounds",
+
+ -- Memory Module
+ ["AddOn Memory"] = "AddOn Memory",
+ ["Showing Top 15 AddOns"] = "Showing Top 15 AddOns",
+ ["Total AddOn Memory"] = "Total AddOn Memory",
+ ["Total UI Memory Usage"] = "Total UI Memory Usage",
+ ["Hover"] = "Hover",
+ ["Show only top AddOns"] = "Show only top AddOns",
+ ["Alt+Hover"] = "Alt+Hover",
+ ["Show all AddOns"] = "Show all AddOns",
+ ["Collect Garbage"] = "Collect Garbage",
+ ["mb"] = "mb",
+ ["MemTextDesc"] = "Tags for Text Display: [MA] = Addon Memory, [MT] = Total Memory",
+
+ -- Reputation Module
+ ["Reputation"] = "Reputation",
+ ["No Reputation"] = "No Reputation",
+ ["Click to set display reputation."] = "Click to set display reputation.",
+ ["Display Reputation"] = "Display Reputation",
+ ["Hated"] = "Hated",
+ ["Hostile"] = "Hostile",
+ ["Unfriendly"] = "Unfriendly",
+ ["Neutral"] = "Neutral",
+ ["Friendly"] = "Friendly",
+ ["Honored"] = "Honored",
+ ["Revered"] = "Revered",
+ ["Exalted"] = "Exalted",
+}
\ No newline at end of file
diff --git a/Localization/frFR.lua b/Localization/frFR.lua
new file mode 100644
index 0000000..7ec0238
--- /dev/null
+++ b/Localization/frFR.lua
@@ -0,0 +1,178 @@
+if ( GetLocale() ~= "frFR" ) then return end
+
+local addon, ns = ...
+ns.L = {
+ -- Core Globals
+ ["Combat Fade"] = "Cachez-vous dans bataille",
+ ["Class Colored"] = "Classe de couleur",
+ ["Global Font Size"] = "Mondial Taille de la police",
+ ["ProfDesc"] = "Crer un nouveau ou copier les profils existants. Profils par dfaut mis caractre.",
+ ["ProfResDesc"] = "Reset Profile",
+ ["ProfNew"] = "Nouveau",
+ ["ProfReset"] = "Reset",
+ ["ProfCurrent"] = "Courant",
+ ["ProfCopy"] = "Copie",
+ ["ProfDel"] = "Delete",
+ ["/sldt"] = "/sldt",
+ ["Command List"] = "Liste des commandes",
+ ["config"] = "config",
+ ["Toggle Configuration Mode"] = "Basculer le mode de configuration",
+ ["Configuration Mode"] = "Mode de configuration",
+ ["active"] = "Actif",
+ ["inactive"] = "Inactives",
+ ["global"] = "mondial",
+ ["Open SLDataText global menu"] = "Ouvrez le menu SLDataText mondiale",
+ [""] = "",
+ ["Open Module Option Menu"] = "Ouvrir le menu Option module",
+ ["Loaded Modules"] = "Modules chargs",
+ ["TTScale"] = "SLToolTip Scale",
+
+ -- Common
+ ["Enabled"] = "Activ",
+ ["Global Font"] = "Font mondiale",
+ ["Outline"] = "Aperu",
+ ["Force Shown"] = "Voir dans bataille",
+ ["Tooltip On"] = "Sur Tooltip",
+ ["Show Tooltip (Combat)"] = "Show Tooltip (Combat)",
+ ["Font Size"] = "Taille de la police",
+ ["Font"] = "Type de police",
+ ["Justify"] = "Alignement du texte",
+ ["Parent"] = "Cadre parent",
+ ["Anchor"] = "D'ancrage",
+ ["X Offset"] = "X Alignement",
+ ["Y Offset"] = "Y Alignement",
+ ["Frame Strata"] = "Cadre strates",
+ ["Update Interval"] = "Mise jour Frquence",
+ ["On"] = "Sur",
+ ["Off"] = "Off",
+ ["Prefix"] = "Prfixe",
+ ["Prefix Text"] = "Prfixe Texte",
+ ["Suffix"] = "Suffixe",
+ ["Suffix Text"] = "Suffixe Texte",
+ ["Left-Click"] = "Clic gauche",
+ ["Right-Click"] = "Faites un clic droit",
+ ["Show Icon"] = "Afficher l'icne",
+ ["Show Text"] = "Afficher le texte",
+ ["Text Display"] = "Texte Affichage",
+
+ -- Armor Module
+ ["Armor"] = "Armures",
+ ["All Items"] = "Tous les Articles",
+ ["Auto Repair"] = "Automatique Rparation",
+ ["Use Guild Bank"] = "Use Guild Bank",
+ ["AutoRepairLine"] = "Articles rpar pour",
+ ["GFAutoRepairLine"] = "Articles rpar pour (Guild Funds)",
+ ["ArmorTextDesc"] = "Tags for Text Display: [Dur] = Current Durability",
+
+ -- Bag Module
+ ["Bag Info"] = "Sac Information",
+ ["Space Used"] = "Espace Utilis",
+ ["Space Avail"] = "Espace Disponibles",
+ ["Space Left"] = "Espace Restantes",
+ ["AutoSell Junk"] = "Jonque automatique Vendre",
+ ["JunkSoldLine"] = "Jonque vendu a gnr",
+ ["Toggle Bags"] = "Sacs Ouverts",
+ ["BagTextDesc"] = "Tags for Texte Affichage: [T] = Total, [R] = Remaining, [U] = Used",
+
+ -- Clock Module
+ ["Toggle Calendar"] = "Ouvrez Calendrier",
+ ["Toggle Time Manager"] = "Dlai ouvert",
+ ["Queued for:"] = "En file d'attente pour:",
+ ["Realm Time"] = "Heure du Serveur",
+ ["24 Hour"] = "24 heures",
+ ["PvP Info"] = "PvP informacin",
+ ["Time String"] = "Time String",
+ ["ClockDesc"] = "Visit http://www.lua.org/pil/22.1.html for a full list of clock tags. Turn 'Correct Hour' option off if hour tag is not first in the time string.",
+ ["CorrHour"] = "Correct Hour",
+
+ -- Coords Module
+ ["Precision"] = "Precisin",
+
+ -- Currency Module
+ ["Currency"] = "Devises",
+ ["No Currency"] = "Pas de devise",
+ ["Click to set display currency."] = "Cliquez dfinir la monnaie d'affichage.",
+ ["Display Currency"] = "Affichage Devises",
+
+ -- Exp Module
+ ["Max Level Hide"] = "Niveau max Cacher",
+ ["Exp"] = "Exp",
+ ["ExpTextDesc"] = "Tags for Text Display: [Cur] = Current XP, [Max] = Max XP, [Rem] = Remaining XP, [Per] = XP Percent, [PerR] = XP Remaining Percent, [R] = Rest XP, [RP] = Rest XP Percent",
+
+ -- FPS Module
+ ["fps"] = "fps",
+ ["FPSTextDesc"] = "Tags for Text Display: [F] = Current FPS",
+
+ -- Friends Module
+ ["Show Note"] = "Voir la note",
+ ["ClickDesc"] = "Cliquez ici pour envoyer dire.",
+ ["AltClickDesc"] = "Alt+Clic d'inviter.",
+ ["Show Icon"] = "Afficher l'icne",
+ ["Friend List"] = "Amis List",
+ ["Friends"] = "Amis",
+ ["Friends Online"] = "Amis Online",
+ ["BNet Friends"] = "BNet Amis",
+ ["Note"] = "Note",
+ ["(AFK)"] = "(AFK)",
+ ["(DND)"] = "(DND)",
+
+ -- Gold Module
+ ["Wallet"] = "Portefeuille",
+ ["Current"] = "Courant",
+ ["Session Start"] = "Dbut de session",
+ ["Session Earned"] = "Earned cette session",
+ ["Server Gold"] = "L'argent du serveur",
+ ["Horde"] = "Horde",
+ ["Alliance"] = "Alliance",
+ ["Total Gold"] = "L'argent total",
+ ["Display Style"] = "Style D'affichage",
+ ["Alt Money"] = "Alt Argent",
+ ["ResetData"] = "Reset Data",
+
+ -- Guild Module
+ ["Show Officer Note"] = "Voir la note officier",
+ ["No Guild"] = "Pas de Guild",
+ ["Guild"] = "Guilde",
+
+ -- Latency Module
+ ["Latency"] = "Latency",
+ ["Bandwidth In"] = "Bandwidth In",
+ ["Bandwidth Out"] = "Bandwidth Out",
+ ["Latency (Home)"] = "Latency (Home)",
+ ["Latency (World)"] = "Latency (World)",
+ ["ms"] = "ms",
+ ["LagTextDesc"] = "Tags for Text Display: [L] = Current Latency",
+
+ -- Mail Module
+ ["No Mail"] = "Pas de courrier",
+ ["Mail!"] = "Courrier!",
+ ["AH Alert!"] = "AH Alerte!",
+ ["Play Sounds"] = "Lire des sons",
+
+ -- Memory Module
+ ["AddOn Memory"] = "mmoire AddOn",
+ ["Showing Top 15 AddOns"] = "Affichage Top 15 AddOns",
+ ["Total AddOn Memory"] = "Mmoire totale AddOn",
+ ["Total UI Memory Usage"] = "Utilisation de la mmoire totale UI",
+ ["Hover"] = "Hover",
+ ["Show only top AddOns"] = "Show only top AddOns",
+ ["Alt+Hover"] = "Alt+Hover",
+ ["Show all AddOns"] = "Voir tous les AddOns",
+ ["Collect Garbage"] = "Ramasser les Ordures",
+ ["mb"] = "mb",
+ ["MemTextDesc"] = "Tags for Text Display: [MA] = Addon Memory, [MT] = Total Memory",
+
+ -- Reputation Module
+ ["Reputation"] = "Reputation",
+ ["No Reputation"] = "No Reputation",
+ ["Click to set display reputation."] = "Click to set display reputation.",
+ ["Display Reputation"] = "Display Reputation",
+ ["Hated"] = "Hated",
+ ["Hostile"] = "Hostile",
+ ["Unfriendly"] = "Unfriendly",
+ ["Neutral"] = "Neutral",
+ ["Friendly"] = "Friendly",
+ ["Honored"] = "Honored",
+ ["Revered"] = "Revered",
+ ["Exalted"] = "Exalted",
+}
\ No newline at end of file
diff --git a/Localization/ruRU.lua b/Localization/ruRU.lua
new file mode 100644
index 0000000..c49212e
--- /dev/null
+++ b/Localization/ruRU.lua
@@ -0,0 +1,159 @@
+if ( GetLocale() ~= "ruRU" ) then return end
+
+local addon, ns = ...
+ns.L = {
+ -- Core Globals
+ ["Combat Fade"] = "Скрыть в бою",
+ ["Class Colored"] = "Окраска классов",
+ ["Global Font Size"] = "Глобальный размер шрифта",
+ ["ProfDesc"] = "Создание нового или копию существующих профилей. По умолчанию профили набор к персонаж.",
+ ["ProfResDesc"] = "Reset Profile",
+ ["ProfNew"] = "новый",
+ ["ProfReset"] = "Reset",
+ ["ProfCurrent"] = "текущий",
+ ["ProfCopy"] = "копия",
+ ["ProfDel"] = "Delete",
+ ["/sldt"] = "/sldt",
+ ["Command List"] = "Список команд",
+ ["config"] = "конфиг",
+ ["Toggle Configuration Mode"] = "Переключить режим конфигурации",
+ ["Configuration Mode"] = "Режим конфигурации",
+ ["active"] = "активный",
+ ["inactive"] = "неактивный",
+ ["global"] = "глобальный",
+ ["Open SLDataText global menu"] = "Открытое SLDataText глобальное меню",
+ [""] = "<модуль>",
+ ["Open Module Option Menu"] = "Открыть меню Дополнительный модуль",
+ ["Loaded Modules"] = "Загруженные модули",
+ ["TTScale"] = "SLToolTip Scale",
+
+ -- Common
+ ["Enabled"] = "Включен",
+ ["Global Font"] = "Основной шрифт",
+ ["Outline"] = "Контур основного шрифта",
+ ["Force Shown"] = "Показать в бою",
+ ["Tooltip On"] = "Шоу подсказку",
+ ["Font Size"] = "Размер шрифта",
+ ["Font"] = "Шрифт",
+ ["Justify"] = "Выравнивание текста",
+ ["Parent"] = "Родительский",
+ ["Anchor"] = "Привязать к",
+ ["X Offset"] = "Смещение по X",
+ ["Y Offset"] = "Смещение по Y",
+ ["Frame Strata"] = "кадр Слои",
+ ["Update Interval"] = "Интервал обновления",
+ ["On"] = "на",
+ ["Off"] = "от",
+ ["Prefix"] = "префикс",
+ ["Prefix Text"] = "Префикс текст",
+ ["Suffix"] = "суффикс",
+ ["Suffix Text"] = "суффикс текст",
+ ["Left-Click"] = "Левый клик",
+ ["Right-Click"] = "право клик",
+ ["Show Icon"] = "Показать значок",
+ ["Show Text"] = "Показать текст",
+ ["Text Display"] = "текст дисплей",
+
+ -- Armor Module
+ ["Armor"] = "Доспехи",
+ ["All Items"] = "все пункт",
+ ["Auto Repair"] = "Авто-починка",
+ ["Use Guild Bank"] = "Исп. средства гильдии",
+ ["AutoRepairLine"] = "Cтоимость ремонта",
+ ["GFAutoRepairLine"] = "Cтоимость ремонта (Guild Funds)",
+ ["ArmorTextDesc"] = "Tags for Text Display: [Dur] = Current Durability",
+
+ -- Bag Module
+ ["Bag Info"] = "Сумки информация",
+ ["Space Used"] = "Пространство Зането",
+ ["Space Avail"] = "Пространство доступный",
+ ["Space Left"] = "Пространство бесплатно",
+ ["AutoSell Junk"] = "Авто продать барахло",
+ ["JunkSoldLine"] = "Нежелательная продал заработал",
+ ["Toggle Bags"] = "Переключить Сумки",
+ ["BagTextDesc"] = "Tags for текст дисплей: [T] = Total, [R] = Remaining, [U] = Used",
+
+ -- Clock Module
+ ["Toggle Calendar"] = "переключатель календарь",
+ ["Toggle Time Manager"] = "переключатель время менеджер",
+ ["Queued for:"] = "В очереди на:",
+ ["Realm Time"] = "Показать серверное время",
+ ["24 Hour"] = "24ч",
+ ["PvP Info"] = "PvP информации",
+ ["Time String"] = "Time String",
+ ["ClockDesc"] = "Visit http://www.lua.org/pil/22.1.html for a full list of clock tags. Turn 'Correct Hour' option off if hour tag is not first in the time string.",
+ ["CorrHour"] = "Correct Hour",
+
+ -- Coords Module
+ ["Precision"] = "Точность",
+
+ -- Currency Module
+ ["Currency"] = "Bалюта",
+ ["No Currency"] = "Нет Bалюта",
+ ["Click to set display currency."] = "Нажмите, чтобы установить дисплей валюты.",
+ ["Display Currency"] = "дисплей Bалюта",
+
+ -- Exp Module
+ ["Max Level Hide"] = "Скрыть уровне макс",
+ ["Exp"] = "Exp",
+ ["ExpTextDesc"] = "Tags for Text Display: [Cur] = Current XP, [Max] = Max XP, [Rem] = Remaining XP, [Per] = XP Percent, [PerR] = XP Remaining Percent, [R] = Rest XP, [RP] = Rest XP Percent",
+
+ -- FPS Module
+ ["fps"] = "fps",
+ ["FPSTextDesc"] = "Tags for Text Display: [F] = Current FPS",
+
+ -- Gold Module
+ ["Wallet"] = "бумажник",
+ ["Current"] = "текущий",
+ ["Session Start"] = "сессия начало",
+ ["Session Earned"] = "сессия заработанный",
+ ["Server Gold"] = "cервер золото",
+ ["Horde"] = "Орда",
+ ["Alliance"] = "Альянс",
+ ["Total Gold"] = "Всего золота",
+ ["Display Style"] = "стиль отображения",
+ ["Alt Money"] = "Alt Деньги",
+ ["ResetData"] = "Reset Data",
+
+ -- Latency Module
+ ["Latency"] = "Задержка",
+ ["Bandwidth In"] = "трафик в",
+ ["Bandwidth Out"] = "трафик из",
+ ["Latency (Home)"] = "Задержка (домой)",
+ ["Latency (World)"] = "Задержка (мир)",
+ ["ms"] = "мс",
+ ["LagTextDesc"] = "Tags for Text Display: [L] = Current Latency",
+
+ -- Mail Module
+ ["No Mail"] = "Нет Почта",
+ ["Mail!"] = "Почта!",
+ ["AH Alert!"] = "AH оповещения!",
+ ["Play Sounds"] = "Звук Бдительные",
+
+ -- Memory Module
+ ["AddOn Memory"] = "Аддон Память",
+ ["Showing Top 15 AddOns"] = "отображения хигхест 15 Аддон",
+ ["Total AddOn Memory"] = "Всего Аддон Память",
+ ["Total UI Memory Usage"] = "Всего UI Память пользование",
+ ["Hover"] = "зависать",
+ ["Show only top AddOns"] = "Показать только верхний Аддон",
+ ["Alt+Hover"] = "Alt+зависать",
+ ["Show all AddOns"] = "Показать все Аддон",
+ ["Collect Garbage"] = "Сбор мусора",
+ ["mb"] = "mb",
+ ["MemTextDesc"] = "Tags for Text Display: [MA] = Addon Memory, [MT] = Total Memory",
+
+ -- Reputation Module
+ ["Reputation"] = "Reputation",
+ ["No Reputation"] = "No Reputation",
+ ["Click to set display reputation."] = "Click to set display reputation.",
+ ["Display Reputation"] = "Display Reputation",
+ ["Hated"] = "Hated",
+ ["Hostile"] = "Hostile",
+ ["Unfriendly"] = "Unfriendly",
+ ["Neutral"] = "Neutral",
+ ["Friendly"] = "Friendly",
+ ["Honored"] = "Honored",
+ ["Revered"] = "Revered",
+ ["Exalted"] = "Exalted",
+}
\ No newline at end of file
diff --git a/Localization/zhTW.lua b/Localization/zhTW.lua
new file mode 100644
index 0000000..d5a8b25
--- /dev/null
+++ b/Localization/zhTW.lua
@@ -0,0 +1,180 @@
+if ( GetLocale() ~= "zhTW" ) then return end
+
+local addon, ns = ...
+ns.L = {
+ -- Core Globals
+ ["Combat Fade"] = "戰鬥中隱藏",
+ ["Class Colored"] = "職業顏色",
+ ["Global Font Size"] = "全域字型大小",
+ ["ProfDesc"] = "建立一個新的或是複製設定檔,設為角色預設設定",
+ ["ProfResDesc"] = "重置設定檔",
+ ["ProfNew"] = "New",
+ ["ProfReset"] = "Reset",
+ ["ProfCurrent"] = "Current",
+ ["ProfCopy"] = "Copy",
+ ["ProfDel"] = "Delete",
+ ["/sldt"] = "/sldt",
+ ["Command List"] = "命令列表",
+ ["config"] = "config",
+ ["Toggle Configuration Mode"] = "組態模式切換",
+ ["Configuration Mode"] = "組態模式",
+ ["active"] = "active",
+ ["inactive"] = "inactive",
+ ["global"] = "global",
+ ["Open SLDataText Global Menu"] = "開啟SLDataText全域選單",
+ [""] = "",
+ ["Open Module Option Menu"] = "開啟模組設置選單",
+ ["Loaded Modules"] = "Loaded Modules",
+ ["TTScale"] = "SL提示訊息縮放",
+
+ -- Common
+ ["Enabled"] = "啟用",
+ ["Global Font"] = "全域字型",
+ ["Outline"] = "外框線",
+ ["Force Shown"] = "總是顯示",
+ ["Tooltip On"] = "開啟提示資訊",
+ ["Show Tooltip (Combat)"] = "Show Tooltip (Combat)",
+ ["Font Size"] = "字型大小",
+ ["Font"] = "字型",
+ ["Justify"] = "對齊",
+ ["Parent"] = "依附",
+ ["Anchor"] = "錨點",
+ ["X Offset"] = "水平位移",
+ ["Y Offset"] = "垂直位移",
+ ["Frame Strata"] = "框架層級",
+ ["Update Interval"] = "更新頻率",
+ ["On"] = "開啟",
+ ["Off"] = "關閉",
+ ["Prefix"] = "Prefix",
+ ["Prefix Text"] = "Prefix Text",
+ ["Suffix"] = "Suffix",
+ ["Suffix Text"] = "Suffix Text",
+ ["Left-Click"] = "左鍵點擊",
+ ["Right-Click"] = "右鍵點擊",
+ ["Show Icon"] = "顯示小圖示",
+ ["Show Text"] = "顯示文字",
+ ["Text Display"] = "文字格式",
+
+ -- Armor Module
+ ["Armor"] = "護甲",
+ ["All Items"] = "所有物品",
+ ["Auto Repair"] = "自動修理",
+ ["Use Guild Bank"] = "Use Guild Bank",
+ ["Armor"] = "護甲",
+ ["AutoRepairLine"] = "修理物品花費",
+ ["GFAutoRepairLine"] = "修理物品花費 (Guild Funds)",
+ ["ArmorTextDesc"] = "[Dur] = 目前的耐久值",
+
+ -- Bag Module
+ ["Bag Info"] = "背包資訊",
+ ["Space Used"] = "已使用",
+ ["Space Avail"] = "總空間",
+ ["Space Left"] = "尚餘",
+ ["AutoSell Junk"] = "自動販賣垃圾",
+ ["JunkSoldLine"] = "垃圾販售所得",
+ ["Toggle Bags"] = "開啟背包",
+ ["BagTextDesc"] = "[T] = 總計, [R] = 尚餘, [U] = 已使用",
+
+ -- Clock Module
+ ["Toggle Calendar"] = "行事曆",
+ ["Toggle Time Manager"] = "計時器",
+ ["Queued for:"] = "佇列:",
+ ["Realm Time"] = "伺服器時間",
+ ["24 Hour"] = "24小時制",
+ ["PvP Info"] = "PvP資訊",
+ ["Time String"] = "時間文字格式",
+ ["ClockDesc"] = "造訪 http://www.lua.org/pil/22.1.html 取得完整時間標籤,如果時間標籤不是起始字串請關閉時間校準",
+ ["CorrHour"] = "時間校準",
+
+ -- Coords Module
+ ["Precision"] = "精準度",
+
+ -- Currency Module
+ ["Currency"] = "兌換通貨",
+ ["No Currency"] = "無兌換通貨",
+ ["Click to set display currency."] = "點擊設定兌換通貨顯示",
+ ["Display Currency"] = "顯示兌換通貨",
+
+ -- Exp Module
+ ["Max Level Hide"] = "封頂後隱藏",
+ ["Exp"] = "經驗值",
+ ["ExpTextDesc"] = "[Cur] = 目前經驗, [Max] = 總經驗, [Rem] = 尚餘經驗, [Per] = 目前經驗百分比, [PerR] = 尚餘經驗百分比, [R] = 充分休息經驗, [RP] = 充分休息經驗百分比",
+
+ -- FPS Module
+ ["fps"] = "fps",
+ ["FPSTextDesc"] = "[F] = 目前FPS",
+
+ -- Friends Module
+ ["Show Note"] = "顯示註記",
+ ["ClickDesc"] = "點擊傳送悄悄話",
+ ["AltClickDesc"] = "Alt+點擊傳送組隊邀請",
+ ["Show Icon"] = "顯示小圖示",
+ ["Friend List"] = "好友名單",
+ ["Friends"] = "好友",
+ ["Friends Online"] = "線上好友",
+ ["BNet Friends"] = "戰網好友",
+ ["Note"] = "註記",
+ ["(AFK)"] = "(AFK)",
+ ["(DND)"] = "(DND)",
+
+ -- Gold Module
+ ["'s"] = "的",
+ ["Wallet"] = "錢包",
+ ["Current"] = "目前",
+ ["Session Start"] = "初始",
+ ["Session Earned"] = "所得",
+ ["Server Gold"] = "伺服器金額",
+ ["Horde"] = "部落",
+ ["Alliance"] = "聯盟",
+ ["Total Gold"] = "總金額",
+ ["Display Style"] = "顯示細節",
+ ["Alt Money"] = "分身金錢",
+ ["ResetData"] = "Reset Data",
+
+ -- Guild Info
+ ["Show Officer Note"] = "顯示幹部註記",
+ ["No Guild"] = "尚無公會",
+ ["Guild"] = "公會",
+
+ -- Latency Module
+ ["Latency"] = "延遲",
+ ["Bandwidth In"] = "下載頻寬",
+ ["Bandwidth Out"] = "上傳頻寬",
+ ["Latency (Home)"] = "延遲 (住家)",
+ ["Latency (World)"] = "延遲 (世界)",
+ ["ms"] = "ms",
+ ["LagTextDesc"] = "標籤說明: [L] = 目前延遲",
+
+ -- Mail Module
+ ["No Mail"] = "無新郵件",
+ ["Mail!"] = "新郵件!",
+ ["AH Alert!"] = "拍賣場通知!",
+ ["Play Sounds"] = "播放音效",
+
+ -- Memory Module
+ ["AddOn Memory"] = "插件記憶體監視",
+ ["Showing Top 15 AddOns"] = "顯示消耗最多記憶體的前15名",
+ ["Total AddOn Memory"] = "插件消耗記憶體",
+ ["Total UI Memory Usage"] = "使用者介面消耗記憶體",
+ ["Hover"] = "滑鼠懸停",
+ ["Show only top AddOns"] = "只顯示消耗排名前15",
+ ["Alt+Hover"] = "Alt+滑鼠懸停",
+ ["Show all AddOns"] = "顯示所有插件",
+ ["Collect Garbage"] = "回收記憶體",
+ ["mb"] = "mb",
+ ["MemTextDesc"] = "[MA] = 插件消耗記憶體, [MT] = 總記憶體",
+
+ -- Reputation Module
+ ["Reputation"] = "聲望",
+ ["No Reputation"] = "無聲望",
+ ["Click to set display reputation."] = "點擊設定聲望顯示",
+ ["Display Reputation"] = "顯示聲望",
+ ["Hated"] = "仇恨",
+ ["Hostile"] = "敵對",
+ ["Unfriendly"] = "不友好",
+ ["Neutral"] = "中立",
+ ["Friendly"] = "友好",
+ ["Honored"] = "尊敬",
+ ["Revered"] = "崇敬",
+ ["Exalted"] = "崇拜",
+}
\ No newline at end of file
diff --git a/Media/glowTex.tga b/Media/glowTex.tga
new file mode 100644
index 0000000..62905cc
Binary files /dev/null and b/Media/glowTex.tga differ
diff --git a/Media/mail.mp3 b/Media/mail.mp3
new file mode 100644
index 0000000..9de61cb
Binary files /dev/null and b/Media/mail.mp3 differ
diff --git a/SLDataText.toc b/SLDataText.toc
new file mode 100644
index 0000000..2c6e7ce
--- /dev/null
+++ b/SLDataText.toc
@@ -0,0 +1,35 @@
+## Interface: 100000
+## Title: SLDataText
+## Author: Taffu
+## Notes: Simple Light Data Text! Special thanks to Suicidal Katt & snichols1122
+## Version: 10.0.0
+## SavedVariables: SLDTDB
+
+Libs\Libstub\Libstub.lua
+Libs\CallbackHandler-1.0\CallbackHandler-1.0.xml
+Libs\AceDB-3.0\AceDB-3.0.xml
+Libs\LibSharedMedia-3.0\LibSharedMedia-3.0.lua
+Libs\LibSL-1.0\LibSL-1.0.lua
+Libs\LibSLTip-1.0\LibSLTip-1.0.lua
+
+Localization\deDE.lua
+Localization\enUS.lua
+Localization\frFR.lua
+Localization\ruRU.lua
+Localization\zhTW.lua
+
+core.lua
+Elements\armor.lua
+Elements\bag.lua
+Elements\clock.lua
+Elements\currency.lua
+Elements\exp.lua
+Elements\friends.lua
+Elements\fps.lua
+Elements\gold.lua
+Elements\guild.lua
+Elements\latency.lua
+Elements\mail.lua
+Elements\memory.lua
+Elements\reputation.lua
+Elements\zonetext.lua
\ No newline at end of file
diff --git a/core.lua b/core.lua
new file mode 100644
index 0000000..0fe4a96
--- /dev/null
+++ b/core.lua
@@ -0,0 +1,334 @@
+--[[ Simple Light Data Text ]]
+--[[ Author: Taffu RevDate: 01/21/18 Version: 7.3.1 ]]
+
+-- Rev Notes:
+-- Reviewed Code
+-- Minor Adjustments
+-- Investigating slow LibSharedMedia response.
+
+local addon, ns = ...
+SLDataText = CreateFrame("Frame")
+local SML, SLC, L = LibStub("LibSharedMedia-3.0"), LibStub("LibSL-1.0"), ns.L
+local profileList, db = {}
+
+function SLDataText:SetupBaseFrame(module)
+ module.Frame = module.Frame or CreateFrame("Frame", "SLDT_" .. tostring(module.db.profile.name), UIParent, BackdropTemplateMixin and "BackdropTemplate")
+ module.Tool = module.Tool or CreateFrame("Frame", nil, module.Frame)
+ module.Text = module.Text or module.Frame:CreateFontString(nil, "OVERLAY")
+ local frame, text, tool = module.Frame, module.Text, module.Tool
+
+ frame:SetBackdrop({
+ bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
+ tile = true, tileSize = 16, edgeSize = 4,
+ insets = { left = 0, top = 0, right = 0, bottom = 0 }
+ })
+ frame:SetBackdropColor(0,0,0,0)
+ frame:SetClampedToScreen(true)
+ frame:EnableMouse(false)
+ tool:EnableMouse(true)
+
+ return frame, text, tool
+end
+
+function SLDataText:SetupPulseFrame(module)
+ module.Pulse = module.Pulse or CreateFrame("Frame", nil, module.Frame, BackdropTemplateMixin and "BackdropTemplate")
+ local pulse = module.Pulse
+ pulse:SetBackdrop({
+ bgFile = "Interface\\BUTTONS\\WHITE8X8",
+ edgeFile = "Interface\\AddOns\\SLDataText\\Media\\glowTex",
+ tile = true, tileSize = 16, edgeSize = 4,
+ insets = { left = 3, top = 3, right = 3, bottom = 3 }
+ })
+ pulse:EnableMouse(false)
+ pulse:SetBackdropColor(1,1,0,1)
+ pulse:SetBackdropBorderColor(1,1,0,1)
+ pulse:Hide()
+
+ pulse:ClearAllPoints()
+ pulse:SetPoint("CENTER", module.Frame, "CENTER", 0, 0)
+
+ return pulse
+end
+
+function SLDataText:Pulse(module, start)
+ module.Pulse = module.Pulse or self:SetupPulseFrame(module)
+ if ( not module.Pulse.down ) then module.Pulse.down = false end
+
+ if ( not start ) then
+ if ( module.Pulse:IsShown() ) then module.Pulse:Hide() end
+ module.Pulse:SetScript("OnUpdate", nil)
+ else
+ if ( not module.Pulse:IsShown() ) then module.Pulse:Show() end
+ module.Pulse:SetFrameLevel(0)
+ module.Pulse:SetScript("OnUpdate", function(self, elapsed)
+ local step = abs(1/30)
+ if ( self:GetAlpha() == 1 ) then
+ module.Pulse.down = true; self:SetAlpha(self:GetAlpha()-step)
+ elseif ( self:GetAlpha() == 0 ) then
+ module.Pulse.down = false; self:SetAlpha(self:GetAlpha()+step)
+ else
+ if ( module.Pulse.down ) then
+ self:SetAlpha(self:GetAlpha()-step)
+ else
+ self:SetAlpha(self:GetAlpha()+step)
+ end
+ end
+ end)
+ end
+end
+
+function SLDataText:UpdateBaseText(module, mdb)
+ local font, gfont, gfontSize, text = SML:Fetch("font", mdb.font), SML:Fetch("font", db.gFont), db.gFontSize, module.Text
+ text:SetFont(mdb.gfont and gfont or font, mdb.gfont and gfontSize or mdb.fontSize, mdb.outline and "THINOUTLINE" or nil)
+ if ( not mdb.outline ) then text:SetShadowColor(0,0,0,1); text:SetShadowOffset(1, -1) else text:SetShadowColor(0,0,0,0) end
+ text:ClearAllPoints()
+ text:SetPoint("CENTER", module.Frame, "CENTER", 0, 0)
+end
+
+local function SLDTAnchorFix(module, mdb)
+ local reset, timer = CreateFrame("Frame"), 10
+ reset:SetScript("OnUpdate", function(this, elapsed)
+ if ( (GetTime() - elapsed) >= timer ) then
+ reset:SetScript("OnUpdate", nil)
+ SLDataText:UpdateBaseFrame(module, mdb)
+ end
+ end)
+end
+
+function SLDataText:UpdateBaseFrame(module, mdb)
+ module.Frame:SetWidth(module.Text:GetWidth()); module.Frame:SetHeight(module.Text:GetHeight())
+ module.Frame:ClearAllPoints()
+
+ if ( string.sub(mdb.anch, 0, 5) == "SLDT_" ) then
+ local found = false
+ for k, v in pairs(SLDataText.Modules) do
+ local frame = SLDataText[v[1]].Frame
+ if ( frame:GetName() == mdb.anch ) then found = true end
+ end
+ if ( not found ) then
+ SLDTAnchorFix(module, mdb)
+ else
+ module.Frame:SetParent(frame)
+ module.Frame:SetPoint(mdb.aP, mdb.anch, mdb.aF, mdb.xOff, mdb.yOff)
+ end
+ else
+ module.Frame:SetParent(_G[mdb.anch])
+ module.Frame:SetPoint(mdb.aP, mdb.anch, mdb.aF, mdb.xOff, mdb.yOff)
+ end
+
+ module.Frame:SetFrameStrata(mdb.strata)
+ module.Tool:SetAllPoints(module.Frame)
+ if ( module.Pulse ) then
+ module.Pulse:SetWidth(module.Frame:GetWidth()+8); module.Pulse:SetHeight(module.Frame:GetHeight()+8)
+ end
+ if ( not mdb.tooltipOn or db.configMode ) then module.Tool:EnableMouse(false) else module.Tool:EnableMouse(true) end
+ if ( db.configMode ) then module.Frame:EnableMouse(true) else module.Frame:EnableMouse(false) end
+ if ( not module.Frame:IsShown() ) then module.Frame:Show() end
+end
+
+function SLDataText:AddModule(modname, db)
+ if ( not modname or modname == nil ) then error("SLDataText:AddModule(modname, db) - 'modname': string expected, cannot create module entry", 2) end
+ if ( not db or db == nil ) then error("SLDataText:AddModule(modname, db) - 'db': table expected, cannot create module entry", 2) end
+
+ self.Modules = self.Modules or {}
+ if ( not self.Modules[modname] ) then
+ table.insert(self.Modules, { modname, db })
+ end
+end
+
+local function FadeOut(module)
+ local step, f = 0.1, CreateFrame("Frame")
+ if ( db.cFade ) then
+ f:SetScript("OnUpdate", function()
+ local mAlpha = module.Frame:GetAlpha()
+ if ( mAlpha > 0 ) then module.Frame:SetAlpha(mAlpha-step)
+ elseif ( mAlpha == 0 ) then f:SetScript("OnUpdate", nil); f = nil end
+ end)
+ end
+end
+
+local function FadeIn(module)
+ local step, f = 0.1, CreateFrame("Frame")
+ if ( db.cFade ) then
+ f:SetScript("OnUpdate", function()
+ local mAlpha = module.Frame:GetAlpha()
+ if ( mAlpha < 1 ) then module.Frame:SetAlpha(mAlpha+step)
+ elseif ( mAlpha == 1 ) then f:SetScript("OnUpdate", nil); f = nil end
+ end)
+ end
+end
+
+local function SLDT_ChangeMode(module, mdb)
+ if ( db.configMode ) then
+ module.Frame:Show()
+ module.Frame:EnableMouse(true)
+ module.Frame:SetBackdropColor(0,0,0,0.75)
+ module.Tool:EnableMouse(false)
+
+ module.Frame:SetMovable(true)
+ module.Frame:SetScript("OnMouseDown", function(_, button)
+ if ( button == "LeftButton" ) then SLC:MoveSLFrame(module.Frame, mdb); module.Moving = true end
+ if ( button == "RightButton" ) then SLC:OpenOptBox(module) end
+ end)
+ module.Frame:SetScript("OnMouseUp", function(_, button)
+ if ( button == "LeftButton" ) then SLC:StopSLFrame(module.Frame, mdb, module.Opt, mdb.name); module.Moving = false end
+ end)
+ module.Frame:SetScript("OnEnter", function(this)
+ GameTooltip:SetOwner(this, "ANCHOR_TOP", 0, 6)
+ GameTooltip:AddLine("|cffffffffConfig Mode|r")
+ GameTooltip:AddDoubleLine("Left-Click", "Drag & Move", 1,1,0,1,1,1)
+ GameTooltip:AddDoubleLine("Right-Click", "Open Menu", 1,1,0,1,1,1)
+ GameTooltip:Show()
+ end)
+ module.Frame:SetScript("OnLeave", function(this) if ( GameTooltip:IsVisible() ) then GameTooltip:Hide() end end)
+ else
+ if ( not mdb.enabled ) then module.Frame:Hide() end
+ module.Frame:EnableMouse(false)
+ module.Frame:SetBackdropColor(0,0,0,0)
+ module.Tool:EnableMouse(true)
+
+ module.Frame:SetMovable(false)
+ module.Frame:SetScript("OnMouseDown", nil)
+ module.Frame:SetScript("OnMouseUp", nil)
+ end
+end
+
+local function SLDT_Refresh()
+ for k, v in pairs(SLDataText.Modules) do
+ SLDataText:UpdateBaseText(SLDataText[v[1]], SLDataText[v[1]].db.profile)
+ SLDataText[v[1]]:Refresh()
+ end
+end
+
+function SLDataText:Refresh()
+ for k, v in pairs(SLDataText.Modules) do
+ self:UpdateBaseText(SLDataText[v[1]], SLDataText[v[1]].db.profile)
+ SLDataText[v[1]]:Refresh()
+ end
+end
+
+local optsTbl = {
+ [1] = { [1] = "toggle", [2] = L["Combat Fade"], [3] = "cFade" },
+ [2] = { [1] = "toggle", [2] = L["Class Colored"], [3] = "cCol" },
+ [3] = { [1] = "range", [2] = L["Global Font Size"], [3] = "gFontSize", [4] = 6, [5] = 40, [6] = 1 },
+ [4] = { [1] = "select", [2] = L["Global Font"], [3] = "gFont", [4] = SML:List("font") },
+ [5] = { [1] = "range", [2] = L["TTScale"], [3] = "ttScale", [4] = 0.1, [5] = 2.0, [6] = 0.1 },
+ [6] = { [1] = "desc", [2] = "ProfDesc", [3] = L["ProfDesc"] },
+ [7] = { [1] = "profile", [2] = L["ProfNew"], [3] = "New", },
+ [8] = { [1] = "profile", [2] = L["ProfCurrent"], [3] = "Current", },
+ [9] = { [1] = "profile", [2] = L["ProfCopy"], [3] = "Copy", },
+ [10] = { [1] = "profile", [2] = L["ProfDel"], [3] = "Delete", },
+ [11] = { [1] = "profile", [2] = L["ProfReset"], [3] = "Reset", [4] = L["ProfResDesc"], },
+}
+
+SLASH_SLDT1 = L["/sldt"]
+function SlashCmdList.SLDT(msg, _)
+ if ( type(msg) == "string" and string.len(msg) > 1 ) then
+ if ( string.lower(msg) == string.lower(L["config"]) ) then
+ db.configMode = not db.configMode
+ print(string.format("|cff6698FFSLDataText|r Configuration Mode |cffffff00%s|r.", db.configMode and "active" or "inactive"))
+ for k, v in pairs(SLDataText.Modules) do
+ SLDT_ChangeMode(SLDataText[v[1]], v[2])
+ SLDataText[v[1]]:Refresh()
+ end
+ elseif ( string.lower(msg) == L["global"] ) then
+ if ( not SLDataText.Opt ) then SLC:CreateMenu("SLDataText", SLDataText, optsTbl) end
+ SLC:OpenOptBox(SLDataText)
+ elseif ( SLDataText[msg] ) then
+ SLC:OpenOptBox(SLDataText[msg])
+ end
+ else
+ -- Help printout
+ print("|cff6698FFSLDataText|r")
+ print("|cffffff00/sldt|r - "..L["Command List"])
+ print("|cffffff00/sldt "..L["config"].."|r - "..L["Toggle Configuration Mode"])
+ print("|cffffff00/sldt "..L["global"].."|r - "..L["Open SLDataText Global Menu"])
+ print("|cffffff00/sldt "..L[""].."|r - "..L["Open Module Option Menu"])
+ local modString = ""
+ for k, v in pairs(SLDataText.Modules) do modString = string.format("%s %s", modString, v[1]) end
+ print(L["Loaded Modules"]..":"..modString)
+ end
+end
+
+local function OnInit()
+ SLDataText.db = LibStub("AceDB-3.0"):New("SLDTDB")
+ SLDataText.db:RegisterDefaults({
+ profile = {
+ cFade = true,
+ cCol = true,
+ gFont = "Arial Narrow",
+ gFontSize = 12,
+ configMode = false,
+ ttScale = 1.0,
+ modules = {
+ ['*'] = true,
+ },
+ },
+ })
+ SLDataText.db.RegisterCallback("SLDataText", "OnProfileChanged", SLDT_Refresh)
+ SLDataText.db.RegisterCallback("SLDataText", "OnProfileCopied", SLDT_Refresh)
+ SLDataText.db.RegisterCallback("SLDataText", "OnProfileReset", SLDT_Refresh)
+ db = SLDataText.db.profile
+
+ -- Force configMode off OnLoad
+ db["configMode"] = false
+ -- Do this to ensure proper scaling of global menu to UIParent
+ if ( not SLDataText.Frame ) then SLDataText.Frame = CreateFrame("Frame", nil, UIParent) end
+ -- Kill OnInit
+ SLDataText:UnregisterEvent("PLAYER_LOGIN")
+ -- Get class color hex
+ local class = select(2, UnitClass("player"))
+ SLDataText.classColor = string.format("%02X%02X%02X", RAID_CLASS_COLORS[class].r*255, RAID_CLASS_COLORS[class].g*255, RAID_CLASS_COLORS[class].b*255)
+ -- Setup Fade Functionality
+ SLDataText:RegisterEvent("PLAYER_REGEN_ENABLED")
+ SLDataText:RegisterEvent("PLAYER_REGEN_DISABLED")
+ SLDataText:SetScript("OnEvent", function(_, event)
+ if ( event == "PLAYER_REGEN_DISABLED" ) then
+ -- In combat / fade out
+ for _, v in pairs(SLDataText.Modules) do
+ local module, mdb = SLDataText[v[1]], v[2]
+ if ( not mdb.forceShow ) then
+ FadeOut(module)
+ end
+ end
+ elseif ( event == "PLAYER_REGEN_ENABLED" ) then
+ -- Out of combat / fade in
+ for _, v in pairs(SLDataText.Modules) do
+ local module, mdb = SLDataText[v[1]], v[2]
+ if ( not mdb.forceShow ) then
+ FadeIn(module)
+ end
+ end
+ end
+ end)
+end
+
+SLDataText.Locale = L
+SLDataText.fontTbl = SML:List("font")
+SLDataText.justTbl = {
+ [1] = "LEFT",
+ [2] = "CENTER",
+ [3] = "RIGHT",
+}
+SLDataText.anchTbl = {
+ [1] = "TOPLEFT",
+ [2] = "TOP",
+ [3] = "TOPRIGHT",
+ [4] = "LEFT",
+ [5] = "CENTER",
+ [6] = "RIGHT",
+ [7] = "BOTTOMLEFT",
+ [8] = "BOTTOM",
+ [9] = "BOTTOMRIGHT",
+}
+SLDataText.stratTbl = {
+ [1] = "BACKGROUND",
+ [2] = "LOW",
+ [3] = "MEDIUM",
+ [4] = "HIGH",
+ [5] = "DIALOG",
+}
+
+SLDataText:RegisterEvent("PLAYER_LOGIN")
+SLDataText:SetScript("OnEvent", OnInit)
+SLDataText.GlobalErr = "SLDataText Global is nil, %s module not created."
\ No newline at end of file