-
Notifications
You must be signed in to change notification settings - Fork 152
Expand file tree
/
Copy pathEUI__General_Options.lua
More file actions
7624 lines (7060 loc) · 413 KB
/
Copy pathEUI__General_Options.lua
File metadata and controls
7624 lines (7060 loc) · 413 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
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
-------------------------------------------------------------------------------
-- EUI__General_Options.lua
-- Registers the Global Settings module with EllesmereUI
-- CVar-based settings that apply to all EllesmereUI addons
--
-- Default-application policy:
-- We use C_CVar.GetCVarInfo(name) to get both the current value and
-- Blizzard's built-in default. Our preferred defaults are only applied
-- when the CVar is still sitting at Blizzard's default -- meaning
-- neither the player nor another addon has touched it. If the value
-- differs from the Blizzard default in any way, we leave it alone.
-- Widgets always read the live CVar value so they stay in sync
-- regardless of who set it.
-------------------------------------------------------------------------------
local ADDON_NAME = ...
-------------------------------------------------------------------------------
-- Page / section names
-------------------------------------------------------------------------------
local PAGE_GENERAL = "General"
local PAGE_COLORS = "Fonts & Colors"
local PAGE_PROFILES = "Profiles"
local PAGE_PRESETS = "Presets" -- navigation tab over the presets subpage of the profiles page
local PAGE_WHATSNEW = "Patch Notes"
-- Profiles and Patch Notes are their own sidebar pages (single-page modules),
-- not tabs under Global Settings. These keys match the sidebar buttons created
-- in EllesmereUI.lua.
local PROFILES_KEY = "_EUIProfiles"
local PATCHNOTES_KEY = "_EUIPatchNotes"
-- Standalone single-module builds rename the host addon to contain "Standalone".
-- The What's New tab is suite-only, so it is never added to the page list there.
local IS_STANDALONE = type(ADDON_NAME) == "string" and ADDON_NAME:find("Standalone") ~= nil
-------------------------------------------------------------------------------
-- Shared CDM spell-layout export flow
-- Used by BOTH the full-profile export and the per-addon export. Asks whether
-- to bundle the CDM spell layout (which spells sit on which bars + per-spell
-- settings); on Yes, opens the spec picker so the user chooses which specs.
-- Calls exportFn(includeCDM, cdmSpecs) with the result. An export string is
-- produced ONLY on an explicit "No" (without layout) or a completed picker
-- selection -- closing/escaping either popup produces NO export.
-------------------------------------------------------------------------------
function EllesmereUI.RunCDMSpellExportFlow(activeName, exportFn)
local function pickThenExport()
local specs = {}
local sp = EllesmereUIDB and EllesmereUIDB.spellAssignments
and EllesmereUIDB.spellAssignments.profiles
and EllesmereUIDB.spellAssignments.profiles[activeName]
and EllesmereUIDB.spellAssignments.profiles[activeName].specProfiles
local n = (GetNumSpecializations and GetNumSpecializations()) or 0
for i = 1, n do
local specID = GetSpecializationInfo and GetSpecializationInfo(i)
if specID then
local key = tostring(specID)
local d = sp and sp[key]
specs[#specs + 1] = {
key = key,
checked = (d and type(d.barSpells) == "table" and next(d.barSpells) ~= nil) and true or false,
}
end
end
EllesmereUI:ShowCDMSpecPickerPopup({
title = EllesmereUI.L("Export CDM Spells"),
subtitle = EllesmereUI.L("This can't change which spells the user tracks in Blizzard's CDM.\nIt's recommended to also share your Blizzard CDM layout for any spec you choose here."),
subtitleColor = { 1, 0.82, 0.2 },
subtitleAtBottom = true,
confirmText = EllesmereUI.L("Export"),
specs = specs,
onConfirm = function(selectedSpecs) exportFn(true, selectedSpecs) end,
onCancel = function() end, -- cancel / Esc / click-off: just close, NO export
})
end
EllesmereUI:ShowConfirmPopup({
title = EllesmereUI.L("Include CDM Spell Layout?"),
message = EllesmereUI.L("Include your Cooldown Manager spell layout (which spells sit on which bars) plus all per-spell settings for any specs you choose."),
confirmText = EllesmereUI.L("Yes"),
cancelText = EllesmereUI.L("No"),
onConfirm = function() pickThenExport() end,
onCancel = function() exportFn(false, nil) end, -- "No": export WITHOUT layout
onDismiss = function() end, -- Esc / click-off: just close, NO export
})
end
-------------------------------------------------------------------------------
-- What's New? page -- interactive patch notes in three tiers of importance:
-- 1) hero cards (two per row), 2) small clickable listings, 3) fix lines.
-- Content lives in EllesmereUI._WHATSNEW_PATCHES (newest patch first). A
-- hero/listing entry with a `nav` deep-links to the setting it changed via
-- EllesmereUI:NavigateToElementSettings (opens the page + green-pulses the
-- control); an entry with NO `nav` renders as a static, non-clickable card
-- (for automatic behavior that has no setting to open). Defined at file scope
-- (namespace function) so it adds no locals or upvalues to the deferred
-- options closure below.
-------------------------------------------------------------------------------
function EllesmereUI._BuildWhatsNewPage(pageName, parent, yOffset)
local PP = EllesmereUI.PanelPP
local EG = EllesmereUI.ELLESMERE_GREEN
local PAD = EllesmereUI.CONTENT_PAD
local W = EllesmereUI.Widgets
local MakeFont = EllesmereUI.MakeFont
local MakeBorder = EllesmereUI.MakeBorder
-- This page is a free-form feed, not a DualRow split layout.
parent._showRowDivider = nil
local y = yOffset
local totalW = parent:GetWidth() - PAD * 2
local CARD_GAP = 14
-- Display title: "Module: Title" -- the module name is prepended to every entry.
local function TitleOf(e)
return ((e.module and EllesmereUI.L(e.module) .. ": ") or "") .. (EllesmereUI.L(e.title) or "")
end
-- Stable sort by module display name so same-module entries group together
-- (preserves authored order within a module).
local function SortByModule(list)
local idx = {}
for i, e in ipairs(list) do idx[i] = { e, i } end
table.sort(idx, function(a, b)
local am, bm = a[1].module or "", b[1].module or ""
if am ~= bm then return am < bm end
return a[2] < b[2]
end)
local out = {}
for i = 1, #idx do out[i] = idx[i][1] end
return out
end
-- Deep-link to a setting (opens the page; highlights the control if mapped).
local function GoTo(nav)
if nav and nav.module then
EllesmereUI:NavigateToElementSettings(nav.module, nav.page, nav.section, nav.preSelect, nav.highlight)
end
end
-- Tier 1: a clickable hero card -- dark fill, faint border, green top accent,
-- title + wrapping description, uniform hover lift.
local function MakeHeroCard(x, cy, w, hgt, entry)
local card = CreateFrame("Button", nil, parent)
PP.Size(card, w, hgt)
PP.Point(card, "TOPLEFT", parent, "TOPLEFT", x, cy)
card:SetFrameLevel(parent:GetFrameLevel() + 2)
local bg = card:CreateTexture(nil, "BACKGROUND")
bg:SetAllPoints()
bg:SetColorTexture(0.06, 0.08, 0.10, 0.50)
local brd = MakeBorder(card, 1, 1, 1, 0.12, PP)
local accent = card:CreateTexture(nil, "ARTWORK", nil, 7)
accent:SetColorTexture(EG.r, EG.g, EG.b, 0.6)
PP.Point(accent, "TOPLEFT", card, "TOPLEFT", 1, -1)
PP.Point(accent, "TOPRIGHT", card, "TOPRIGHT", -1, -1)
accent:SetHeight(2)
if PP.DisablePixelSnap then PP.DisablePixelSnap(accent) end
local titleFs = MakeFont(card, 14, nil, EG.r, EG.g, EG.b, 0.9)
PP.Point(titleFs, "TOPLEFT", card, "TOPLEFT", 16, -14)
PP.Point(titleFs, "RIGHT", card, "RIGHT", -16, 0)
titleFs:SetJustifyH("LEFT"); titleFs:SetWordWrap(false)
titleFs:SetText(TitleOf(entry))
local descFs = MakeFont(card, 12, nil, 1, 1, 1, 0.45)
PP.Point(descFs, "TOPLEFT", titleFs, "BOTTOMLEFT", 0, -7)
PP.Point(descFs, "RIGHT", card, "RIGHT", -16, 0)
descFs:SetJustifyH("LEFT"); descFs:SetJustifyV("TOP"); descFs:SetWordWrap(true)
descFs:SetText(EllesmereUI.L(entry.desc) or "")
-- Clickable only when the entry has a nav target. An entry with no nav
-- (automatic behavior with no setting to open -- e.g. party frames in
-- arena) renders as a static card: no hover lift, no click, and mouse
-- disabled so nothing invites a click that would go nowhere.
if entry.nav and entry.nav.module then
card:SetScript("OnEnter", function()
bg:SetColorTexture(0.11, 0.13, 0.15, 0.50); brd:SetColor(1, 1, 1, 0.22)
titleFs:SetAlpha(1)
end)
card:SetScript("OnLeave", function()
bg:SetColorTexture(0.06, 0.08, 0.10, 0.50); brd:SetColor(1, 1, 1, 0.12)
titleFs:SetAlpha(0.9)
end)
card:SetScript("OnClick", function() GoTo(entry.nav) end)
else
card:EnableMouse(false)
end
end
-- Tier 1b: a full-width banner hero (entry.banner = true), styled after
-- the announcement popups (EllesmereUI_RaidFramesPopup /
-- EllesmereUI_PatchNotesPopup): their solid panel fill and white 1px
-- border, the 2px green top accent, a small green eyebrow over a LARGE
-- centered title and centered description, and -- their signature --
-- decorative abstract art built from plain texture bars. Here the art is
-- two mirrored mini bar-charts flanking the text: cost stepping DOWN into
-- a green bar on the left, framerate stepping UP to a green bar on the
-- right. Takes a whole row; height follows the description. Static unless
-- the entry carries a nav.
local function MakeBannerCard(x, cy, w, entry)
local card = CreateFrame("Button", nil, parent)
-- Width FIRST, height provisional: the description anchors LEFT+RIGHT
-- to the card, so the card must already be its real width when the
-- text lays out (and is measured below) -- a width-0 card renders the
-- description as one truncated line instead of wrapping it.
PP.Size(card, w, 100)
PP.Point(card, "TOPLEFT", parent, "TOPLEFT", x, cy)
card:SetFrameLevel(parent:GetFrameLevel() + 2)
local bg = card:CreateTexture(nil, "BACKGROUND")
bg:SetAllPoints()
bg:SetColorTexture(0.06, 0.08, 0.10, 0.92)
local brd = MakeBorder(card, 1, 1, 1, 0.15, PP)
local accent = card:CreateTexture(nil, "ARTWORK", nil, 7)
accent:SetColorTexture(EG.r, EG.g, EG.b, 0.9)
PP.Point(accent, "TOPLEFT", card, "TOPLEFT", 1, -1)
PP.Point(accent, "TOPRIGHT", card, "TOPRIGHT", -1, -1)
accent:SetHeight(2)
if PP.DisablePixelSnap then PP.DisablePixelSnap(accent) end
-- Flanking decorative bar-charts, in the popups' stand-in-texture
-- language (dim white steps, the "now" bar green, a faint baseline).
local BAR_W, BAR_GAP2 = 8, 4
local function MakeChart(anchorSide, inset, heights, alphas)
local groupW = #heights * BAR_W + (#heights - 1) * BAR_GAP2
local base = card:CreateTexture(nil, "ARTWORK")
base:SetColorTexture(1, 1, 1, 0.12)
PP.Size(base, groupW, 1)
if anchorSide == "LEFT" then
PP.Point(base, "LEFT", card, "LEFT", inset, -12)
else
PP.Point(base, "RIGHT", card, "RIGHT", -inset, -12)
end
if PP.DisablePixelSnap then PP.DisablePixelSnap(base) end
for i = 1, #heights do
local bar = card:CreateTexture(nil, "ARTWORK")
local a = alphas[i]
if a == "green" then
bar:SetColorTexture(EG.r, EG.g, EG.b, 0.9)
else
bar:SetColorTexture(1, 1, 1, a)
end
PP.Size(bar, BAR_W, heights[i])
PP.Point(bar, "BOTTOMLEFT", base, "TOPLEFT", (i - 1) * (BAR_W + BAR_GAP2), 1)
if PP.DisablePixelSnap then PP.DisablePixelSnap(bar) end
end
end
-- Left: cost falling to a low green bar. Right: fps rising to a tall
-- green bar.
MakeChart("LEFT", 36, { 34, 26, 19, 13, 8 }, { 0.28, 0.23, 0.18, 0.14, "green" })
MakeChart("RIGHT", 36, { 8, 13, 19, 26, 34 }, { 0.14, 0.18, 0.23, 0.28, "green" })
local eyebrow = MakeFont(card, 11, nil, EG.r, EG.g, EG.b, 0.9)
PP.Point(eyebrow, "TOP", card, "TOP", 0, -18)
eyebrow:SetJustifyH("CENTER"); eyebrow:SetWordWrap(false)
eyebrow:SetText(EllesmereUI.L(entry.eyebrow or "SPECIAL UPDATE"))
-- Banner titles stand alone: no "Module:" prefix, the card IS the
-- event -- and it renders LARGE, like the popups' 26px headline.
local titleFs = MakeFont(card, 24, nil, 1, 1, 1, 1)
PP.Point(titleFs, "TOP", eyebrow, "BOTTOM", 0, -8)
titleFs:SetJustifyH("CENTER"); titleFs:SetWordWrap(false)
titleFs:SetText(EllesmereUI.L(entry.title) or "")
local descFs = MakeFont(card, 13, nil, 1, 1, 1, 0.5)
PP.Point(descFs, "TOP", titleFs, "BOTTOM", 0, -10)
PP.Point(descFs, "LEFT", card, "LEFT", 110, 0)
PP.Point(descFs, "RIGHT", card, "RIGHT", -110, 0)
descFs:SetJustifyH("CENTER"); descFs:SetJustifyV("TOP"); descFs:SetWordWrap(true)
descFs:SetText(EllesmereUI.L(entry.desc) or "")
local dh = math.ceil(descFs:GetStringHeight() or 14)
local bh = 18 + 11 + 8 + 24 + 10 + dh + 28
PP.Size(card, w, bh)
if entry.nav and entry.nav.module then
card:SetScript("OnEnter", function()
brd:SetColor(1, 1, 1, 0.30)
descFs:SetAlpha(0.65)
end)
card:SetScript("OnLeave", function()
brd:SetColor(1, 1, 1, 0.15)
descFs:SetAlpha(0.5)
end)
card:SetScript("OnClick", function() GoTo(entry.nav) end)
else
card:EnableMouse(false)
end
return bh
end
-- Tier 2: a clickable small listing -- title + subtitle, no card chrome, a
-- faint row highlight on hover.
local function MakeListing(cy, w, entry)
local ROW_H = 48
local row = CreateFrame("Button", nil, parent)
PP.Size(row, w, ROW_H)
PP.Point(row, "TOPLEFT", parent, "TOPLEFT", PAD, cy)
local hov = row:CreateTexture(nil, "BACKGROUND")
hov:SetAllPoints()
hov:SetColorTexture(1, 1, 1, 0.07)
hov:SetAlpha(0)
local titleFs = MakeFont(row, 13, nil, 1, 1, 1, 0.9)
PP.Point(titleFs, "TOPLEFT", row, "TOPLEFT", 6, -5)
titleFs:SetJustifyH("LEFT"); titleFs:SetWordWrap(false)
titleFs:SetText(TitleOf(entry))
local subFs = MakeFont(row, 11, nil, 1, 1, 1, 0.4)
PP.Point(subFs, "TOPLEFT", titleFs, "BOTTOMLEFT", 0, -4)
PP.Point(subFs, "RIGHT", row, "RIGHT", -10, 0)
subFs:SetJustifyH("LEFT"); subFs:SetWordWrap(false)
subFs:SetText(EllesmereUI.L(entry.desc) or "")
-- Clickable only when the entry has a nav target (see MakeHeroCard); a
-- nav-less listing renders static with no hover or click.
if entry.nav and entry.nav.module then
row:SetScript("OnEnter", function()
hov:SetAlpha(1); titleFs:SetAlpha(1)
end)
row:SetScript("OnLeave", function()
hov:SetAlpha(0); titleFs:SetAlpha(0.9)
end)
row:SetScript("OnClick", function() GoTo(entry.nav) end)
else
row:EnableMouse(false)
end
return ROW_H
end
-- Tier 3: a plain bug-fix line (bullet + wrapping text, not clickable).
local function MakeFixLine(cy, text)
local dot = MakeFont(parent, 12, nil, EG.r, EG.g, EG.b, 0.55)
PP.Point(dot, "TOPLEFT", parent, "TOPLEFT", PAD + 2, cy - 1)
dot:SetText("\226\128\162") -- bullet glyph (ASCII-safe UTF-8 escape)
local fs = MakeFont(parent, 12, nil, 1, 1, 1, 0.5)
PP.Point(fs, "TOPLEFT", parent, "TOPLEFT", PAD + 18, cy)
PP.Point(fs, "RIGHT", parent, "RIGHT", -PAD, 0)
fs:SetJustifyH("LEFT"); fs:SetWordWrap(true)
fs:SetText(text or "")
local th = fs:GetStringHeight() or 14
return math.max(22, math.ceil(th) + 8)
end
local patches = EllesmereUI._WHATSNEW_PATCHES
if not patches or #patches == 0 then
local none = MakeFont(parent, 13, nil, 1, 1, 1, 0.5)
PP.Point(none, "TOPLEFT", parent, "TOPLEFT", PAD, y - 20)
none:SetText (EllesmereUI.L("No patch notes yet."))
return math.abs(y) + 60
end
-- Intro hint: centered, with 20px of breathing room above and below.
y = y - 20
local hint = MakeFont(parent, 14, nil, 1, 1, 1, 0.5)
PP.Point(hint, "TOP", parent, "TOP", 0, y)
hint:SetJustifyH("CENTER")
hint:SetText (EllesmereUI.L("Click any new feature to go directly to the setting"))
-- Top-left: "New Patch Reminder Dot" opt-out for the pulsing sidebar dot
-- that appears when the account's version increases (see the Patch Notes
-- button in EllesmereUI.lua). Small free-form checkbox on the hint line.
do
local BOX = 14
local row = CreateFrame("Button", nil, parent)
row:SetFrameLevel(parent:GetFrameLevel() + 2)
local box = CreateFrame("Frame", nil, row)
PP.Size(box, BOX, BOX)
PP.Point(box, "LEFT", row, "LEFT", 0, 0)
local boxBg = box:CreateTexture(nil, "BACKGROUND")
boxBg:SetAllPoints()
boxBg:SetColorTexture(0.075, 0.113, 0.141, 1)
local boxBrd = MakeBorder(box, 1, 1, 1, 0.25, PP)
local check = box:CreateTexture(nil, "ARTWORK")
PP.Point(check, "TOPLEFT", box, "TOPLEFT", 3, -3)
PP.Point(check, "BOTTOMRIGHT", box, "BOTTOMRIGHT", -3, 3)
check:SetColorTexture(EG.r, EG.g, EG.b, 1)
local lbl = MakeFont(row, 12, nil, 1, 1, 1, 0.5)
PP.Point(lbl, "LEFT", box, "RIGHT", 7, 0)
lbl:SetText(EllesmereUI.L("New Patch Reminder Dot"))
row:SetSize(BOX + 10 + (lbl:GetStringWidth() or 130), 20)
PP.Point(row, "TOPRIGHT", parent, "TOPRIGHT", -PAD, y + 2)
local function Paint()
local on = not (EllesmereUIDB and EllesmereUIDB.patchDotDisabled)
check:SetShown(on)
if on then
boxBrd:SetColor(EG.r, EG.g, EG.b, 0.85)
else
boxBrd:SetColor(1, 1, 1, 0.25)
end
end
Paint()
row:SetScript("OnClick", function()
if not EllesmereUIDB then EllesmereUIDB = {} end
EllesmereUIDB.patchDotDisabled = (not EllesmereUIDB.patchDotDisabled) and true or nil
Paint()
if EllesmereUI._UpdatePatchDot then EllesmereUI._UpdatePatchDot() end
end)
row:SetScript("OnEnter", function(self)
lbl:SetAlpha(0.85)
if EllesmereUI.ShowWidgetTooltip then
EllesmereUI.ShowWidgetTooltip(self, EllesmereUI.L("Show a pulsing dot on the Patch Notes button whenever EllesmereUI updates to a new version."))
end
end)
row:SetScript("OnLeave", function()
lbl:SetAlpha(0.5)
if EllesmereUI.HideWidgetTooltip then EllesmereUI.HideWidgetTooltip() end
end)
end
y = y - math.ceil(hint:GetStringHeight() or 14) - 20
-- Cap the page to the newest patches (max 10). Older entries may remain in
-- the data table but are not shown; trim them on ship to keep the file tidy.
local MAX_PATCHES = 10
local shown = math.min(#patches, MAX_PATCHES)
for pi = 1, shown do
local patch = patches[pi]
-- A "mini" patch is a bugfix-only release: it carries just a `fixes`
-- tier and renders in a lighter, more compact style so a small patch
-- does not take up as much room as a full feature release.
local isMini = patch.mini
-- Version header. Full patches: large 20px title + neutral divider.
-- Mini patches: compact 15px title with a green "MINI PATCH" tag and a
-- tighter divider.
if isMini then
local ver = MakeFont(parent, 15, nil, 1, 1, 1, 0.9)
PP.Point(ver, "TOPLEFT", parent, "TOPLEFT", PAD, y)
ver:SetText("EllesmereUI " .. (patch.version or ""))
local tag = MakeFont(parent, 10, nil, EG.r, EG.g, EG.b, 0.85)
PP.Point(tag, "LEFT", ver, "RIGHT", 10, -1)
tag:SetText("MINI PATCH")
local uline = parent:CreateTexture(nil, "ARTWORK")
uline:SetColorTexture(1, 1, 1, 0.10)
PP.Size(uline, totalW, 1)
PP.Point(uline, "TOPLEFT", parent, "TOPLEFT", PAD, y - 24)
if PP.DisablePixelSnap then PP.DisablePixelSnap(uline) end
y = y - 34
else
local ver = MakeFont(parent, 20, nil, 1, 1, 1, 0.95)
PP.Point(ver, "TOPLEFT", parent, "TOPLEFT", PAD, y)
ver:SetText("EllesmereUI " .. (patch.version or ""))
local uline = parent:CreateTexture(nil, "ARTWORK")
uline:SetColorTexture(1, 1, 1, 0.12)
PP.Size(uline, totalW, 1)
PP.Point(uline, "TOPLEFT", parent, "TOPLEFT", PAD, y - 32)
if PP.DisablePixelSnap then PP.DisablePixelSnap(uline) end
y = y - 48
end
-- Tier 1: hero cards, two per row. Heroes render in AUTHORED order (the
-- order they appear in the patch's `heroes` table) -- NOT module-sorted
-- like features/fixes -- so each patch can headline whatever matters most
-- first. Reorder the entries in _WHATSNEW_PATCHES to reorder the cards.
local heroes = patch.heroes or {}
if #heroes > 0 then
local cardW = math.floor((totalW - CARD_GAP) / 2)
local CARD_H = 96
-- Sequential layout with column state: normal heroes flow two per
-- row in authored order; a `banner` hero takes a full row of its
-- own, breaking and then resuming the two-column flow. A patch
-- with only two-column heroes consumes exactly the vertical space
-- the old rows-times-height math produced.
local col = 0
for _, hero in ipairs(heroes) do
if hero.banner then
if col == 1 then y = y - CARD_H - CARD_GAP; col = 0 end
local bh = MakeBannerCard(PAD, y, totalW, hero)
y = y - bh - CARD_GAP
else
local cx = PAD + col * (cardW + CARD_GAP)
MakeHeroCard(cx, y, cardW, CARD_H, hero)
col = col + 1
if col == 2 then y = y - CARD_H - CARD_GAP; col = 0 end
end
end
if col == 1 then y = y - CARD_H - CARD_GAP end
y = y + CARD_GAP - 18
end
-- Tier 2: small listings.
local feats = SortByModule(patch.features or {})
if #feats > 0 then
local _, sh = W:SectionHeader(parent, "ADDITIONAL FEATURES", y); y = y - sh
y = y - 5 -- extra spacing below the divider
for _, f in ipairs(feats) do
local rh = MakeListing(y, totalW, f); y = y - rh
end
y = y - 6
end
-- Tier 3: bug-fix lines. Full patches label them under a "BUG FIXES"
-- header; a mini patch is entirely fixes, so the lines render directly
-- beneath the compact header with no redundant section label.
local fixes = SortByModule(patch.fixes or {})
if #fixes > 0 then
if not isMini then
local _, sh = W:SectionHeader(parent, "BUG FIXES", y); y = y - sh
y = y - 10 -- extra spacing below the divider
end
for _, fx in ipairs(fixes) do
local fh = MakeFixLine(y, ((fx.module and EllesmereUI.L(fx.module) .. ": ") or "") .. (EllesmereUI.L(fx.text) or "")); y = y - fh
end
end
if pi < shown then
local _, gap = W:Spacer(parent, y, 24); y = y - gap
end
end
return math.abs(y) + 20
end
-------------------------------------------------------------------------------
-- Patch-notes content for the What's New page (newest patch first). Each hero
-- and listing entry's `nav` deep-links to the setting it changed via
-- EllesmereUI:NavigateToElementSettings(module, page, section, preSelect, highlight).
-------------------------------------------------------------------------------
EllesmereUI._WHATSNEW_PATCHES = {
{
version = "8.7",
mini = true,
fixes = {
{ module = "Cooldown Manager", text = "Hide Active State now greys transformed charge spells (e.g. Judgment under Avenging Wrath) at zero charges in real combat, reading the transformed spell's own cooldown." },
{ module = "Mythic+ Timer", text = "Fixed the floating timer appearing in the wrong place at the start of each key when the timer is scaled, drifting toward the center of the screen until Unlock Mode was opened." },
{ module = "Nameplates", text = "Pandemic and dispel glows no longer cover the duration and stack text on nameplate auras." },
{ module = "Quality of Life", text = "Hide Item Transformations no longer hides the Atomically Recalibrator and Atomically Regoblinator toy effects by default." },
{ module = "Raid Frames", text = "Frames now show OFFLINE instead of DEAD when a player is both disconnected and dead." },
{ module = "Raid Frames", text = "Fixed action blocked errors when buff indicators built their icons for the first time during combat, such as on delve trash pulls." },
{ module = "Unit Frames", text = "Fixed buffs and debuffs keeping the previous target's icons when switching targets." },
},
},
{
version = "8.6.8",
heroes = {
{
-- Full-width banner card (banner = true, see MakeBannerCard):
-- announcement-style chrome dedicated to the suite-wide
-- performance overhaul. Static on purpose -- the speedup is
-- automatic, there is no setting to open.
banner = true,
eyebrow = "SUITE-WIDE OPTIMIZATION",
title = "The Performance Patch",
desc = "The entire suite has been rebuilt for speed: CPU Usage has been cut by more than 70% while idle, and over 50% during M+/Raid combat. Same look, same features, at a fraction of the cost.",
},
},
fixes = {
{ module = "Action Bars", text = "The micro menu and bag bar reappear on their own after wild pet battles." },
{ module = "Action Bars", text = "Clicking an empty stretch of an action bar no longer flips the main bar to another page." },
{ module = "Action Bars", text = "Cooldown swipes repaint when a proc modifies them, and an active GCD no longer greys out charge spells." },
{ module = "Blizz UI Enhanced", text = "Context menus keep their skin after the first menu of the session." },
{ module = "Blizz UI Enhanced", text = "Submenu flyouts (Loot Specialization, Raid Markers and friends) are skinned again." },
{ module = "Blizz UI Enhanced", text = "Fixed repeating errors when hovering enemy nameplate auras inside instances." },
{ module = "Cooldown Manager", text = "Replaced tracked buffs (e.g. Wither for Hellcaller) show the castable spell's icon instead of the aura's." },
{ module = "Cooldown Manager", text = "Transforming cooldowns like Holy Armaments stay on the bar you assigned them to." },
{ module = "Cooldown Manager", text = "Custom Active States (e.g. trinket glows) work after login without opening the settings first." },
{ module = "Cooldown Manager", text = "Pandemic Glow's None option is now selectable and actually hides Blizzard's pandemic glow." },
{ module = "Cooldown Manager", text = "Suppress GCD now covers racials and user-added spells." },
{ module = "Cooldown Manager", text = "Transformed charge spells (e.g. Judgment under Avenging Wrath) grey out at zero charges with Hide Active State." },
{ module = "Cooldown Manager", text = "Bar Glows light up when the aura is gained, not only after one is removed." },
{ module = "General", text = "Typing a value into a slider's number box now updates dependent controls the same as dragging it." },
{ module = "General", text = "Many missing translations now translate on non-English clients; Traditional Chinese and Korean translations expanded (community)." },
{ module = "Quality of Life", text = "The Upgrade Calculator works on non-English clients: crest totals, missing upgrades and the queue no longer read zero." },
{ module = "Quality of Life", text = "The Raid Tools window keeps its saved position correctly when scaled." },
{ module = "Unit Frames", text = "More absorb bar position options." },
{ module = "Unit Frames", text = "With Only Dispellable by You, dwarves now get the dispel overlay for bleeds (Stoneform clears them)." },
},
},
{
version = "8.6.6",
heroes = {
{
-- Umbrella card: absorbs the pull-timer boss-mod sync, the
-- combat-safe markers, and the auto-show/collapse/keybind work
-- rather than spawning sibling feature cards beside itself.
module = "Quality of Life",
title = "Raid Tools Panel",
desc = "A new movable panel with ready check, role check, convert or disband, one click pull timers, and target/world markers that work in combat. Show it as one or two windows at any scale, collapse it to an icon, and open it from a keybind.",
nav = { module = "EllesmereUIQoL", page = "Raid Tools", section = "GENERAL", highlight = "Show Raid Tools" },
},
},
features = {
{
module = "Chat",
title = "Input Field Size and Font",
desc = "Set the chat box height, font and size",
nav = { module = "EllesmereUIChat", page = "Chat", section = "INPUT FIELD", highlight = "Edit Box Height" },
},
{
module = "Chat",
title = "Sidebar Width",
desc = "Size the sidebar from 30 to 100 pixels",
nav = { module = "EllesmereUIChat", page = "Sidebar", section = "SIDEBAR", highlight = "Sidebar Width" },
},
{
module = "General",
title = "Name Font",
desc = "Own font for floating names; needs a logout",
nav = { module = "_EUIGlobal", page = "Fonts & Colors", section = "GLOBAL FONT", highlight = "Name Font" },
},
{
-- Title carries no module word: TitleOf prefixes "Party Mode: ",
-- and the option's own label ends in "on Party Mode", which would
-- read twice. The row is a direct W:Dropdown call, which still
-- tags _labelText from its text argument, so the label matches.
module = "Party Mode",
title = "Activation Sound",
desc = "Play a chosen sound when it turns on",
nav = { module = "EllesmereUIPartyMode", page = "Party Mode", section = "PARTY MODE", highlight = "Play Sound on Party Mode" },
},
{
-- Lives as the "Anchor to Debuffs" VALUE inside the Buff Display
-- dropdown, so the highlight targets that row (its DualRow label
-- starts "Buff Display", and it is the first row under the
-- header, so nothing can intercept the match). preSelect is
-- REQUIRED, not optional: the BUFFS AND DEBUFFS section only
-- builds for player/target/focus, so anyone whose last viewed
-- unit was pet or boss would land on a page without the section.
module = "Unit Frames",
title = "Anchor to Debuffs",
desc = "Buffs show as the first rows of your debuff stack",
nav = { module = "EllesmereUIUnitFrames", page = "Main Frames", section = "BUFFS AND DEBUFFS", highlight = "Buff Display",
preSelect = function()
if EllesmereUI._setUnitFrameUnit then EllesmereUI._setUnitFrameUnit("player") end
end },
},
},
fixes = {
{ module = "Action Bars", text = "Reduced CPU usage while Assisted Combat (One Button Assist) is active: a new suggested spell now updates just that button, instead of running a full pass over every button on every bar each time the rotation moves on." },
{ module = "Bags", text = "TradeSkillMaster's Banking UI now detects when you switch between your character bank and the warbank from the sidebar, instead of staying on the wrong bank type." },
{ module = "Blizz UI Enhanced", text = "Fixed right-clicking a unit and choosing Whisper sometimes opening the chat box with a broken, unreadable recipient name and spamming repeated errors." },
{ module = "Chat", text = "Fixed undocked windows creeping toward the bottom-left corner of the screen on every login or reload." },
{ module = "Chat", text = "Turning on Input on Top now grows the chat panel upward to fit the input box, instead of placing it inside the panel and shrinking the area your chat text has to work with." },
{ module = "Chat", text = "Fixed windows you create and dock permanently sometimes being sized like a temporary whisper tab, and tabs losing their custom colors after moving or resizing the frame in Blizzard's Edit Mode." },
{ module = "Chat", text = "The Tab Texture option, renamed from Tab Background Texture, now works whether or not Sync Border with Chat Panel is on, instead of staying greyed out." },
{ module = "Chat", text = "A Mouseover sidebar now only takes up panel space while it is actually showing, so with Tabs Inside Chat Panel or Align Tabs to Full Panel the panel and tab alignment resize as you move the mouse on and off it, where before that space was reserved at all times." },
{ module = "Chat", text = "Tab borders, dividers and the active underline now line up again immediately after changing Tab Spacing, instead of staying at their old positions until something else redrew the tabs." },
{ module = "Chat", text = "Tab dividers now sit in the gap between tabs rather than on the tab's own edge, and temporary whisper tabs no longer draw one." },
{ module = "Chat", text = "Tab Background Color and Tab Background Color Active are now color swatches, with their opacity moved into the cog beside each row." },
{ module = "Chat", text = "Tab fonts, the active tab font and the active tab background can now be set to Accent Color or Class Color." },
{ module = "Chat", text = "The Active Underline's third color preset is now Class Color instead of Border Color, so an underline that was set to Border Color now shows your Custom Color instead." },
{ module = "Chat", text = "Fixed another source of repeating error messages when receiving a whisper, or when a Battle.net whisper toast appeared, while the sender's name was hidden by the game such as during a Mythic+ key." },
{ module = "Cooldown Manager", text = "Fixed an inactive tracked buff's placeholder icon showing the pre-talent spell's art, such as a Hellcaller Destruction Warlock's Immolate slot that actually casts Wither. The icon's tooltip follows the same correction, and the per-icon preview in the options page shows the corrected art." },
{ module = "Cooldown Manager", text = "Turning off a bar's Pandemic Glow now clears a glow already lit on an icon straight away, instead of leaving it stuck on screen until you turned the setting back on, let the buff expire, then turned it off again." },
{ module = "Cooldown Manager", text = "Custom and preset buff icons now use the Cooldown Swipe Color you picked for them, instead of falling back to the cooldown style swipe handling meant for ability cooldowns." },
{ module = "Cooldown Manager", text = "Setting up or editing a Generic CDs/Buffs sync now tells you in chat how many specs were included and that icon order is not synced, and says when confirming with only one spec ticked cleared an existing sync instead of creating one." },
{ module = "Cooldown Manager", text = "The Health Potion preset now shows and tracks the newest health potion first, falling back to the Silvermoon potions when you have none of the new ones." },
{ module = "General", text = "Tooltips inside the EllesmereUI options panel and its popups now follow your EUI Options Panel Scale setting, instead of always showing at the default size." },
{ module = "General", text = "The Mushroom hearthstone toy is now included, so it can be picked in the Data Bars Travel block and shows in the Chat and Minimap portal flyouts." },
{ module = "General", text = "Account Wide Interface Settings no longer triggers an Incompatible Addon Detected warning on login for Quest Tracker." },
{ module = "General", text = "Added and corrected translations across German, Spanish, French, Italian, Portuguese, Russian, Korean, Simplified Chinese and Traditional Chinese." },
{ module = "Nameplates", text = "Nameplate text slots can now show a unit's level, on its own or alongside the name." },
{ module = "PTR Nameplates", text = "Fixed the Caster nameplate color on PTR, it now applies to any unit with a mana bar." },
{ module = "PTR Unit Frames", text = "Focus, focus target and target of target frames show class colors for allied players again, instead of falling back to the plain green friendly color. Those three frames use Blizzard's standard class colors, so a custom class color addon cannot recolor them." },
{ module = "Quality of Life", text = "Auto Repair now uses whatever the guild bank can contribute and charges you only the remainder, instead of charging your own gold for the whole bill any time the guild bank could not cover it in full. It also no longer refuses to repair when your own gold is short but your gold plus guild funds would cover it." },
{ module = "Resource Bars", text = "Fixed vertical Health Bar, Power Bar and Class Resource bars showing a sideways box and swapped size numbers in Unlock Mode, so dragging a handle resized the wrong axis. On all four bars, including the GCD Bar, the Height and Width Match options now grey out the slider they actually control. Horizontal bars were not affected." },
{ module = "Resource Bars", text = "Fixed the Protection Warrior Ignore Pain bar's stack count text going blank and staying blank until Blizzard's tracked buff viewer happened to reuse the same icon slot." },
{ module = "Spec Overrides", text = "Fixed a spec or conditional override captured on a custom raid size (10, 15, 25 or 30 man) silently never taking effect, and continuing to fail on later edits to that tier. New overrides now save correctly, and profiles carrying the earlier ones repair themselves with nothing for you to do." },
{ module = "Spec Overrides", text = "Fixed old profile corruption that could cause switching to a different profile while a spec-specific Unlock Mode layout was active to leave the old layout's frame positions on screen and then save them over your regular layout. Positions now resync immediately instead." },
{ module = "Unit Frames", text = "Fixed the Absorb Short health text getting stuck on a leftover 0 on target, focus, boss and pet frames after the unit changed or died. The player frame was never affected." },
},
},
{
version = "8.6.5",
-- No hero tier: 8.6.5 is a maintenance release whose largest additions
-- are single toggles. `_BuildWhatsNewPage` skips the hero block when
-- `heroes` is absent, and this is NOT a mini patch (a features tier is
-- present), so the version title still renders full size.
features = {
{
-- Page-only nav on purpose. Both new Cooldown Saturation rows
-- are MakeSubnavRow entries inside the per-icon spell picker
-- popup, which never gets a _labelText or _isSectionHeader, so
-- any section/highlight would fall through the match loop and
-- no-op. The popup opens off the live preview in the page's
-- fixed content header, so this lands one click away.
module = "Cooldown Manager",
title = "Cooldown Saturation",
desc = "Keep icons colored while on cooldown",
nav = { module = "EllesmereUICooldownManager", page = "CDM Bars" },
},
{
-- PTR entry: the socialui window pack gates on
-- Blizzard_SocialUI, which does not exist on 12.0, so this is
-- 12.1-only. Umbrella for the whole Social window effort: the
-- window pack chrome, the 12.1 friends tile styling, and the
-- legacy Friends skin standing down when the Social UI is live.
-- Page-only rather than targeting the Friends List card: that
-- card's _sectionName is title .. " " .. desc, a 169-char join
-- that any wording tweak would silently break.
module = "PTR Friends List",
title = "Social Window Styling",
desc = "EllesmereUI styling for the 12.1 friends window",
nav = { module = "EllesmereUIBlizzardSkin", page = "Blizzard Window Skins" },
},
},
fixes = {
{ module = "Action Bars", text = "Fixed charge abilities flickering between colored and greyed out while recharging, and sometimes showing two overlapping cooldown numbers." },
{ module = "Action Bars", text = "Fixed the recharge countdown on charge abilities showing in Blizzard's default font instead of your configured cooldown font." },
{ module = "Action Bars", text = "Fixed a bar set to Never not getting a move handle in unlock mode while the Toggle Action Bar Visibility keybind had it on screen, and a bar set to Always that the keybind had toggled off still getting one." },
{ module = "Action Bars", text = "Fixed combat error spam when the micro menu or bag bar changed visibility during Mythic+ keys and other combat." },
{ module = "Blizz UI Enhanced", text = "Fixed the Crafting Orders type tabs (Public, NPC, Guild, Personal) keeping their highlight stuck on Public no matter which tab was selected." },
{ module = "Blizz UI Enhanced", text = "Added an optional Mana row to the character sheet Attributes stats, off by default in the Attributes cog and hidden for classes with no mana pool." },
{ module = "Conditional Overrides", text = "Fixed a pending condition switch such as Dark Mode getting stuck while the options panel was open, which silently blocked later setting changes from saving until a reload." },
{ module = "Cooldown Manager", text = "Fixed two buff viewer slots that collide, such as Diabolic Ritual and Demonic Art, sharing one reserved slot, which could resize a buff bar mid fight as the two icons came and went." },
{ module = "Cooldown Manager", text = "Added an Only In Combat option to Tracking Bars, hiding a bar completely while out of combat no matter what it is tracking." },
{ module = "Cooldown Manager", text = "Added a Charges/Stacks Only option to Cooldown and Utility bars, stripping icons down to just their charge or stack count." },
{ module = "Data Bars", text = "Fixed micro menu block buttons, and a hidden Blizzard micro menu, staying gone after a pet battle ended." },
{ module = "General", text = "Fixed a permanent frame rate collapse caused by the anchor settle pass re-triggering itself in a loop, most likely at low UI scale where a re-apply is not pixel stable." },
{ module = "General", text = "Added and corrected translations across German, French, Russian, Korean, Simplified Chinese and Traditional Chinese, including hyphenation fixes across a batch of German strings." },
{ module = "Quality of Life", text = "Fixed Auto Sell Junk sometimes leaving grey items unsold. The sweep now retries until everything sells and tells you in chat if anything could not be sold." },
{ module = "Quality of Life", text = "Movement Alert now only warns for charge based movement spells once every charge is spent, instead of treating a recharging spell as unavailable while a charge was still banked." },
{ module = "Quality of Life", text = "Raised the crosshair H Length and V Length slider maximums from 100 to 500." },
{ module = "Raid Frames", text = "Fixed Hover Cast bindings never firing over nameplates, and the Friendly and Enemy reaction toggles being ignored for macro bindings." },
{ module = "Resource Bars", text = "Added an Always Show option to the cast bar, keeping it on screen and empty between casts." },
{ module = "Resource Bars", text = "Fixed the Survival Hunter Tip of the Spear tracker landing on the wrong stack count after Takedown when Twin Fangs is talented." },
{ module = "Spec Overrides", text = "Fixed a sustained frame rate drop lasting up to two minutes after leaving combat when a Dragon Riding HUD setting had been captured into an override." },
},
},
{
version = "8.6.4",
-- No hero tier this patch. `_BuildWhatsNewPage` skips the hero block
-- entirely when `heroes` is absent, and this is NOT a mini patch (mini
-- is fixes-only; a features tier is present), so the version title
-- still renders full size and drops straight into ADDITIONAL FEATURES.
features = {
{
module = "Action Bars",
title = "Icon Order",
desc = "Reverse a bar, or start button 1 in any corner",
nav = { module = "EllesmereUIActionBars", page = "Bar Display", section = "LAYOUT", highlight = "Icon Order" },
},
{
-- Highlights the on-page "Text Size" slider in the first of the
-- three data-bar sections (Experience, Reputation, House Favor);
-- each section carries its own copy of the row. Note the rows
-- below a section's visibility dropdown are hidden entirely
-- while that bar's visibility is Never, so the pulse no-ops on
-- a profile with the Experience bar switched off.
module = "Action Bars",
title = "Bar Text Size",
desc = "Resize Experience, Reputation, and Favor text",
nav = { module = "EllesmereUIActionBars", page = "Menu, Bags & XP Bars", section = "EXPERIENCE BAR", highlight = "Text Size" },
},
{
-- Page-only nav: the module's own NavigateToElementSettings
-- pre-hook only force-expands the window cards when a section or
-- highlight is passed, so this lands on the card list collapsed,
-- which is the right landing for an entry covering three windows.
module = "Blizz UI Enhanced",
title = "Loot and Item Upgrade Skins",
desc = "Loot window, Item Upgrade, and toast popups",
nav = { module = "EllesmereUIBlizzardSkin", page = "Blizzard Window Skins" },
},
{
-- Highlight targets the neighbouring Duration Size row: the new
-- Position dropdown is cog-only, and cog rows use label= so they
-- never get a _labelText to match against.
module = "Cooldown Manager",
title = "Duration Text Position",
desc = "Place the countdown outside the icon",
nav = { module = "EllesmereUICooldownManager", page = "CDM Bars", section = "ICON DISPLAY", highlight = "Duration Size" },
},
{
-- Page-only nav: block rows only exist once the user adds the
-- block from the preview strip, so any section or highlight here
-- would be state-dependent and could silently miss.
module = "Data Bars",
title = "Location and Coordinates Blocks",
desc = "Show your zone and X/Y coordinates",
nav = { module = "EllesmereUIDataBars", page = "DataBars" },
},
{
-- The Bar Strata dropdown is cog-only, so the highlight targets
-- the on-page row that owns the cog: the Visibility dropdown,
-- whose left slot is labelled "Visibility" by
-- EllesmereUI.BuildVisibilityModeRow. It is the first row under
-- BAR SETTINGS, so it cannot be intercepted by an earlier match.
module = "Data Bars",
title = "Bar Strata",
desc = "Raise or lower a bar against other frames",
nav = { module = "EllesmereUIDataBars", page = "DataBars", section = "BAR SETTINGS", highlight = "Visibility" },
},
{
-- The Show Spark toggle is cog-only (cog rows use label= and get
-- no _labelText), so the highlight targets the on-page multiSwatch
-- row that owns the Cast Color cog.
module = "Nameplates",
title = "Cast Bar Spark",
desc = "Hide the bright spark on the cast bar fill",
nav = { module = "EllesmereUINameplates", page = "Display", section = "CAST COLORS AND EFFECTS", highlight = "Cast Color" },
},
{
-- Page-only nav: the grow picker lives in the Unlock Mode
-- right-click menu, not on a settings row, so there is no valid
-- highlight to pass and inventing one would ship a dead pulse.
module = "Resource Bars",
title = "Totem Bar Grow Direction",
desc = "Grow left, right, centered, up or down",
nav = { module = "EllesmereUIResourceBars", page = "Totem Bar" },
},
{
module = "Unit Frames",
title = "Separate Tooltip Controls",
desc = "Turn aura tooltips off on their own",
nav = { module = "EllesmereUIUnitFrames", page = "Main Frames", section = "DISPLAY", highlight = "Show Tooltip For" },
},
},
fixes = {
{ module = "Action Bars", text = "Fixed a CPU usage issue caused by the One Button Assist button. Its rotation ring is now static, with a new toggle to hide it and a slider in its cog for how far it extends past the button." },
{ module = "Action Bars", text = "Charge cooldowns no longer freeze. A spell's recharge swipe, charge count, or edge glow could silently stop updating for the rest of the session after one unlucky read, such as right after login or a talent swap. Charge spells spent off the global cooldown now draw their recharge swipe at all." },
{ module = "Action Bars", text = "The icon order control for each bar is back, so a bar left stuck in reversed order since 8.5.3 can be changed again." },
{ module = "Blizz UI Enhanced", text = "The new Loot, Item Upgrade, and loot toast skins are on by default, each with its own toggle on the Window Skins page. Loot toasts can also show a quality-color strip down the edge in place of the icon's quality ring." },
{ module = "Blizz UI Enhanced", text = "The Currency Options popup on the character panel now follows that panel's own window style instead of showing as a flat grey box, and its checkboxes keep the standard checkmark. The Currency tab also no longer loads unskinned on characters where Blizzard's currency window arrives late." },
{ module = "Blizz UI Enhanced", text = "Skinned Blizzard windows whose close button sits on the title bar no longer keep Blizzard's red X." },
{ module = "Cooldown Manager", text = "Active State Glow and per-item Active State rules now light up reliably. A glow could stay dark for the rest of the session when Blizzard's engine skipped a color update, and rules for on-use trinkets or gear could fail to match the equipped item depending on login order." },
{ module = "Cooldown Manager", text = "Show Item Count is now a three-way choice of Never, Always, or Out of Combat, so charge and stack numbers can hide themselves while you are in combat and come back afterwards." },
{ module = "General", text = "Fixed a crash during unit frame setup that left the player frame blank and the settings tab unable to open when a profile still held an older Absorb Bar style value. Importing such a profile now converts the value to the matching style instead of falling back to a default texture." },
{ module = "General", text = "The UI Scale slider now snaps to the exact pixel-perfect value for 1080p displays near 0.71, matching the snap already in place near 0.53 for 1440p." },
{ module = "General", text = "Added new Korean and French translations." },
{ module = "Minimap", text = "The square border no longer vanishes. Depending on what else was loading at login, or after a housing-related minimap change, a solid or textured square border could disappear and not come back after a reload." },
{ module = "Nameplates", text = "Friendly nameplate visibility is no longer forced back on at every login, and leaving a follower dungeon now hands back the setting you had instead of forcing plates on, so hiding friendly nameplates in Blizzard's own Nameplate settings finally sticks. Friendly plates are only forced visible on a fresh install or when you turn on Show EUI Friendly Player Nameplates or Make Friendly Nameplates Name Only, so if you relied on the old forcing to restore them after another addon cleared the setting, use one of those toggles instead." },
{ module = "PTR Raid Frames", text = "Turning Hide Tooltips back off in the Buff Manager or Debuff Display sections now restores aura tooltips right away instead of needing a reload." },
{ module = "Raid Frames", text = "Buff Manager and Debuff Display aura tooltips are no longer silenced by the unit tooltip mode, and now follow only their own section's Hide Tooltips toggle. If you were setting Show Raid Frames Tooltip to Never, or hiding it in combat, to suppress aura tooltips as well, turn on Hide Tooltips in the Buff Manager and Debuff Display sections to keep them hidden." },
{ module = "Raid Frames", text = "MiniCC cooldown icons can now anchor to raid frames, not just party frames." },
{ module = "Resource Bars", text = "Shift Elements If No Power now closes the gap when a bar is hidden by your current Druid form, such as the primary power bar while in Moonkin form." },
{ module = "Unit Frames", text = "Boss frames now have the same 4th Extra Text zone as other frames, with its own content, size, color, alignment and offsets, plus a Max Per Row slider in the Simple Display buff and debuff layout menus." },
},
},
{
version = "8.6.3",
mini = true,
fixes = {
{ module = "Cooldown Manager", text = "Reordering a buff that shares its spell with another tracked ability, such as Diabolic Ritual, now moves the live bar instead of only the options preview." },
{ module = "Cooldown Manager", text = "Blizzard's own tracked buff bars no longer reappear over Tracked Buff Bars in combat; the suppression now re-asserts itself whatever moved them, including Edit Mode layout passes and other addons." },
{ module = "General", text = "Custom fonts from a SharedMedia font addon now apply reliably. When that addon finished loading after EllesmereUI, text could stay on the default font for the rest of the session, most visibly on action bars." },
{ module = "General", text = "Added the missing French translations for the latency block's bandwidth labels, plus a large pass of new German translations." },
{ module = "Resource Bars", text = "Destruction Warlock soul shard fragments display and drain again. Partial shards were invisible in combat and did not deplete out of combat." },
{ module = "Unit Frames", text = "The External Defensives frame no longer breaks when Duration Format is set to anything other than Blizzard Default. Those custom formats now display correctly." },
},
},
{
version = "8.6.2",
heroes = {
{
-- Static on purpose: a suite-wide CPU pass has no single
-- setting to open, so this card renders non-clickable.
module = "General",
title = "Performance Upgrades",
desc = "A major optimization pass across many of the core addons of the suite: Resource Bars, Action Bars, Cooldown Manager, and Unit Frames.",
},
},
features = {
{
module = "General",
title = "Expressway Font Option",
desc = "Now selectable in non-Latin locales",
nav = { module = "_EUIGlobal", page = "Fonts & Colors", section = "GLOBAL FONT", highlight = "Global Font" },
},
{
-- Page-only nav: BuildFullExportPage is hand-built chrome with
-- no W:SectionHeader to anchor, and the scroll resets to the
-- top on tab switch, which is where its content sits.
module = "Profiles",
title = "Full Account Export & Import",
desc = "Share every account-wide setting as one string",
nav = { module = "_EUIProfiles", page = "Full Export" },
},
},
fixes = {
{ module = "Action Bars", text = "The pet bar's visibility conditions work again; in combat, out of combat, and the dragonriding modes were being ignored, or applied under the opposite state." },
{ module = "Conditional Overrides", text = "Deleting an active group no longer leaves its captured values stuck on your profile; your normal settings come back the moment it is removed, and any settings page you have open updates immediately." },
{ module = "Cooldown Manager", text = "Blizzard's own tracked buff bars no longer reappear over Tracked Buff Bars during combat or on zone-in, and no longer stay invisible while still blocking clicks after Tracked Buff Bars is disabled." },
{ module = "General", text = "Added the missing Traditional Chinese translations." },
{ module = "Nameplates", text = "Execute Pulse Glow is now spec-aware: it lights only for specs that actually have an execute, at that spec's own health threshold, and rises automatically with talents that widen the window. Most specs now trigger at 20% instead of a flat 30%, and specs with no execute no longer glow at all." },
{ module = "Profiles", text = "The Spec Overrides and Conditional Overrides tabs are now a single Overrides tab, with a toggle at the top to switch between the two lists." },
{ module = "Quality of Life", text = "Buff-based Movement Alerts such as Burning Rush no longer throw an error and stop detecting the buff once you are in combat." },
{ module = "Unit Frames", text = "An attached power bar no longer draws a stray border line where it meets the health bar." },
{ module = "Unit Frames", text = "Turning off EllesmereUI's own cast bar no longer leaves Blizzard's player and pet cast bars dead or invisible, including when you log in with it already off or hide the player frame entirely." },
},
},
{
version = "8.5.9",
mini = true,
features = {
{
module = "Data Bars",
title = "Home, World or Both Latency",
desc = "One block can now show both, with optional icons",
nav = { module = "EllesmereUIDataBars", page = "DataBars" },
},
{
module = "Unit Frames",
title = "Boss Frame Absorb Text",
desc = "Show shield and heal-absorb amounts as text",
-- No highlight: "Left Text" also matches the Left Text Settings
-- rows above it and the matcher stops at the first hit.
nav = { module = "EllesmereUIUnitFrames", page = "Boss Frames", section = "HEALTH BAR" },
},
},
fixes = {
{ module = "General", text = "Added and corrected German, Korean, and Traditional Chinese translations." },
{ module = "Nameplates", text = "Nameplates no longer eat clicks and camera drags meant for the world, or show aura tooltips over empty space." },
{ module = "Nameplates", text = "Cast targets and interrupter names now keep their class color in Mythic+ and raids." },
{ module = "PTR Nameplates & Frames", text = "Aura icons no longer start eating clicks again after a settings change." },
{ module = "PTR Resource Bars", text = "The Ebon Might bar no longer blocks clicks on nameplates behind it." },
{ module = "Unit Frames", text = "Blizzard's cast bar no longer appears when you use a standalone cast bar addon." },
},
},
{
version = "8.5.8",
heroes = {
{
module = "Preset Gallery",
title = "New Presets and Ultrawide Imports",
desc = "Five new community layouts join the gallery: Light of Nitex, Fires of Nitex, Delsi's Faded Veil, Lazar's Dawn, and Lazar's Eclipse. Additionally, several presets now include an ultrawide option!",
nav = { module = "_EUIProfiles", page = "Presets" },
},
{
module = "Nameplates",
title = "Execute Pulse Glow",
desc = "A new option that makes enemy nameplates pulse with a red glow the moment a target drops below 30% health, so a whole pack tells you at a glance which mobs are in execute range.",
nav = { module = "EllesmereUINameplates", page = "General", section = "EXTRAS", highlight = "Execute Pulse Glow" },
},
},
features = {
{
module = "Action Bars",
title = "Icon Background Color and Opacity",
desc = "Recolor or fade the slot behind each icon",
-- No highlight on purpose: an older "Show Blizzard Icon Background"
-- row sits above the new one in this section and the matcher stops
-- at the first substring hit, so it would pulse the wrong control.
nav = { module = "EllesmereUIActionBars", page = "Bar Display", section = "ICONS",
preSelect = function()
if EllesmereUI._setActionBarKey then EllesmereUI._setActionBarKey("MainBar") end
end },
},
{
module = "Conditional Overrides",
title = "Dark Mode Condition",
desc = "Trigger an override group when Dark Mode is on",
nav = { module = "_EUIProfiles", page = "Overrides" },
},
{
module = "Damage Meters",
title = "Border Follows Bar",
desc = "Border wraps only the filled portion",
nav = { module = "EllesmereUIDamageMeters", page = "Damage Meters", section = "BARS", highlight = "Border Style" },
},
{
module = "Damage Meters",
title = "Bar Text Offsets",
desc = "Nudge name and amount text into place",
nav = { module = "EllesmereUIDamageMeters", page = "Damage Meters", section = "BAR TEXT" },
},
{
-- Static on purpose: the Debuff Manager page only exists on 12.1,
-- and What's New renders every card on both clients, so a nav here
-- would drop live users on a blank page.
module = "PTR Raid Frames",
title = "Aura Tooltip Modes",
desc = "Hidden, shown, at cursor, or hidden in combat",
},
{
module = "PTR Unit & Raid Frames",
title = "Non-Player Debuffs Filter",
desc = "Show debuffs you and your pet did not apply",
nav = { module = "EllesmereUIUnitFrames", page = "Main Frames", section = "BUFFS AND DEBUFFS", highlight = "Debuff Filter",
preSelect = function()
if EllesmereUI._setUnitFrameUnit then EllesmereUI._setUnitFrameUnit("player") end
end },
},
{
module = "Quest Tracker",
title = "All Objectives Header",
desc = "Bring back the master tracker header",
nav = { module = "EllesmereUIQuestTracker", page = "Quest Tracker", section = "DISPLAY", highlight = "Hide All Objectives" },
},
{
module = "Quest Tracker",
title = "Header Color and Font Size",
desc = "Color the header, divider line, and text size",
nav = { module = "EllesmereUIQuestTracker", page = "Quest Tracker", section = "COLORS", highlight = "Header Color" },
},
},
fixes = {
{ module = "Bags", text = "Level-scaling items such as leveling drops no longer show an incorrect red tint suggesting you cannot use them, in both bags and the bank." },
{ module = "Blizzard Skin", text = "Fixed the minimum quality icon on crafting orders vanishing again after the window re-skinned itself on a later show." },
{ module = "Blizzard Skin", text = "The EllesmereUI and Unlock Mode buttons in the Escape menu now pick up Button Background color and border changes immediately instead of staying on stale colors until reload." },
{ module = "Blizzard Skin", text = "The List My Guild in Guild Finder dialog is now fully skinned instead of see-through, and docks beside the Guild and Communities window instead of appearing at the top of the screen." },
{ module = "Conditional Overrides", text = "The group picker now blocks selecting a condition whose requirement is not met, with a tooltip explaining why, and hides the Unlock button for conditions that have no custom layout to unlock. Changing a setting while editing a group also no longer silently fails to be captured into it." },
{ module = "Cooldown Manager", text = "The per-spell CD Ready sound now plays the moment a spell actually comes off cooldown instead of waiting for your next cast, and it no longer misfires the instant you begin a cast-time spell." },
{ module = "Cooldown Manager", text = "Hidden (CD Ready) and Hidden CD Ready (Shift Icons) now keep a charge-based spell visible and tracking its recharge until it reaches max charges, instead of vanishing the moment one charge came back; the same correction applies to charge-based trinkets, potions, and custom tracked items. A new Stay Hidden While Charges Remain toggle restores the old behavior per spell." },
{ module = "Cooldown Manager", text = "Per-spell settings menus and the Custom Tracking, Potion, and Apply-to pickers now widen to fit their longest entry, so long custom spell names, item names, and translated labels no longer get cut off." },
{ module = "Data Bars", text = "The spec block's popup now lists all four click actions, adding Ctrl+Left Click to change loadout and Shift+Left Click to open talents." },
{ module = "General", text = "Fixed grayed-out options across Cooldown Manager, Nameplates, Raid Frames, Resource Bars, and Quality of Life showing a duplicated or backwards requirement sentence when hovered; each now shows the single correct message." },
{ module = "General", text = "Toggling Dark Mode now immediately re-evaluates any Conditional Override group that triggers on it, and the controls that feed that condition (the Dark Mode master, each unit frame's Dark Mode toggle, and Raid Frames Fill Color) lock while you are editing the trigger so an override cannot capture a change that flips its own condition." },