502 lines
14 KiB
Lua
502 lines
14 KiB
Lua
if not WeakAuras.IsLibsOK() then return end
|
|
local AddonName, Private = ...
|
|
|
|
local SharedMedia = LibStub("LibSharedMedia-3.0");
|
|
local L = WeakAuras.L;
|
|
|
|
local screenWidth, screenHeight = math.ceil(GetScreenWidth() / 20) * 20, math.ceil(GetScreenHeight() / 20) * 20
|
|
|
|
local defaultFont = WeakAuras.defaultFont
|
|
local defaultFontSize = WeakAuras.defaultFontSize
|
|
|
|
local default = function(parentType)
|
|
if parentType == "icon" then
|
|
-- No Shadow, but Outline
|
|
return {
|
|
text_text = "%p",
|
|
text_color = {1, 1, 1, 1},
|
|
text_font = defaultFont,
|
|
text_fontSize = defaultFontSize,
|
|
text_fontType = "OUTLINE",
|
|
text_visible = true,
|
|
text_justify = "CENTER",
|
|
|
|
text_selfPoint = "AUTO",
|
|
text_anchorPoint = "CENTER",
|
|
anchorXOffset = 0,
|
|
anchorYOffset = 0,
|
|
|
|
text_shadowColor = { 0, 0, 0, 1},
|
|
text_shadowXOffset = 0,
|
|
text_shadowYOffset = 0,
|
|
|
|
text_automaticWidth = "Auto",
|
|
text_fixedWidth = 64,
|
|
text_wordWrap = "WordWrap",
|
|
}
|
|
else
|
|
-- With Shadow, without Outline
|
|
return {
|
|
text_text = "%n",
|
|
text_color = {1, 1, 1, 1},
|
|
text_font = defaultFont,
|
|
text_fontSize = defaultFontSize,
|
|
text_fontType = "None",
|
|
text_visible = true,
|
|
text_justify = "CENTER",
|
|
|
|
text_selfPoint = "AUTO",
|
|
text_anchorPoint = parentType == "aurabar" and "INNER_RIGHT" or "BOTTOMLEFT",
|
|
anchorXOffset = 0,
|
|
anchorYOffset = 0,
|
|
|
|
text_shadowColor = { 0, 0, 0, 1},
|
|
text_shadowXOffset = 1,
|
|
text_shadowYOffset = -1,
|
|
|
|
text_automaticWidth = "Auto",
|
|
text_fixedWidth = 64,
|
|
text_wordWrap = "WordWrap",
|
|
}
|
|
end
|
|
end
|
|
|
|
local properties = {
|
|
text_visible = {
|
|
display = L["Visibility"],
|
|
setter = "SetVisible",
|
|
type = "bool",
|
|
defaultProperty = true
|
|
},
|
|
text_text = {
|
|
display = L["Text"],
|
|
setter = "ChangeText",
|
|
type = "string"
|
|
},
|
|
text_color = {
|
|
display = L["Color"],
|
|
setter = "Color",
|
|
type = "color",
|
|
},
|
|
text_fontSize = {
|
|
display = L["Font Size"],
|
|
setter = "SetTextHeight",
|
|
type = "number",
|
|
min = 6,
|
|
softMax = 72,
|
|
step = 1,
|
|
default = 12
|
|
},
|
|
text_anchorXOffset = {
|
|
display = L["X-Offset"],
|
|
setter = "SetXOffset",
|
|
type = "number",
|
|
softMin = (-1 * screenWidth),
|
|
softMax = screenWidth,
|
|
bigStep = 10,
|
|
},
|
|
text_anchorYOffset = {
|
|
display = L["Y-Offset"],
|
|
setter = "SetYOffset",
|
|
type = "number",
|
|
softMin = (-1 * screenHeight),
|
|
softMax = screenHeight,
|
|
bigStep = 10,
|
|
},
|
|
}
|
|
|
|
local function create()
|
|
local region = CreateFrame("Frame", nil, UIParent);
|
|
|
|
local text = region:CreateFontString(nil, "OVERLAY");
|
|
region.text = text;
|
|
|
|
-- WOW's layout system works best if frames and all their parents are anchored
|
|
-- In this case, it appears that a text doesn't get the right size on the initial
|
|
-- load with a custom font. (Though it works if the font is non-custom or after
|
|
-- a ReloadUI). Just moving the normal AnchorSubRegion to the start of modify was not enough
|
|
-- But anchoring the text to UIParent before re-anchoring it correctly does seem to fix
|
|
-- the issue. Also see #1778
|
|
text:SetPoint("CENTER", UIParent, "CENTER")
|
|
|
|
text:SetWordWrap(true)
|
|
text:SetNonSpaceWrap(true)
|
|
|
|
return region;
|
|
end
|
|
|
|
local function onAcquire(subRegion)
|
|
subRegion:Show()
|
|
end
|
|
|
|
local function onRelease(subRegion)
|
|
subRegion:Hide()
|
|
end
|
|
|
|
local function modify(parent, region, parentData, data, first)
|
|
region:SetParent(parent)
|
|
local text = region.text;
|
|
|
|
local fontPath = SharedMedia:Fetch("font", data.text_font);
|
|
text:SetFont(fontPath, data.text_fontSize < 33 and data.text_fontSize or 33, data.text_fontType);
|
|
if not text:GetFont() and fontPath then -- workaround font not loading correctly
|
|
local objectName = "WeakAuras-Font-" .. data.text_font
|
|
local fontObject = _G[objectName] or CreateFont(objectName)
|
|
fontObject:SetFont(fontPath, data.text_fontSize < 33 and data.text_fontSize or 33, data.text_fontType == "None" and "" or data.text_fontType)
|
|
text:SetFontObject(fontObject)
|
|
end
|
|
if not text:GetFont() then -- Font invalid, set the font but keep the setting
|
|
text:SetFont(STANDARD_TEXT_FONT, data.text_fontSize < 33 and data.text_fontSize or 33, data.text_fontType);
|
|
end
|
|
if text:GetFont() then
|
|
text:SetText(WeakAuras.ReplaceRaidMarkerSymbols(data.text_text));
|
|
end
|
|
|
|
text:SetTextHeight(data.text_fontSize);
|
|
|
|
text:SetShadowColor(unpack(data.text_shadowColor))
|
|
text:SetShadowOffset(data.text_shadowXOffset, data.text_shadowYOffset)
|
|
text:SetJustifyH(data.text_justify or "CENTER")
|
|
|
|
if (data.text_automaticWidth == "Fixed") then
|
|
if (data.text_wordWrap == "WordWrap") then
|
|
text:SetWordWrap(true);
|
|
text:SetNonSpaceWrap(true);
|
|
else
|
|
text:SetWordWrap(false);
|
|
text:SetNonSpaceWrap(false);
|
|
end
|
|
|
|
text:SetWidth(data.text_fixedWidth);
|
|
region:SetWidth(data.text_fixedWidth);
|
|
region.width = data.text_fixedWidth;
|
|
else
|
|
text:SetWidth(0);
|
|
text:SetWordWrap(true);
|
|
text:SetNonSpaceWrap(true);
|
|
end
|
|
|
|
if first then
|
|
local containsCustomText = false
|
|
for index, subRegion in ipairs(parentData.subRegions) do
|
|
if subRegion.type == "subtext" and Private.ContainsCustomPlaceHolder(subRegion.text_text) then
|
|
containsCustomText = true
|
|
break
|
|
end
|
|
end
|
|
if not containsCustomText then
|
|
if type(parentData.conditions) == "table" then
|
|
for _, condition in ipairs(parentData.conditions) do
|
|
if type(condition.changes) == "table" then
|
|
for _, change in ipairs(condition.changes) do
|
|
if type(change.property) == "string"
|
|
and change.property:match("sub%.%d+%.text_text")
|
|
then
|
|
containsCustomText = true
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if containsCustomText and parentData.customText and parentData.customText ~= "" then
|
|
parent.customTextFunc = WeakAuras.LoadFunction("return "..parentData.customText)
|
|
else
|
|
parent.customTextFunc = nil
|
|
end
|
|
parent.values.custom = nil
|
|
parent.values.lastCustomTextUpdate = nil
|
|
end
|
|
|
|
local texts = {}
|
|
local textStr = data.text_text or ""
|
|
if textStr ~= "" then
|
|
tinsert(texts, textStr)
|
|
end
|
|
|
|
local subRegionIndex = 1
|
|
for index, subRegion in ipairs(parentData.subRegions) do
|
|
if subRegion == data then
|
|
subRegionIndex = index
|
|
break;
|
|
end
|
|
end
|
|
if type(parentData.conditions) == "table" then
|
|
local conditionName = "sub."..subRegionIndex..".text_text"
|
|
for _, condition in ipairs(parentData.conditions) do
|
|
if type(condition.changes) == "table" then
|
|
for _, change in ipairs(condition.changes) do
|
|
if type(change.property) == "string" and change.property == conditionName then
|
|
if type(change.value ) == "string" and change.value ~= "" then
|
|
tinsert(texts, change.value)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local getter = function(key, default)
|
|
local fullKey = "text_text_format_" .. key
|
|
if (data[fullKey] == nil) then
|
|
data[fullKey] = default
|
|
end
|
|
return data[fullKey]
|
|
end
|
|
region.subTextFormatters = Private.CreateFormatters(texts, getter)
|
|
|
|
function region:ConfigureTextUpdate()
|
|
local UpdateText
|
|
if region.text_text and Private.ContainsAnyPlaceHolders(region.text_text) then
|
|
UpdateText = function()
|
|
local textStr = region.text_text or ""
|
|
textStr = Private.ReplacePlaceHolders(textStr, parent, nil, false, self.subTextFormatters)
|
|
|
|
if text:GetFont() then
|
|
text:SetText(WeakAuras.ReplaceRaidMarkerSymbols(textStr))
|
|
end
|
|
region:UpdateAnchor()
|
|
end
|
|
end
|
|
|
|
local Update
|
|
if parent.customTextFunc and UpdateText then
|
|
Update = function()
|
|
if parent.values.lastCustomTextUpdate ~= GetTime() then
|
|
parent.values.custom = Private.RunCustomTextFunc(parent, parent.customTextFunc)
|
|
parent.values.lastCustomTextUpdate = GetTime()
|
|
end
|
|
UpdateText()
|
|
end
|
|
else
|
|
Update = UpdateText
|
|
end
|
|
|
|
local TimerTick
|
|
if Private.ContainsPlaceHolders(region.text_text, "p") then
|
|
TimerTick = UpdateText
|
|
end
|
|
|
|
local FrameTick
|
|
if parent.customTextFunc and parentData.customTextUpdate == "update" then
|
|
if Private.ContainsCustomPlaceHolder(region.text_text) then
|
|
FrameTick = function()
|
|
if parent.values.lastCustomTextUpdate ~= GetTime() then
|
|
parent.values.custom = Private.RunCustomTextFunc(parent, parent.customTextFunc)
|
|
parent.values.lastCustomTextUpdate = GetTime()
|
|
end
|
|
UpdateText()
|
|
end
|
|
end
|
|
end
|
|
|
|
region.Update = Update
|
|
region.FrameTick = FrameTick
|
|
region.TimerTick = TimerTick
|
|
|
|
if not UpdateText then
|
|
if text:GetFont() then
|
|
local textStr = region.text_text
|
|
textStr = textStr:gsub("\\n", "\n");
|
|
text:SetText(WeakAuras.ReplaceRaidMarkerSymbols(textStr))
|
|
end
|
|
end
|
|
end
|
|
|
|
function region:ConfigureSubscribers()
|
|
local visible = self:IsShown()
|
|
if self.Update then
|
|
if visible then
|
|
parent.subRegionEvents:AddSubscriber("Update", region)
|
|
end
|
|
else
|
|
parent.subRegionEvents:RemoveSubscriber("Update", region)
|
|
end
|
|
if self.FrameTick then
|
|
if visible then
|
|
parent.subRegionEvents:AddSubscriber("FrameTick", region)
|
|
end
|
|
else
|
|
parent.subRegionEvents:RemoveSubscriber("FrameTick", region)
|
|
end
|
|
if self.TimerTick then
|
|
if visible then
|
|
parent.subRegionEvents:AddSubscriber("TimerTick", region)
|
|
end
|
|
else
|
|
parent.subRegionEvents:RemoveSubscriber("TimerTick", region)
|
|
end
|
|
if self.Update and parent.state and visible then
|
|
self:Update()
|
|
end
|
|
end
|
|
|
|
function region:ChangeText(msg)
|
|
region.text_text = msg
|
|
region:ConfigureTextUpdate()
|
|
region:ConfigureSubscribers()
|
|
end
|
|
|
|
region.text_text = data.text_text
|
|
region:ConfigureTextUpdate()
|
|
|
|
function region:SetTextHeight(size)
|
|
local fontPath = SharedMedia:Fetch("font", data.text_font);
|
|
if not text:GetFont() then -- Font invalid, set the font but keep the setting
|
|
text:SetFont(STANDARD_TEXT_FONT, size < 33 and size or 33, data.text_fontType);
|
|
else
|
|
region.text:SetFont(fontPath, size < 33 and size or 33, data.text_fontType);
|
|
end
|
|
region.text:SetTextHeight(size)
|
|
region:UpdateAnchor();
|
|
end
|
|
|
|
function region:SetVisible(visible)
|
|
if visible then
|
|
self:Show()
|
|
else
|
|
self:Hide()
|
|
end
|
|
region:ConfigureSubscribers()
|
|
end
|
|
|
|
function region:Color(r, g, b, a)
|
|
region.color_r = r;
|
|
region.color_g = g;
|
|
region.color_b = b;
|
|
region.color_a = a;
|
|
if (r or g or b) then
|
|
a = a or 1;
|
|
end
|
|
text:SetTextColor(region.color_anim_r or r, region.color_anim_g or g,
|
|
region.color_anim_b or b, region.color_anim_a or a)
|
|
end
|
|
|
|
local selfPoint = data.text_selfPoint
|
|
if selfPoint == "AUTO" then
|
|
if parentData.regionType == "icon" then
|
|
local anchorPoint = data.text_anchorPoint or "CENTER"
|
|
if anchorPoint:sub(1, 6) == "INNER_" then
|
|
selfPoint = anchorPoint:sub(7)
|
|
elseif anchorPoint:sub(1, 6) == "OUTER_" then
|
|
anchorPoint = anchorPoint:sub(7)
|
|
selfPoint = Private.inverse_point_types[anchorPoint] or "CENTER"
|
|
else
|
|
selfPoint = "CENTER"
|
|
end
|
|
elseif parentData.regionType == "aurabar" then
|
|
selfPoint = data.text_anchorPoint or "CENTER"
|
|
if selfPoint:sub(1, 5) == "ICON_" then
|
|
selfPoint = selfPoint:sub(6)
|
|
elseif selfPoint:sub(1, 6) == "INNER_" then
|
|
selfPoint = selfPoint:sub(7)
|
|
end
|
|
selfPoint = Private.point_types[selfPoint] and selfPoint or "CENTER"
|
|
else
|
|
selfPoint = Private.inverse_point_types[data.text_anchorPoint or "CENTER"] or "CENTER"
|
|
end
|
|
end
|
|
|
|
region.text_anchorXOffset = data.text_anchorXOffset
|
|
region.text_anchorYOffset = data.text_anchorYOffset
|
|
|
|
region.UpdateAnchor = function(self)
|
|
parent:AnchorSubRegion(text, "point", selfPoint, data.text_anchorPoint, self.text_anchorXOffset or 0, self.text_anchorYOffset or 0)
|
|
end
|
|
|
|
region.SetXOffset = function(self, xOffset)
|
|
if self.text_anchorXOffset == xOffset then
|
|
return
|
|
end
|
|
self.text_anchorXOffset = xOffset
|
|
self:UpdateAnchor()
|
|
end
|
|
|
|
region.SetYOffset = function(self, yOffset)
|
|
if self.text_anchorYOffset == yOffset then
|
|
return
|
|
end
|
|
self.text_anchorYOffset = yOffset
|
|
self:UpdateAnchor()
|
|
end
|
|
|
|
region:Color(data.text_color[1], data.text_color[2], data.text_color[3], data.text_color[4]);
|
|
region:SetVisible(data.text_visible)
|
|
region:UpdateAnchor()
|
|
end
|
|
|
|
local function addDefaultsForNewAura(data)
|
|
if data.regionType == "aurabar" then
|
|
tinsert(data.subRegions, {
|
|
["type"] = "subtext",
|
|
text_text = "%p",
|
|
text_color = {1, 1, 1, 1},
|
|
text_font = defaultFont,
|
|
text_fontSize = defaultFontSize,
|
|
text_fontType = "None",
|
|
text_justify = "CENTER",
|
|
text_visible = true,
|
|
|
|
text_selfPoint = "AUTO",
|
|
text_anchorPoint = "INNER_LEFT",
|
|
anchorXOffset = 0,
|
|
anchorYOffset = 0,
|
|
|
|
text_shadowColor = { 0, 0, 0, 1},
|
|
text_shadowXOffset = 1,
|
|
text_shadowYOffset = -1,
|
|
});
|
|
|
|
tinsert(data.subRegions, {
|
|
["type"] = "subtext",
|
|
text_text = "%n",
|
|
text_color = {1, 1, 1, 1},
|
|
text_font = defaultFont,
|
|
text_fontSize = defaultFontSize,
|
|
text_fontType = "None",
|
|
text_justify = "CENTER",
|
|
text_visible = true,
|
|
|
|
text_selfPoint = "AUTO",
|
|
text_anchorPoint = "INNER_RIGHT",
|
|
anchorXOffset = 0,
|
|
anchorYOffset = 0,
|
|
|
|
text_shadowColor = { 0, 0, 0, 1},
|
|
text_shadowXOffset = 1,
|
|
text_shadowYOffset = -1,
|
|
});
|
|
elseif data.regionType == "icon" then
|
|
tinsert(data.subRegions, {
|
|
["type"] = "subtext",
|
|
text_text = "%s",
|
|
text_color = {1, 1, 1, 1},
|
|
text_font = defaultFont,
|
|
text_fontSize = defaultFontSize,
|
|
text_fontType = "OUTLINE",
|
|
text_justify = "CENTER",
|
|
text_visible = true,
|
|
|
|
text_selfPoint = "AUTO",
|
|
text_anchorPoint = "INNER_BOTTOMRIGHT",
|
|
anchorXOffset = 0,
|
|
anchorYOffset = 0,
|
|
|
|
text_shadowColor = { 0, 0, 0, 1},
|
|
text_shadowXOffset = 0,
|
|
text_shadowYOffset = 0,
|
|
});
|
|
end
|
|
end
|
|
|
|
local function supports(regionType)
|
|
return regionType == "texture"
|
|
or regionType == "progresstexture"
|
|
or regionType == "icon"
|
|
or regionType == "aurabar"
|
|
end
|
|
|
|
WeakAuras.RegisterSubRegionType("subtext", L["Text"], supports, create, modify, onAcquire, onRelease,
|
|
default, addDefaultsForNewAura, properties)
|