-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSubText.lua
More file actions
244 lines (228 loc) · 10 KB
/
Copy pathSubText.lua
File metadata and controls
244 lines (228 loc) · 10 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
-- WeakestAuras -- the "subtext" sub-region: a placeholder-driven FontString a
-- display can carry any number of (stacks, remaining time, name...). Mirrors
-- WA2's SubText (§8/§9).
-- Upstream section refs (§N) point at design/architecture/weakauras2-reference.md
--
-- An instance is a plain object wrapping a FontString parented to the region.
-- It never polls: it subscribes to the region's subRegionEvents bus -- "Update"
-- (state changed) always, "FrameTick" only when its text contains %p, "PreShow"
-- to reassert visibility a condition may have cleared. Text is resolved through
-- WA.ReplacePlaceHolders against the region's active state, via the per-symbol
-- formatters built from this instance's text_text_format_* settings.
if WeakestAuras.disabled then return end
local WA = WeakestAuras
local proto = WA.regionPrototype
-- The nine standard frame anchor points offered by the Anchor dropdown.
local TEXT_ANCHORS = {
"TOPLEFT", "TOP", "TOPRIGHT",
"LEFT", "CENTER", "RIGHT",
"BOTTOMLEFT", "BOTTOM", "BOTTOMRIGHT",
}
-- Per-symbol format settings (WA.format_types) are flat keys on the sub-region
-- under upstream's layout, text_text_format_<symbol>_<setting>. Both the
-- formatter build and the options generator address them through these.
local function formatGetter(subData)
return function(key, default)
local v = subData["text_text_format_" .. key]
if v == nil then return default end
return v
end
end
WA.RegisterSubRegionType("subtext", {
displayName = "Text",
supports = function(regionType)
return regionType == "icon" or regionType == "progressbar" or regionType == "texture"
end,
default = {
type = "subtext",
text_text = "%s",
text_color = { 1, 1, 1, 1 },
text_fontSize = 12,
anchor_point = "CENTER",
anchorXOffset = 0,
anchorYOffset = 0,
text_visible = true,
},
-- Icon: a %s stacks text bottom-right. Bar: %n name at the left, %p time at
-- the right (upstream's own new-aura defaults, §8).
addDefaultsForNewAura = function(data)
if data.regionType == "icon" then
table.insert(data.subRegions, {
type = "subtext", text_text = "%s", text_color = { 1, 1, 1, 1 },
text_fontSize = 12, anchor_point = "BOTTOMRIGHT", anchorXOffset = -2, anchorYOffset = 2,
text_visible = true,
})
elseif data.regionType == "progressbar" then
-- Offsets are from the *bar*, not the whole region (see modify below),
-- so neither has to leave room for an icon that may not be there.
table.insert(data.subRegions, {
type = "subtext", text_text = "%n", text_color = { 1, 1, 1, 1 },
text_fontSize = 10, anchor_point = "LEFT", anchorXOffset = 3, anchorYOffset = 0,
text_visible = true,
})
table.insert(data.subRegions, {
type = "subtext", text_text = "%p", text_color = { 1, 1, 1, 1 },
text_fontSize = 10, anchor_point = "RIGHT", anchorXOffset = -3, anchorYOffset = 0,
text_visible = true,
})
end
end,
-- Condition-overridable properties, namespaced sub.<n>.* (§8). Each setter
-- is a method defined in create below.
properties = {
text_visible = { display = "Visible", setter = "SetVisible", type = "bool" },
text_color = { display = "Color", setter = "SetTextColor", type = "color" },
text_fontSize = { display = "Font Size", setter = "SetTextHeight", type = "number", min = 6, max = 48, step = 1 },
},
create = function(parent)
local region = { parent = parent }
-- The FontString lives in a frame of its own, not on the region: a child
-- frame's draw layers all sit above its parent's, so text created directly
-- on the region renders *under* anything the region type builds as a child
-- frame -- the progress bar, the icon's cooldown swipe. The level is
-- (re)asserted in modify, since SetParent resets it.
local frame = CreateFrame("Frame", nil, parent)
frame:SetAllPoints(parent)
region.frame = frame
local fs = frame:CreateFontString(nil, "OVERLAY")
region.fontString = fs
function region:Update()
WA.textCore.SetText(self.fontString,
WA.ReplacePlaceHolders(self.text or "", self.parent, self.formatters))
end
function region:Show() if self.visible ~= false then self.fontString:Show() end end
function region:Hide() self.fontString:Hide() end
function region:SetVisible(b)
self.visible = b
if b then self.fontString:Show() else self.fontString:Hide() end
end
function region:SetTextColor(r, g, b, a)
self.fontString:SetTextColor(r, g, b, a or 1)
end
function region:SetTextHeight(size)
WA.textCore.Apply(self.fontString, self.subData, "text_", size, WA.textCore.SUBTEXT_KEYS)
self.fontString:SetTextHeight(size)
end
return region
end,
modify = function(parent, region, parentData, subData)
region.subData = subData
region.text = subData.text_text or ""
region.visible = subData.text_visible ~= false
region.formatters, region.everyFrameFormatters =
WA.CreateFormatters(region.text, formatGetter(subData), parentData)
local fs = region.fontString
WA.textCore.Apply(fs, subData, "text_", nil, WA.textCore.SUBTEXT_KEYS)
region.frame:SetFrameLevel(parent:GetFrameLevel() + WA.regionPrototype.SUB_LEVEL)
proto.AnchorSubRegion(fs, parent, subData, {
mode = subData.anchor_mode or "point", target = parent.subRegionAnchor and "bar" or "region",
anchorPoint = subData.anchor_point or "CENTER",
selfPoint = subData.anchor_point or "CENTER",
x = subData.anchorXOffset or 0, y = subData.anchorYOffset or 0,
})
if region.visible then fs:Show() else fs:Hide() end
parent.subRegionEvents:AddSubscriber("Update", function() region:Update() end)
parent.subRegionEvents:AddSubscriber("PreShow", function()
if region.visible then fs:Show() end
end)
-- Two independent reasons to repaint per frame: the string's own (%p, an
-- every-frame formatter), and a %c whose function is set to run per frame.
-- The second is the parent's setting, asked one level up -- the parent has
-- already subscribed its refresh ahead of this, so what is left here is
-- re-resolving the string against the values it just recomputed.
local needsTick = WA.TextNeedsFrameTick(region.text, region.everyFrameFormatters)
or (parent.customTextFunc ~= nil and parent.customTextMode == "update"
and WA.ContainsCustomPlaceHolder(region.text))
if needsTick then
parent.subRegionEvents:AddSubscriber("FrameTick", function() region:Update() end)
end
region:Update()
end,
-- BuildOptions field array for OptionsFrame's Display Effects list.
options = function(parentData, subData, index)
local fields = {
{
-- %i is absent from the label deliberately: it resolves to nothing
-- here, this client's FontString having no inline texture escape.
type = "input", name = "Text (%p %t %n %s %c)", key = "text_text",
get = function() return subData.text_text end,
-- Re-renders the tab: Format Options below is one row per symbol
-- in this string, so editing it changes which rows exist.
set = function(v)
subData.text_text = v
WA.SetDefaultFormatters(subData.text_text, formatGetter(subData),
function(key, value) subData["text_text_format_" .. key] = value end,
parentData)
WA.Add(parentData, true)
WA.RefreshOptions()
end,
},
{
type = "range", name = "Size", key = "text_fontSize", min = 6, max = 48, step = 1, half = true,
get = function() return subData.text_fontSize end,
set = function(v) subData.text_fontSize = v; WA.Add(parentData, true) end,
},
{
type = "color", name = "Color", key = "text_color",
get = function() return subData.text_color end,
set = function(v) subData.text_color = v; WA.Add(parentData, true) end,
},
}
local anchorFields = WA.regionPrototype.SubRegionAnchorFields(parentData, subData, {
mode = subData.anchor_mode or "point", target = parentData.regionType == "progressbar" and "bar" or "region",
anchorPoint = subData.anchor_point or "CENTER",
selfPoint = subData.anchor_point or "CENTER",
x = subData.anchorXOffset or 0, y = subData.anchorYOffset or 0,
})
for i = 1, table.getn(anchorFields) do table.insert(fields, anchorFields[i]) end
-- Directly under the Text field, whose label can only name the five
-- built-in symbols.
local hint = WA.TextSymbolHint(parentData)
if hint then table.insert(fields, 2, { type = "description", name = hint }) end
-- Keyed inside the "sub:" namespace for the same reason the Format fold
-- below is: removing a sub-region renumbers the rest, and clearCollapsed
-- drops the whole namespace with it.
local fontFields = WA.textCore.OptionFields(parentData, "sub:" .. index .. ":font",
function(key) return subData["text_" .. key] end,
function(key, v)
subData["text_" .. key] = v
WA.Add(parentData, true)
end, WA.textCore.SUBTEXT_KEYS)
for i = 1, table.getn(fontFields) do table.insert(fields, fontFields[i]) end
local get = formatGetter(subData)
local formatFields = WA.FormatOptionFields(subData.text_text, get,
function(key, v)
subData["text_text_format_" .. key] = v
WA.Add(parentData, true)
end, parentData)
if table.getn(formatFields) > 0 then
-- Folded away by default: every %symbol in the text grows a Format row,
-- and with two or three symbols those rows bury the ones actually being
-- edited under settings that get chosen once. The summary keeps the
-- closed line honest about what they hold.
--
-- Keyed inside the "sub:" namespace so removing a sub-region clears this
-- along with that sub-region's own fold state (OptionsFrame's
-- clearCollapsed) -- otherwise the renumbering would land it on a
-- different text's format rows.
local S = WA.OptionsState
local key = "sub:" .. index .. ":format"
local collapsed = S.isCollapsed(parentData, key, true)
table.insert(fields, {
type = "disclosure", name = "Format Options",
summary = WA.FormatSummary(subData.text_text, get, parentData),
collapsed = collapsed,
onToggle = function()
S.setCollapsed(parentData, key, not collapsed)
WA.RefreshOptions()
end,
})
if not collapsed then
for i = 1, table.getn(formatFields) do
table.insert(fields, formatFields[i])
end
end
end
return fields
end,
})