-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathOptions.lua
More file actions
377 lines (319 loc) · 13.3 KB
/
Options.lua
File metadata and controls
377 lines (319 loc) · 13.3 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
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
-- ZaeUI_ActionBars Options panel
-- Registers a settings panel under AddOns > ZaeUI > ActionBars
local _, ns = ...
-- Widget helpers ----------------------------------------------------------------
--- Create a cycle button that rotates through a list of options.
--- @param parent table Parent frame
--- @param y number Y offset from TOPLEFT
--- @param label string Button label
--- @param options table Array of { value, text } pairs
--- @param get function Returns current value
--- @param set function Called with new value
--- @return table button The created button
--- @return number nextY The Y offset for the next widget
local function createCycleButton(parent, y, label, options, get, set)
local container = CreateFrame("Frame", nil, parent)
container:SetSize(350, 26)
container:SetPoint("TOPLEFT", parent, "TOPLEFT", 16, y)
local title = container:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
title:SetPoint("LEFT", 0, 0)
title:SetText(label .. ":")
local btn = CreateFrame("Button", nil, container)
btn:SetSize(120, 22)
btn:SetPoint("LEFT", title, "RIGHT", 8, 0)
local bg = btn:CreateTexture(nil, "BACKGROUND")
bg:SetAllPoints()
bg:SetColorTexture(0.2, 0.2, 0.2, 0.8)
local btnText = btn:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
btnText:SetPoint("CENTER")
local function updateText()
local current = get()
for i = 1, #options do
if options[i][1] == current then
btnText:SetText(options[i][2])
return
end
end
btnText:SetText("?")
end
updateText()
btn:SetScript("OnClick", function()
local current = get()
local nextIdx = 1
for i = 1, #options do
if options[i][1] == current then
nextIdx = (i % #options) + 1
break
end
end
set(options[nextIdx][1])
updateText()
end)
btn:SetScript("OnEnter", function()
bg:SetColorTexture(0.3, 0.3, 0.3, 0.9)
end)
btn:SetScript("OnLeave", function()
bg:SetColorTexture(0.2, 0.2, 0.2, 0.8)
end)
btn.refresh = function()
updateText()
end
return btn, y - 30
end
-- Tab bar colors
local TAB_COLOR_NORMAL = { r = 0.2, g = 0.2, b = 0.2, a = 0.8 }
local TAB_COLOR_HOVER = { r = 0.3, g = 0.3, b = 0.3, a = 0.9 }
local TAB_COLOR_SELECTED = { r = 0.1, g = 0.4, b = 0.7, a = 1.0 }
local TAB_HEIGHT = 24
local TAB_SPACING = 2
local TABS_PER_ROW = 5
-- Panel creation ----------------------------------------------------------------
local function createOptionsPanel(parentCategory)
local currentDB = ns.db
local C = ns.constants
local orderList = ns.BAR_ORDER
local nameList = ns.BAR_NAMES
local panel = CreateFrame("Frame")
panel:SetSize(1, 1)
-- General options area (above tabs)
local generalWidgets = {}
local generalArea = CreateFrame("Frame", nil, panel)
generalArea:SetPoint("TOPLEFT", panel, "TOPLEFT", 12, -8)
generalArea:SetPoint("TOPRIGHT", panel, "TOPRIGHT", -12, -8)
generalArea:SetHeight(30)
local gw
gw, _ = ZaeUI_Shared.createCheckbox(generalArea, -4, "Show load message in chat",
function() return currentDB.showLoadMessage end,
function(checked)
currentDB.showLoadMessage = checked
end
)
generalWidgets[#generalWidgets + 1] = gw
-- Tab buttons container (two rows: 5 + 5)
local tabContainer = CreateFrame("Frame", nil, panel)
tabContainer:SetPoint("TOPLEFT", generalArea, "BOTTOMLEFT", 0, -4)
tabContainer:SetPoint("TOPRIGHT", generalArea, "BOTTOMRIGHT", 0, -4)
tabContainer:SetHeight(TAB_HEIGHT * 2 + TAB_SPACING)
-- Content area below tabs
local contentArea = CreateFrame("Frame", nil, panel)
contentArea:SetPoint("TOPLEFT", tabContainer, "BOTTOMLEFT", 0, -8)
contentArea:SetPoint("BOTTOMRIGHT", panel, "BOTTOMRIGHT", 0, 0)
-- Separator line between tabs and content
local separator = contentArea:CreateTexture(nil, "ARTWORK")
separator:SetPoint("TOPLEFT", contentArea, "TOPLEFT", 0, 0)
separator:SetPoint("TOPRIGHT", contentArea, "TOPRIGHT", 0, 0)
separator:SetHeight(1)
separator:SetColorTexture(0.4, 0.4, 0.4, 0.6)
-- Per-bar content frames (created once, shown/hidden on tab switch)
local barPages = {}
local tabButtons = {}
local selectedTab = nil
--- Switch to the given tab, hiding all others.
--- @param barID string The bar to show
local function selectTab(barID)
if selectedTab == barID then return end
-- Hide previous page
if selectedTab and barPages[selectedTab] then
barPages[selectedTab]:Hide()
end
-- Update tab button colors
for _, id in ipairs(orderList) do
local btn = tabButtons[id]
if id == barID then
btn.bg:SetColorTexture(TAB_COLOR_SELECTED.r, TAB_COLOR_SELECTED.g, TAB_COLOR_SELECTED.b, TAB_COLOR_SELECTED.a)
btn.label:SetFontObject("GameFontHighlight")
else
btn.bg:SetColorTexture(TAB_COLOR_NORMAL.r, TAB_COLOR_NORMAL.g, TAB_COLOR_NORMAL.b, TAB_COLOR_NORMAL.a)
btn.label:SetFontObject("GameFontNormalSmall")
end
end
-- Show new page
selectedTab = barID
barPages[barID]:Show()
end
-- Create tab buttons (two rows of 5)
for i, barID in ipairs(orderList) do
local row = (i <= TABS_PER_ROW) and 0 or 1
local col = (i <= TABS_PER_ROW) and (i - 1) or (i - TABS_PER_ROW - 1)
local btn = CreateFrame("Button", nil, tabContainer)
btn:SetHeight(TAB_HEIGHT)
-- Background texture
local bg = btn:CreateTexture(nil, "BACKGROUND")
bg:SetAllPoints()
bg:SetColorTexture(TAB_COLOR_NORMAL.r, TAB_COLOR_NORMAL.g, TAB_COLOR_NORMAL.b, TAB_COLOR_NORMAL.a)
btn.bg = bg
-- Label
local label = btn:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
label:SetPoint("CENTER")
label:SetText(nameList[barID])
btn.label = label
-- Position: evenly spaced across the container width
local yOffset = -(row * (TAB_HEIGHT + TAB_SPACING))
btn:SetPoint("TOPLEFT", tabContainer, "TOPLEFT", 0, yOffset)
-- Use relative width via anchoring to fraction of container
btn:SetScript("OnShow", function(self)
local containerWidth = tabContainer:GetWidth()
local tabWidth = (containerWidth - (TABS_PER_ROW - 1) * TAB_SPACING) / TABS_PER_ROW
self:SetWidth(tabWidth)
self:ClearAllPoints()
self:SetPoint("TOPLEFT", tabContainer, "TOPLEFT", col * (tabWidth + TAB_SPACING), yOffset)
end)
-- Hover effects
btn:SetScript("OnEnter", function()
if selectedTab ~= barID then
bg:SetColorTexture(TAB_COLOR_HOVER.r, TAB_COLOR_HOVER.g, TAB_COLOR_HOVER.b, TAB_COLOR_HOVER.a)
end
end)
btn:SetScript("OnLeave", function()
if selectedTab ~= barID then
bg:SetColorTexture(TAB_COLOR_NORMAL.r, TAB_COLOR_NORMAL.g, TAB_COLOR_NORMAL.b, TAB_COLOR_NORMAL.a)
end
end)
btn:SetScript("OnClick", function()
selectTab(barID)
end)
tabButtons[barID] = btn
end
-- Resize tabs when panel size changes
panel:SetScript("OnSizeChanged", function()
local containerWidth = tabContainer:GetWidth()
if containerWidth <= 0 then return end
local tabWidth = (containerWidth - (TABS_PER_ROW - 1) * TAB_SPACING) / TABS_PER_ROW
for i, barID in ipairs(orderList) do
local row = (i <= TABS_PER_ROW) and 0 or 1
local col = (i <= TABS_PER_ROW) and (i - 1) or (i - TABS_PER_ROW - 1)
local yOffset = -(row * (TAB_HEIGHT + TAB_SPACING))
local btn = tabButtons[barID]
btn:SetWidth(tabWidth)
btn:ClearAllPoints()
btn:SetPoint("TOPLEFT", tabContainer, "TOPLEFT", col * (tabWidth + TAB_SPACING), yOffset)
end
end)
-- Per-bar widget lists for refresh
local barWidgets = {}
-- Create content pages for each bar
for _, barID in ipairs(orderList) do
local barSettings = currentDB.bars[barID]
local widgets = {}
-- Page container (holds the scroll frame)
local page = CreateFrame("Frame", nil, contentArea)
page:SetPoint("TOPLEFT", contentArea, "TOPLEFT", 0, -8)
page:SetPoint("BOTTOMRIGHT", contentArea, "BOTTOMRIGHT", 0, 0)
page:Hide()
-- ScrollFrame inside each tab page
local pageScroll = CreateFrame("ScrollFrame", nil, page, "UIPanelScrollFrameTemplate")
pageScroll:SetPoint("TOPLEFT", 0, 0)
pageScroll:SetPoint("BOTTOMRIGHT", -26, 0)
local pageContent = CreateFrame("Frame", nil, pageScroll)
pageContent:SetWidth(pageScroll:GetWidth() or 540)
pageScroll:SetScrollChild(pageContent)
page:SetScript("OnSizeChanged", function(_, width)
pageContent:SetWidth(width - 26)
end)
local y = -8
local w
w, y = ZaeUI_Shared.createCheckbox(pageContent, y, "Enable",
function() return barSettings.enabled end,
function(checked)
if checked and InCombatLockdown() then
print("|cff00ccff[ZaeUI_ActionBars]|r Cannot enable bar during combat. Try again after combat.")
-- Revert checkbox visually
C_Timer.After(0, function() w:SetChecked(false) end)
return
end
barSettings.enabled = checked
if checked then
ns.applyBar(barID)
else
ns.removeBar(barID)
end
end
)
widgets[#widgets + 1] = w
w, y = ZaeUI_Shared.createCheckbox(pageContent, y, "Show in combat",
function() return barSettings.showInCombat end,
function(checked) barSettings.showInCombat = checked end
)
widgets[#widgets + 1] = w
w, y = createCycleButton(pageContent, y, "While flying", ns.BEHAVIOR_OPTIONS,
function() return barSettings.flyingBehavior end,
function(v)
if InCombatLockdown() then
print("|cff00ccff[ZaeUI_ActionBars]|r Cannot change this setting during combat.")
return
end
barSettings.flyingBehavior = v
ns.applyBar(barID)
end
)
widgets[#widgets + 1] = w
w, y = createCycleButton(pageContent, y, "While mounted", ns.BEHAVIOR_OPTIONS,
function() return barSettings.mountedBehavior end,
function(v)
if InCombatLockdown() then
print("|cff00ccff[ZaeUI_ActionBars]|r Cannot change this setting during combat.")
return
end
barSettings.mountedBehavior = v
ns.applyBar(barID)
end
)
widgets[#widgets + 1] = w
w, y = ZaeUI_Shared.createSlider(pageContent, y, "Fade In (s)", C.MIN_FADE, C.MAX_FADE, 0.1,
function() return barSettings.fadeIn end,
function(v) barSettings.fadeIn = v end
)
widgets[#widgets + 1] = w
w, y = ZaeUI_Shared.createSlider(pageContent, y, "Fade Out (s)", C.MIN_FADE, C.MAX_FADE, 0.1,
function() return barSettings.fadeOut end,
function(v) barSettings.fadeOut = v end
)
widgets[#widgets + 1] = w
w, y = ZaeUI_Shared.createSlider(pageContent, y, "Delay (s)", C.MIN_DELAY, C.MAX_DELAY, 0.1,
function() return barSettings.delay end,
function(v) barSettings.delay = v end
)
widgets[#widgets + 1] = w
pageContent:SetHeight(-y + 16)
barPages[barID] = page
barWidgets[barID] = widgets
end
-- Expose refresh function for /zab reset
ns.refreshWidgets = function()
for i = 1, #generalWidgets do
if generalWidgets[i].refresh then
generalWidgets[i].refresh()
end
end
for _, barID in ipairs(orderList) do
local wList = barWidgets[barID]
if wList then
for j = 1, #wList do
if wList[j].refresh then
wList[j].refresh()
end
end
end
end
end
-- Select first tab by default
selectTab(orderList[1])
local subCategory = Settings.RegisterCanvasLayoutSubcategory(parentCategory, panel, "ActionBars")
ns.settingsCategory = subCategory
end
-- Loader --------------------------------------------------------------------
local loader = CreateFrame("Frame")
loader:RegisterEvent("ADDON_LOADED")
loader:SetScript("OnEvent", function(self, _, addonName)
if addonName ~= "ZaeUI_ActionBars" then return end
self:UnregisterEvent("ADDON_LOADED")
if not ZaeUI_Shared then return end
local parentCategory = ZaeUI_Shared.ensureParentCategory()
C_Timer.After(0, function()
if ns.db then
createOptionsPanel(parentCategory)
else
print("|cff00ccff[ZaeUI_ActionBars]|r Options panel failed to load: database not initialized.")
end
end)
end)