Repository navigation
Expand file tree
/
Copy pathUI.lua
More file actions
279 lines (257 loc) · 11.6 KB
/
Copy pathUI.lua
File metadata and controls
279 lines (257 loc) · 11.6 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
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
local testButton
local DUNGEON_PAGES = { Casts = true, Saves = true, Guide = true, RaidGuide = true, RaidSaves = true }
-- Stored as nil when on, false when off, so a fresh profile defaults to on.
local function SetOption(key, enabled)
CastAheadConfig.SetEnabled(key, enabled)
end
local function OptionEnabled(key)
return CastAheadConfig.Enabled(key)
end
-- Exposed so the toggle logic can be tested outside the game: it has now been
-- written wrong twice, both times by collapsing it into an and/or chain.
CastAheadUI.SetOption = SetOption
CastAheadUI.OptionEnabled = OptionEnabled
-- Where the icons sit relative to the nameplate: one of the nine positions in
-- CastAheadAnchors (Core.lua). Loaded before this file, so it is available.
-- The widgets that show the choice live in Options.lua and repaint themselves
-- when that window opens, so nothing here has to be told about a change.
function CastAheadUI.SetAnchor(side)
if not (CastAheadAnchors and CastAheadAnchors[side]) then return false end
CastAheadDB = CastAheadDB or {}
CastAheadDB.anchor = side ~= "left" and side or nil -- left is the default
if CastAheadCore and CastAheadCore.Reapply then CastAheadCore.Reapply() end
return true
end
-- Which way the second and later icons go. "auto" grows away from the plate
-- for the chosen position (see CastAheadAnchors in Core.lua).
function CastAheadUI.SetGrowth(direction)
if direction ~= "auto" and not (CastAheadGrowth and CastAheadGrowth[direction]) then return false end
CastAheadDB = CastAheadDB or {}
CastAheadDB.grow = direction ~= "auto" and direction or nil
if CastAheadCore and CastAheadCore.Reapply then CastAheadCore.Reapply() end
return true
end
-- The test drive stops by itself when the last sample cast runs out, so the
-- button is repainted from the addon's state rather than from what was
-- clicked. Core calls this when a run ends.
function CastAheadUI.RefreshTest()
local running = CastAheadCore and CastAheadCore.Testing and CastAheadCore.Testing()
if testButton then testButton:SetText(running and "Stop test" or "Test drive all") end
if CastAheadUI.RefreshPlayList then CastAheadUI.RefreshPlayList(running) end
end
function CastAheadUI.RefreshTabs()
CastAheadWindow.SetMenuShown("Development", CastAheadConfig.Dev())
local raid = CastAheadConfig.Get("raidMode") == true
CastAheadWindow.SetMenuShown("Features", true)
CastAheadWindow.SetMenuShown("RaidGuide", raid)
CastAheadWindow.SetMenuShown("RaidSaves", raid)
end
-- Opens the window if it is closed, then selects a page. Used by the slash
-- commands and by anything that wants a particular settings group.
function CastAheadUI.ShowTab(name)
CastAheadUI.RefreshTabs()
CastAheadWindow.Show(name)
end
function CastAheadUI.ShowUpdateNotice(message)
CastAheadWindow.ShowUpdateNotice(message)
end
local function WindowShown()
local frame = CastAheadWindow.Frame()
return frame and frame:IsShown()
end
-- Dry run of the selected dungeon's calls: icons, sounds, timeline.
function CastAheadWindow.titleButtons(add)
testButton = add("Test drive all", 110, true, function()
if CastAheadCore and CastAheadCore.Test then CastAheadCore.Test(CastAheadWindow.Dungeon()) end
end)
testButton:SetScript("OnEnter", function(self)
GameTooltip:SetOwner(self, "ANCHOR_LEFT")
GameTooltip:SetText("Test drive all", 1, 1, 1)
GameTooltip:AddLine("Play the selected dungeon's calls with nothing pulled, through the outputs switched on in General: icons on any nameplate in front of you, the centre call, the timeline, the voice and the sounds. Features that are switched on join in with samples of their own. Each feature also has its own Test button on the Features page. Click again to stop.", nil, nil, nil, true)
GameTooltip:Show()
end)
testButton:SetScript("OnLeave", GameTooltip_Hide)
CastAheadUI.RefreshTest()
end
function CastAhead_Toggle()
CastAheadUI.RefreshTabs()
CastAheadWindow.Toggle()
end
-- Kept as the name other code already calls; it selects the Sounds page,
-- and selecting it twice closes the window the way a toggle should.
function CastAheadUI.ToggleSounds()
if WindowShown() and CastAheadWindow.Current() == "Sounds" then
CastAheadWindow.Frame():Hide()
else
CastAheadUI.ShowTab("Sounds")
end
end
SLASH_CASTAHEAD1 = "/castahead"
SLASH_CASTAHEAD2 = "/ca"
local DEV_COMMANDS = { probe = true, report = true, mark = true, note = true }
SlashCmdList.CASTAHEAD = function(msg)
msg = msg and msg:lower() or ""
-- The sub-command is the FIRST word: `msg:find` anywhere in the string
-- meant "/ca anchor center" was answered by the `center` branch.
local word = msg:match("^%s*(%a+)") or ""
if DEV_COMMANDS[word] and not CastAheadConfig.Dev() then
print("|cff33ff99CastAhead|r /ca " .. word .. " needs Development mode (/ca options, Advanced)")
return
end
if word == "probe" then
if CastAheadCore and CastAheadCore.Probe then
CastAheadCore.Probe(msg:match("^%s*%a+%s+(%a+)"))
end
return
end
if word == "report" then
if CastAheadReport then CastAheadReport.Toggle() end
return
end
if word == "journal" then
if msg:match("^%s*%a+%s+clear") and StaticPopup_Show then
StaticPopup_Show("CASTAHEAD_CLEAR_JOURNAL")
elseif CastAheadRecorder then
print(string.format("|cff33ff99CastAhead|r key journal: %d of %d keys - /ca journal clear empties it",
#CastAheadRecorder.Keys(), CastAheadRecorder.MAX_KEYS))
end
return
end
if word == "mark" then
if CastAheadRecorder and CastAheadRecorder.Enabled() then
local n, key = CastAheadRecorder.Mark()
CastAheadRecorder.AddNote(n, msg:match("^%s*%a+%s+(.+)$"), key)
end
return
end
if word == "note" then
local n, text = msg:match("^%s*%a+%s+(%d+)%s+(.+)$")
if CastAheadRecorder and n and CastAheadRecorder.AddNote(n, text) then
print("|cff33ff99CastAhead|r note added to mark " .. n)
else
print("|cff33ff99CastAhead|r usage: /ca note <mark number> <text>")
end
return
end
if word == "debug" then
if CastAheadCore and CastAheadCore.Debug then CastAheadCore.Debug() end
return
end
if word == "option" or word == "options" or word == "config" or word == "settings" then
if WindowShown() and not DUNGEON_PAGES[CastAheadWindow.Current()] then
CastAheadWindow.Frame():Hide()
else
CastAheadUI.ShowTab("General")
end
return
end
if word == "sound" or word == "sounds" then
CastAheadUI.ToggleSounds()
return
end
if word == "move" then
if CastAheadCore and CastAheadCore.MoveCenter then CastAheadCore.MoveCenter() end
return
end
if word == "setup" then
if not CastAheadSetup.Enter() then print("|cff33ff99CastAhead|r Not available in combat.") end
return
end
if word == "test" then
if CastAheadCore and CastAheadCore.Test then CastAheadCore.Test(CastAheadWindow.Dungeon()) end
return
end
if word == "hide" then
if CastAheadCore and CastAheadCore.HideAll then CastAheadCore.HideAll() end
return
end
-- /ca offset 40: push the icon column this many pixels further from the
-- plate, past whatever the nameplate addon draws there.
local offset = msg:match("^%s*offset%s+(-?%d+)")
if offset then
CastAheadDB = CastAheadDB or {}
CastAheadDB.offsetX = tonumber(offset)
if CastAheadCore and CastAheadCore.Reapply then CastAheadCore.Reapply() end
print("|cff33ff99CastAhead|r icons offset by " .. offset .. " px")
return
elseif word == "offset" then
print("|cff33ff99CastAhead|r usage: /ca offset <pixels> (current "
.. tostring(CastAheadDB and CastAheadDB.offsetX or 0) .. ")")
return
end
local centerY = msg:match("^%s*center%s+(-?%d+)")
if centerY then
CastAheadDB = CastAheadDB or {}
CastAheadDB.centerY = tonumber(centerY) - CastAheadCore.CENTER_Y
print("|cff33ff99CastAhead|r centre call placed " .. centerY .. " px from the screen centre")
return
elseif word == "center" then
print("|cff33ff99CastAhead|r usage: /ca center <pixels> (current "
.. tostring(CastAheadCore.CENTER_Y + CastAheadConfig.CenterY()) .. " px from the screen centre)")
return
end
local side = msg:match("^%s*anchor%s+(%a+)")
if side and CastAheadUI.SetAnchor(side) then
print("|cff33ff99CastAhead|r icons anchored to the " .. side .. " of the nameplate")
return
elseif word == "anchor" then
print("|cff33ff99CastAhead|r usage: /ca anchor topleft|top|topright|left|center|right|bottomleft|bottom|bottomright (current "
.. tostring(CastAheadDB and CastAheadDB.anchor or "left") .. ")")
return
end
local grow = msg:match("^%s*grow%s+(%a+)")
if grow and CastAheadUI.SetGrowth(grow) then
print("|cff33ff99CastAhead|r icons grow " .. grow)
return
elseif word == "grow" then
print("|cff33ff99CastAhead|r usage: /ca grow left|down|right|up|auto (current "
.. tostring(CastAheadDB and CastAheadDB.grow or "auto") .. ")")
return
end
CastAhead_Toggle()
end
-- Entry in the game's addon compartment (the button list on the minimap).
function CastAhead_OnCompartmentClick()
CastAhead_Toggle()
end
-- An entry in the game's own AddOns list, which is where a player who does not
-- know the slash command looks first. Every setting lives in our window, so
-- this page is a signpost to it rather than a second copy of the settings that
-- would then have to be kept in step.
local function RegisterSettingsCategory()
if not (Settings and Settings.RegisterCanvasLayoutCategory) then return end
local panel = CreateFrame("Frame")
panel.name = "CastAhead"
local title = panel:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
title:SetPoint("TOPLEFT", 16, -16)
title:SetPoint("TOPRIGHT", -16, -16)
title:SetJustifyH("LEFT")
title:SetText("CastAhead")
local blurb = panel:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
blurb:SetPoint("TOPLEFT", title, "BOTTOMLEFT", 0, -10)
blurb:SetPoint("TOPRIGHT", title, "BOTTOMRIGHT", 0, -10)
blurb:SetJustifyH("LEFT")
blurb:SetJustifyV("TOP")
blurb:SetText("Everything CastAhead has is in its own window: the tracked casts, "
.. "what gets called out, where it is drawn and how it sounds.\n\n"
.. "Open it with |cffffd100/ca|r, the minimap button, or the button below.")
local open = CreateFrame("Button", nil, panel, "UIPanelButtonTemplate")
open:SetSize(180, 24)
open:SetPoint("TOPLEFT", blurb, "BOTTOMLEFT", 0, -16)
open:SetText("Open CastAhead")
open:SetScript("OnClick", function()
-- Close the game's settings first: our window would otherwise open
-- behind it, which reads as the button doing nothing.
if SettingsPanel and SettingsPanel:IsShown() then
HideUIPanel(SettingsPanel)
end
if not WindowShown() then CastAhead_Toggle() end
end)
local category = Settings.RegisterCanvasLayoutCategory(panel, "CastAhead")
category.ID = "CastAhead"
Settings.RegisterAddOnCategory(category)
end
-- Registered as the file loads. The settings API is up before addons are, and
-- an event frame here would be the first OnEvent handler in the file, which is
-- what the stubbed API in the test suite hands events to.
RegisterSettingsCategory()