local mod = StarTip:NewModule("Text", "AceTimer-3.0") mod.name = "Texts" mod.toggled = true --mod.childGroup = true mod.defaultOff = true local _G = _G local StarTip = _G.StarTip local GameTooltip = _G.GameTooltip local GameTooltipStatusBar = _G.GameTooltipStatusBar local UnitIsPlayer = _G.UnitIsPlayer local RAID_CLASS_COLORS = _G.RAID_CLASS_COLORS local UnitSelectionColor = _G.UnitSelectionColor local UnitClass = _G.UnitClass local self = mod local LSM = LibStub("LibSharedMedia-3.0") local WidgetText = LibStub("LibScriptableWidgetText-1.0") local LibCore = LibStub("LibScriptableLCDCore-1.0") local LibQTip = LibStub("LibQTip-1.0") local PluginUtils = LibStub("LibScriptablePluginUtils-1.0") local LibTimer = LibStub("LibScriptableUtilsTimer-1.0") local Widget = LibStub("LibScriptableWidget-1.0") local L = StarTip.L local environment = {} local anchors = { "TOP", "TOPRIGHT", "TOPLEFT", "BOTTOM", "BOTTOMRIGHT", "BOTTOMLEFT", "RIGHT", "LEFT", "CENTER" } local anchorsDict = {} for i, v in ipairs(anchors) do anchorsDict[v] = i end local createTexts local widgets = {} local function copy(tbl) if type(tbl) ~= "table" then return tbl end local newTbl = {} for k, v in pairs(tbl) do newTbl[k] = copy(v) end return newTbl end local defaultWidgets = { [1] = { name = "Name", enabled = true, value = [[ if not UnitExists(unit) then return end return '--' .. select(1, UnitName(unit)) .. '--' ]], color = [[ if UnitIsPlayer(unit) then return ClassColor(unit) elseif unit then return UnitSelectionColor(unit) end ]], cols = 40, align = WidgetText.ALIGN_PINGPONG, update = 1000, speed = 100, direction = SCROLL_LEFT, dontRtrim = true, points = {{"BOTTOMLEFT", "StarTipTooltipMain", "TOPLEFT", 0, 12}}, parent = "StarTipTooltipMain", frameName = "StarTipTextsName", strata = 1, level = 1, }, [2] = { name = "Health", enabled = true, value = [[ if not UnitExists(unit) then return end local health, max = UnitHealth(unit), UnitHealthMax(unit) if max == 0 then max = 0.0001 end return format('Health: %.1f%%', health / max * 100) ]], color = [[ if not UnitExists(unit) then return end local health, max = UnitHealth(unit), UnitHealthMax(unit) return Gradient(health / max) ]], cols = 20, update = 1000, points = {{"TOPLEFT", "StarTipTooltipMain", "BOTTOMLEFT", 0, 1}}, parent = "StarTipTooltipMain", strata = 1, level = 1 }, [3] = { name = "Power", enabled = true, value = [[ if not UnitExists(unit) then return end local mana, max = UnitMana(unit), UnitManaMax(unit) if max == 0 then max = 0.0001 end return format(PowerName(unit)..': %.1f%%', mana / max * 100) ]], color = [[ if not UnitExists(unit) then return end local mana, max = UnitMana(unit), UnitManaMax(unit) return Gradient(mana / max) ]], cols = 20, update = 1000, align = WidgetText.ALIGN_RIGHT, points = {{"TOPRIGHT", "StarTipTooltipMain", "BOTTOMRIGHT", 0, 1}}, parent = "StarTipTooltipMain", strata = 1, level = 1 }, [4] = { name = "Memory Percent", enabled = false, value = [[ local mem, percent, memdiff, totalMem, totaldiff, memperc = GetMemUsage("StarTip") if mem then local num = floor(memperc) if num < 1 then num = 1 end if num > 100 then num = 100 end local r, g, b = gradient[num][1], gradient[num][2], gradient[num][3] return format("Mem: %.2f%%", memperc) end ]], color = [[ local mem, percent, memdiff, totalMem, totaldiff, memperc = GetMemUsage("StarTip") if mem then local num = floor(memperc) if num < 1 then num = 1 end if num > 100 then num = 100 end local r, g, b = gradient[num][1], gradient[num][2], gradient[num][3] return r, g, b end ]], cols = 20, update = 1000, dontRtrim = true, points = {{"TOPLEFT", "StarTipTooltipMain", "BOTTOMLEFT", 0, -62}}, parent = "StarTipTooltipMain", strata = 1, level = 1, intersect = true, intersectPad = 70 }, [5] = { name = "Memory Total", enabled = false, value = [[ local mem, percent, memdiff, totalMem, totaldiff, memperc = GetMemUsage("StarTip") if mem then if totalMem == 0 then totalMem = 100; mem = 0 end memperc = mem / totalMem * 100 return format("%s (%.2f%%)", memshort(mem), memperc) end ]], color = [[ return Color2RGBA(0xffff00) ]], cols = 20, update = 1000, dontRtrim = true, points = {{"TOPLEFT", "StarTipTooltipMain", "BOTTOMLEFT", 0, -124}}, parent = "StarTipTooltipMain", strata = 1, level = 1, intersect = true, intersectPad = 100 }, [6] = { name = "CPU Percent", enabled = false, value = [[ if not scriptProfile then return "Profiling Off" end local cpu, percent, cpudiff, totalCPU, totaldiff, cpuperc = GetCPUUsage("StarTip") if cpu then return format("CPU: %.2f%%", cpuperc) end ]], color = [[ if not scriptProfile then return 0, 1, 0 end local cpu, percent, cpudiff, totalCPU, totaldiff, cpuperc = GetCPUUsage("StarTip") if cpu then local num = floor(cpuperc) if num < 1 then num = 1 end if num > 100 then num = 100 end local r, g, b = gradient[num][1], gradient[num][2], gradient[num][3] return r, g, b end ]], cols = 14, align = WidgetText.ALIGN_RIGHT, update = 1000, dontRtrim = true, points = {{"TOPRIGHT", "StarTipTooltipMain", "BOTTOMRIGHT", 0, -62}}, parent = "StarTipTooltipMain", strata = 1, level = 1, intersect = true, intersectPad = 70 }, [7] = { name = "CPU Total", enabled = false, value = [[ if not scriptProfile then return "Profiling Off" end local cpu, percent, cpudiff, totalCPU, totaldiff = GetCPUUsage("StarTip") if cpu then if totalCPU == 0 then totalCPU = 100; cpu = 0 end cpuperc = cpu / totalCPU * 100; return format("%s (%.2f%%)", timeshort(cpu), cpuperc) end ]], color = [[ return 1, 1, 0 ]], cols = 20, align = WidgetText.ALIGN_RIGHT, update = 1000, dontRtrim = true, points = {{"TOPRIGHT", "StarTipTooltipMain", "BOTTOMRIGHT", 0, -124}}, parent = "StarTipTooltipMain", strata = 1, level = 1, intersect = true, intersectPad = 100 }, } local defaults = { profile = { classColors = true, texts = {} } } local options = {} local optionsDefaults = { add = { name = L["Add Text"], desc = L["Add a text widget"], type = "input", set = function(info, v) local widget = { name = v, type = "text", min = "return 0", max = "return 100", height = 6, points = {{"BOTTOMLEFT", "StarTipTooltipMain", "TOPLEFT"}}, texture = LSM:GetDefault("statustext"), expression = "", strata = 1, level = 1, custom = true } tinsert(mod.db.profile.texts, widget) StarTip:RebuildOpts() mod:ClearTexts() end, order = 5 }, defaults = { name = L["Restore Defaults"], desc = L["Restore Defaults"], type = "execute", func = function() mod.db.profile.texts = copy(defaultWidgets); StarTip:RebuildOpts() end, order = 6 }, } local intersectTimer local intersectUpdate = function() WidgetText.IntersectUpdate(mod.texts) end function updateText(widget) widget.frame.fontstring:SetText(widget.buffer) widget.frame:SetHeight(widget.frame.fontstring:GetStringHeight()) widget.frame:SetWidth(widget.frame.fontstring:GetStringWidth()) local r, g, b, a = 0, 0, 1, 1 if widget.color then r, g, b, a = widget.color.res1, widget.color.res2, widget.color.res3, widget.color.res4 end if type(r) == "number" then widget.frame.fontstring:SetTextColor(r, g, b, a) end if type(widget.background) == "table" then r, g, b, a = unpack(widget.background) end widget.frame:SetBackdropColor(r, g, b, a) if not UnitExists(StarTip.unit or "mouseover") and not widget.config.alwaysShown then widget.frame:Hide() end end local textureDict = {} function mod:CreateTexts() createTexts() end local new, del do local pool = {} local i = 0 function new(background, name, parent) local text = next(pool) if type(parent) == "string" then end if type(parent) ~= "table" then parent = _G["StarTipTooltipMain"] end if text then pool[text] = nil else parent = parent or "UIParent" local frame = CreateFrame("Frame", name, parent) if background then frame:SetBackdrop({bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", tile = true, tileSize = 4, edgeSize=4, insets = { left = 0, right = 0, top = 0, bottom = 0}}) else frame:SetBackdrop({ insets = {left = 0, right = 0, top = 0, bottom = 0}, }) end frame:ClearAllPoints() frame:SetAlpha(1) local fs = frame:CreateFontString() fs:SetAllPoints(frame) fs:SetFontObject(GameFontNormal) fs:Show() frame.fontstring = fs text = frame end return text end function del(text) pool[text] = true end end local defaultPoint = {"BOTTOMLEFT", "StarTipTooltipMain", "TOPLEFT"} local strataNameList = { "TOOLTIP", "FULLSCREEN_DIALOG", "FULLSCREEN", "DIALOG", "HIGH", "MEDIUM", "LOW", "BACKGROUND" } local strataLocaleList = { "Tooltip", "Fullscreen Dialog", "Fullscreen", "Dialog", "High", "Medium", "Low", "Background" } local function clearText(obj) local widget = mod.texts[obj] if not widget then return end widget:Del() widget.frame:Hide() widget.frame.fontstring:Hide() del(widget.frame) end function mod:ClearTexts() for k, v in pairs(mod.texts or {}) do clearText(v) end wipe(mod.texts or {}) end local fontstrings = {} function createTexts() if type(mod.texts) ~= "table" then mod.texts = {} end --[[for k, v in pairs(mod.texts) do v:Del() v.text:Hide() del(v.text) end]] local appearance = StarTip:GetModule("Appearance") for i, v in ipairs(self.db.profile.texts) do if v.enabled and not v.deleted then local widget = mod.texts[v] if not widget then local text = new(v.background, v.frameName, v.parent) widget = WidgetText:New(StarTip.core, v.name, copy(v), v.row or 0 or 0, v.col or 0, v.layer or 0, StarTip.db.profile.errorLevel, updateText) text:ClearAllPoints() for j, point in ipairs(v.points) do local arg1, arg2, arg3, arg4, arg5 = unpack(point) arg4 = (arg4 or 0) arg5 = (arg5 or 0) text:SetPoint(arg1, arg2, arg3, arg4, arg5) end text:SetFrameStrata(strataNameList[v.strata or 1]) text:SetFrameLevel(v.level or 1) text:Show() widget.frame = text mod.texts[v] = widget end widget.config.unit = StarTip.unit end end end function mod:ReInit() if not self.db.profile.texts then self.db.profile.texts = {} end --wipe(self.db.profile.texts) for i, v in ipairs(defaultWidgets) do for j, vv in ipairs(self.db.profile.texts) do if v.name == vv.name and not vv.custom then for k, val in pairs(v) do if v[k] ~= vv[k] and not vv[k.."Dirty"] then vv[k] = v[k] end end v.tagged = true v.deleted = vv.deleted end end end for i, v in ipairs(defaultWidgets) do if not v.tagged and not v.deleted then tinsert(self.db.profile.texts, copy(v)) end end end function mod:OnInitialize() self.db = StarTip.db:RegisterNamespace(self:GetName(), defaults) self:ReInit() StarTip:SetOptionsDisabled(options, true) self.texts = {} end function mod:OnEnable() self:ClearTexts() intersectTimer = intersectTimer or LibTimer:New("Texts.intersectTimer", 100, true, intersectUpdate) StarTip:SetOptionsDisabled(options, false) createTexts() for k, text in pairs(self.texts) do if text.config.alwaysShown then StarTip:Print("always shown -------------------------") text:Start() text.frame:Show() end end end function mod:OnDisable() self:ClearTexts() if type(intersectTimer) == "table" then intersectTimer:Stop() end StarTip:SetOptionsDisabled(options, true) end --[[function mod:RebuildOpts() for k, v in ipairs(self.db.profile.texts) do options.texts.args[k] = WidgetText:GetOptions(v) end end]] function mod:GetOptions() return options end function mod:SetUnit() GameTooltipStatusBar:Hide() createTexts() for k, text in pairs(self.texts) do text:Start() text.frame:Show() end intersectTimer:Start() end function mod:SetItem() for i, text in pairs(self.texts) do if not text.config.alwaysShown then text:Stop() text.frame:Hide() end end intersectTimer:Start() end function mod:SetSpell() for i, text in pairs(self.texts) do if not text.config.alwaysShown then text:Stop() text.frame:Hide() end end intersectTimer:Start() end function mod:OnHide() for i, text in pairs(self.texts) do if not text.config.alwaysShown then text:Stop() text.frame:Hide() end end intersectTimer:Stop() end function mod:RebuildOpts() local defaults = WidgetText.defaults self:ClearTexts() wipe(options) for k, v in pairs(optionsDefaults) do options[k] = v end for i, db in ipairs(self.db.profile.texts) do options[db.name:gsub(" ", "_")] = { name = db.name, type="group", order = i, args=WidgetText:GetOptions(db, StarTip.RebuildOpts, StarTip) } options[db.name:gsub(" ", "_")].args.delete = { name = "Delete", type = "execute", func = function() local delete = true for i, v in ipairs(defaultWidgets) do if db.name == v.name then db.deleted = true delete = false end end if delete then tremove(self.db.profile.texts, i) end self:ClearTexts() StarTip:RebuildOpts() end, order = 100 } options[db.name:gsub(" ", "_")].args.enabled = { name = L["Enabled"], desc = L["Whether the histogram is enabled or not"], type = "toggle", get = function() return db.enabled end, set = function(info, v) db.enabled = v; db["enabledDirty"] = true self:ClearTexts() end, order = 1 } end end --[[ enabled = { name = "Enabled", desc = "Whether this text is enabled or not", type = "toggle", get = function() return db.enabled end, set = function(info, v) db.enabled = v db["enabledDirty"] = true createTexts() end, order = 1 }, height = { name = "Text height", desc = "Enter the text's height", type = "input", pattern = "%d", get = function() return tostring(db.height or defaults.height) end, set = function(info, v) db.height = tonumber(v); db["heightDirty"] = true createTexts(); end, order = 2 }, update = { name = "Text update rate", desc = "Enter the text's refresh rate", type = "input", pattern = "%d", get = function() return tostring(db.update or defaults.update) end, set = function(info, v) db.update = tonumber(v); db["updateDirty"] = true createTexts() end, order = 3 }, strata = { name = "Strata", type = "select", values = strataLocaleList, get = function() return db.strata end, set = function(info, v) db.strata = v end, order = 6 }, point = { name = "Anchor Points", desc = "This text's anchor point. These arguments are passed to text:SetPoint()", type = "group", args = { point = { name = "Text anchor", type = "select", values = anchors, get = function() return anchorsDict[db.point[1] or 1] end, set = function(info, v) db.point[1] = anchors[v] end, order = 1 }, relativeFrame = { name = "Relative Frame", type = "input", get = function() return db.point[2] end, set = function(info, v) db.point[2] = v end, order = 2 }, relativePoint = { name = "Relative Point", type = "select", values = anchors, get = function() return anchorsDict[db.point[3] or 1] end, set = function(info, v) db.point[3] = anchors[v] end, order = 3 }, xOfs = { name = "X Offset", type = "input", pattern = "%d", get = function() return tostring(db.point[4] or 0) end, set = function(info, v) db.point[4] = tonumber(anchors[v]) end, order = 4 }, yOfs = { name = "Y Offset", type = "input", pattern = "%d", get = function() return tostring(db.point[5] or 0) end, set = function(info, v) db.point[5] = tonumber(anchors[v]) end, order = 4 } }, order = 7 }, top = { name = "First is Top", desc = "Toggle whether to place the first text on top", type = "toggle", get = function() return db.top end, set = function(info, v) db.top = v; db["topDirty"] = true createTexts() end, order = 8 }, value = { name = "Text expression", desc = "Enter the text's expression", type = "input", multiline = true, width = "full", get = function() return db.value end, set = function(info, v) db.value = v; db["valueDirty"] = true createTexts() end, order = 9 }, } } end end ]]