-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathUiHideModule.lua
1105 lines (811 loc) · 38.1 KB
/
UiHideModule.lua
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
local folderName, Addon = ...
-- For debugging:
-- We have to work with frame name, because some frames do not exist yet at startup.
-- local debugFrameName = "ClassTrainerFrame"
-- Have to store uiHiddenTime and currentConfig globally,
-- because several addons may use this module simultaneously.
if not ludius_UiHideModule then
ludius_UiHideModule = {}
-- Flag indicating if the UI is currently faded out.
ludius_UiHideModule.uiHiddenTime = 0
-- Save for each addon separately whether they have hidden the UI.
ludius_UiHideModule.addonsHiddenStatus = {}
-- The current configuration passed by the addon calling HideUI.
ludius_UiHideModule.currentConfig = nil
-- Collect alert frames that are created.
ludius_UiHideModule.collectedAlertFrames = {}
end
-- For quick access.
local currentConfig = ludius_UiHideModule.currentConfig
local collectedAlertFrames = ludius_UiHideModule.collectedAlertFrames
-- Call Addon.HideUI(fadeOutTime, config) to hide UI keeping configured frames.
-- Call Addon.ShowUI(fadeInTime, true) when entering combat while UI is hidden.
-- This will show the actually hidden frames, that cannot be shown during combat,
-- but the fade out state will remain. You only see tooltips of faded-out frames.
-- Call Addon.ShowUI(fadeInTime, false) to show UI.
-- Accepted options for config argument of HideUI():
-- config.hideFrameRate
-- config.keepAlertFrames
-- config.keepTooltip
-- config.keepMinimap
-- config.keepChatFrame
-- config.keepPartyRaidFrame
-- config.keepTrackingBar
-- config.keepEncounterBar
-- config.keepCustomFrames
-- config.customFramesToKeep
-- config.UIParentAlpha (while faded out)
-- Lua API
local _G = _G
local tonumber = tonumber
local tinsert = tinsert
local string_find = string.find
local string_match = string.match
local GetTime = _G.GetTime
local InCombatLockdown = _G.InCombatLockdown
local UnitInParty = _G.UnitInParty
local CompactRaidFrameContainer = _G.CompactRaidFrameContainer
-- The user can define custom frames to keep visible.
-- To prevent these user settings from clashing with the other frames,
-- we store the names of frames handled by the addon.
-- Frames whose visibility is defined via explicit UI checkboxes/flags.
local flagFrames = {
-- config.hideFrameRate
["FramerateLabel"] = true,
["FramerateText"] = true,
-- config.keepAlertFrames
["CovenantRenownToast"] = true,
-- config.keepMinimap
["MinimapCluster"] = true,
-- Minimap is needed, because Immersion sets it to IgnoreParentAlpha.
["Minimap"] = true,
-- config.keepTooltip
["GameTooltip"] = true,
["AceGUITooltip"] = true,
["AceConfigDialogTooltip"] = true,
-- config.keepTrackingBar
-- Retail
["StatusTrackingBarManager"] = true,
["BT4BarStatus"] = true,
-- Classic
["MainMenuExpBar"] = true,
["ReputationWatchBar"] = true,
-- GW2 UI
["GwExperienceFrame"] = true,
-- config.keepEncounterBar
["EncounterBar"] = true,
}
-- config.keepChatFrame
for i = 1, 12, 1 do
flagFrames["ChatFrame" .. i] = true
flagFrames["ChatFrame" .. i .. "Tab"] = true
flagFrames["ChatFrame" .. i .. "EditBox"] = true
flagFrames["GwChatContainer" .. i] = true
end
-- config.keepPartyRaidFrame
for i = 1, 4, 1 do
flagFrames["PartyMemberFrame" .. i] = true
flagFrames["PartyMemberFrame" .. i .. "NotPresentIcon"] = true
end
-- Frames which are hidden by default.
local defaultHiddenFrames = {
["QuickJoinToastButton"] = true,
["PlayerFrame"] = true,
["PetFrame"] = true,
["TargetFrame"] = true,
["BuffFrame"] = true,
["DebuffFrame"] = true,
["ObjectiveTrackerFrame"] = true,
-- TODO: Would have to fade every single 3D model separately.
["WardrobeFrame"] = true,
["CollectionsJournal"] = true,
}
if Bartender4 then
defaultHiddenFrames["BT4Bar1"] = true
defaultHiddenFrames["BT4Bar2"] = true
defaultHiddenFrames["BT4Bar3"] = true
defaultHiddenFrames["BT4Bar4"] = true
defaultHiddenFrames["BT4Bar5"] = true
defaultHiddenFrames["BT4Bar6"] = true
defaultHiddenFrames["BT4Bar7"] = true
defaultHiddenFrames["BT4Bar8"] = true
defaultHiddenFrames["BT4Bar9"] = true
defaultHiddenFrames["BT4Bar10"] = true
defaultHiddenFrames["BT4Bar11"] = true
defaultHiddenFrames["BT4Bar12"] = true
defaultHiddenFrames["BT4Bar13"] = true
defaultHiddenFrames["BT4Bar14"] = true
defaultHiddenFrames["BT4Bar15"] = true
defaultHiddenFrames["BT4BarBagBar"] = true
defaultHiddenFrames["BT4BarMicroMenu"] = true
defaultHiddenFrames["BT4BarStanceBar"] = true
defaultHiddenFrames["BT4BarPetBar"] = true
else
defaultHiddenFrames["MainMenuBar"] = true
defaultHiddenFrames["MultiBarLeft"] = true
defaultHiddenFrames["MultiBarRight"] = true
defaultHiddenFrames["MultiBarBottomLeft"] = true
defaultHiddenFrames["MultiBarBottomRight"] = true
defaultHiddenFrames["MultiBar5"] = true
defaultHiddenFrames["MultiBar6"] = true
defaultHiddenFrames["MultiBar7"] = true
defaultHiddenFrames["MultiBar8"] = true
defaultHiddenFrames["ExtraAbilityContainer"] = true
defaultHiddenFrames["MainMenuBarVehicleLeaveButton"] = true
defaultHiddenFrames["MicroButtonAndBagsBar"] = true
defaultHiddenFrames["MultiCastActionBarFrame"] = true
defaultHiddenFrames["StanceBar"] = true
defaultHiddenFrames["PetActionBar"] = true
defaultHiddenFrames["PossessBar"] = true
end
local keepDefaultHiddenFramesAsParent = {}
-- We need a function to change a frame's alpha without automatically showing the frame
-- (as done by the original UIFrameFade() defined in UIParent.lua).
if not ludius_FADEFRAMES then ludius_FADEFRAMES = {} end
local frameFadeManager = CreateFrame("FRAME")
local function UIFrameFadeRemoveFrame(frame)
tDeleteItem(ludius_FADEFRAMES, frame)
end
-- Changed this to work with GetTime() instead of "elapsed" argument.
-- Because the first elapsed after login is always very long and we want
-- to be able to start a smooth fade out beginning at the first update.
local lastUpdate
local function UIFrameFade_OnUpdate(self)
local elapsed = 0
if lastUpdate then
elapsed = GetTime() - lastUpdate
end
lastUpdate = GetTime()
local index = 1
local frame, fadeInfo
while ludius_FADEFRAMES[index] do
frame = ludius_FADEFRAMES[index]
fadeInfo = frame.fadeInfo
-- Reset the timer if there isn't one, this is just an internal counter
if not fadeInfo.fadeTimer then
fadeInfo.fadeTimer = 0
end
fadeInfo.fadeTimer = fadeInfo.fadeTimer + elapsed
-- If the fadeTimer is less then the desired fade time then set the alpha otherwise hold the fade state, call the finished function, or just finish the fade
if tonumber(fadeInfo.fadeTimer) < tonumber(fadeInfo.timeToFade) then
if fadeInfo.mode == "IN" then
frame:SetAlpha((fadeInfo.fadeTimer / fadeInfo.timeToFade) * (fadeInfo.endAlpha - fadeInfo.startAlpha) + fadeInfo.startAlpha)
elseif fadeInfo.mode == "OUT" then
frame:SetAlpha(((fadeInfo.timeToFade - fadeInfo.fadeTimer) / fadeInfo.timeToFade) * (fadeInfo.startAlpha - fadeInfo.endAlpha) + fadeInfo.endAlpha)
end
-- if frame:GetName() == debugFrameName then print("UIFrameFade_OnUpdate", elapsed, frame:GetName(), fadeInfo.fadeTimer, fadeInfo.timeToFade, "Setting alpha", frame:GetAlpha()) end
else
-- if frame:GetName() == debugFrameName then print("Last call of UIFrameFade_OnUpdate.", frame:GetName(), "Setting endAlpha", fadeInfo.endAlpha) end
frame:SetAlpha(fadeInfo.endAlpha)
-- Complete the fade and call the finished function if there is one
UIFrameFadeRemoveFrame(frame)
if fadeInfo.finishedFunc then
fadeInfo.finishedFunc(fadeInfo.finishedArg1, fadeInfo.finishedArg2, fadeInfo.finishedArg3, fadeInfo.finishedArg4)
fadeInfo.finishedFunc = nil
end
end
index = index + 1
end
if #ludius_FADEFRAMES == 0 then
self:SetScript("OnUpdate", nil)
lastUpdate = nil
end
end
local function UIFrameFade(frame, fadeInfo)
if not frame then return end
-- We make sure that we always call this with mode, startAlpha and endAlpha.
assert(fadeInfo.mode)
assert(fadeInfo.startAlpha)
assert(fadeInfo.endAlpha)
-- if frame:GetName() == debugFrameName then print("UIFrameFade", frame:GetName(), fadeInfo.mode, fadeInfo.startAlpha, fadeInfo.endAlpha) end
frame.fadeInfo = fadeInfo
frame:SetAlpha(fadeInfo.startAlpha)
local index = 1
while ludius_FADEFRAMES[index] do
-- If frame is already set to fade then return
if ludius_FADEFRAMES[index] == frame then
return
end
index = index + 1
end
tinsert(ludius_FADEFRAMES, frame)
if #ludius_FADEFRAMES == 1 then
frameFadeManager:SetScript("OnUpdate", UIFrameFade_OnUpdate)
end
end
-- A function to set a frame's alpha depending on mouse over and
-- whether we are fading/faded out or not.
local function SetMouseOverAlpha(frame)
-- Only do something to frames for which the hovering was activated.
if frame.ludius_mouseOver == nil then return end
-- Fading or faded out.
if frame.ludius_fadeout then
-- If the mouse is hovering over the status bar, show it with alpha 1.
if frame.ludius_mouseOver then
-- In case we are currently fading out,
-- interrupt the fade out in progress.
UIFrameFadeRemoveFrame(frame)
frame.ludius_alreadyOnIt = nil
frame:SetAlpha(1)
-- Otherwise use the faded out alpha.
else
frame:SetAlpha(frame.ludius_alphaAfterFadeOut)
end
end
end
if WOW_PROJECT_ID == WOW_PROJECT_MAINLINE then
local function SetMouseOverFading(barManager)
-- Have to do this for the single bars.
-- Otherwise the text does not pop up any more when hovering over the bars.
-- It seems that OnEnter of a parent prevents the OnEnter of children to be triggered.
-- But only the OnEnter of single bars shows the bar text.
for _, frame in pairs(barManager.bars) do
if not frame.ludius_hooked then
frame:HookScript("OnEnter", function()
StatusTrackingBarManager.ludius_mouseOver = true
SetMouseOverAlpha(StatusTrackingBarManager)
end)
frame:HookScript("OnLeave", function()
StatusTrackingBarManager.ludius_mouseOver = false
SetMouseOverAlpha(StatusTrackingBarManager)
end)
frame.ludius_hooked = true
end
end
end
SetMouseOverFading(MainStatusTrackingBarContainer)
SetMouseOverFading(SecondaryStatusTrackingBarContainer)
else
-- Dirty work around with global flag until fade UI has become a lib to share between addons.
if not ludius_bars_hooked then
for _, frame in pairs({ReputationWatchBar, MainMenuExpBar}) do
frame:HookScript("OnEnter", function()
ReputationWatchBar.IEF_tempAlpha = ReputationWatchBar:GetAlpha()
ReputationWatchBar:SetAlpha(1)
MainMenuExpBar.IEF_tempAlpha = MainMenuExpBar:GetAlpha()
MainMenuExpBar:SetAlpha(1)
end )
frame:HookScript("OnLeave", function()
if (ReputationWatchBar.IEF_tempAlpha ~= nil) then
ReputationWatchBar:SetAlpha(ReputationWatchBar.IEF_tempAlpha)
end
if (MainMenuExpBar.IEF_tempAlpha ~= nil) then
MainMenuExpBar:SetAlpha(MainMenuExpBar.IEF_tempAlpha)
end
end )
end
ludius_bars_hooked = true
end
end
if C_AddOns.IsAddOnLoaded("GW2_UI") then
-- GW2_UI seems to offer no way of hooking any of its functions.
-- So we have to do it like this.
local enterWorldFrame = CreateFrame("Frame")
enterWorldFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
enterWorldFrame:SetScript("OnEvent", function()
if GwExperienceFrame then
GwExperienceFrame:HookScript("OnEnter", function()
GwExperienceFrame.ludius_mouseOver = true
SetMouseOverAlpha(GwExperienceFrame)
end)
GwExperienceFrame:HookScript("OnLeave", function()
GwExperienceFrame.ludius_mouseOver = false
SetMouseOverAlpha(GwExperienceFrame)
end)
end
end)
end
-- To hide the tooltip of bag items.
-- (While we are actually hiding other frames to suppress their tooltips,
-- this is not practical for the bag, as opening may cause an annoying FPS drop.)
local function GameTooltipHider(self)
if ludius_UiHideModule.uiHiddenTime == 0 or not self then return end
local ownerName = nil
if self:GetOwner() then
ownerName = self:GetOwner():GetName()
end
if ownerName == nil then return end
if string_find(ownerName, "^ContainerFrame") or ownerName == "ChatFrameChannelButton" then
self:Hide()
-- else
-- print(ownerName)
end
end
if WOW_PROJECT_ID == WOW_PROJECT_MAINLINE then
TooltipDataProcessor.AddTooltipPostCall(Enum.TooltipDataType.Item, GameTooltipHider)
else
GameTooltip:HookScript("OnTooltipSetItem", GameTooltipHider)
end
GameTooltip:HookScript("OnTooltipSetDefaultAnchor", GameTooltipHider)
GameTooltip:HookScript("OnShow", GameTooltipHider)
local function ConditionalHide(frame)
if not frame then return end
-- if frame:GetName() == debugFrameName then print("ConditionalHide", frame:GetName(), frame:GetParent():GetName(), frame:IsIgnoringParentAlpha()) end
-- Checking for combat lockdown is not this function's concern.
-- Functions calling it must make sure, it is not called in combat lockdown.
-- TODO: What if the combat started while the fade out was already happening???
if frame:IsProtected() and InCombatLockdown() then
print("ERROR: Should not try to hide", frame:GetName(), "in combat lockdown!")
end
if frame.ludius_shownBeforeFadeOut == nil then
-- if frame:GetName() == debugFrameName then print("Remember it was shown", frame:IsShown()) end
frame.ludius_shownBeforeFadeOut = frame:IsShown()
end
if frame:IsShown() then
frame:Hide()
end
end
local function ConditionalShow(frame)
if not frame or frame.ludius_shownBeforeFadeOut == nil then return end
-- if frame:GetName() == debugFrameName then print("ConditionalShow", frame:GetName(), frame.ludius_shownBeforeFadeOut) end
if frame:IsProtected() and InCombatLockdown() then
print("ERROR: Should not try to show", frame:GetName(), "in combat lockdown!")
end
-- If the frame is already shown, we leave it be.
if not frame:IsShown() then
-- For party and raid member frames, we cannot rely on ludius_shownBeforeFadeOut,
-- so some more complex checks are necessary.
-- Party member frames.
if string_find(frame:GetName(), "^PartyMemberFrame") then
-- The NotPresentIcon is taken care of by PartyMemberFrame_UpdateNotPresentIcon below.
-- So we only handle the actual PartyMemberFrame and do nothing otherwise.
if string_find(frame:GetName(), "^PartyMemberFrame(%d+)$") then
-- Only show the party member frames, if we are in a party that is not a raid.
-- (Use CompactRaidFrameContainer:IsShown() instead of UnitInRaid("player") because people might use
-- an addon like SoloRaidFrame to show the raid frame even while not in raid.)
if UnitInParty("player") and not CompactRaidFrameContainer:IsShown() then
-- Only for as many frames as there are party members.
local numGroupMembers = GetNumGroupMembers()
local frameNumber = tonumber(string_match(frame:GetName(), "^PartyMemberFrame(%d+)"))
if frameNumber < numGroupMembers then
frame:Show()
PartyMemberFrame_UpdateNotPresentIcon(frame)
-- The above functions set the alpha, but we want to do the fade in ourselves.
frame:SetAlpha(0)
frame.notPresentIcon:SetAlpha(0)
end
end
end
-- Only show the CompactRaidFrameContainer, if the player is still in a party.
elseif frame == CompactRaidFrameContainer then
-- (Again also use CompactRaidFrameContainer:IsShown() because people might use
-- an addon like SoloRaidFrame to show the raid frame even while not in raid.)
if UnitInParty("player") or CompactRaidFrameContainer:IsShown() then
frame:Show()
end
elseif frame.ludius_shownBeforeFadeOut then
-- if frame:GetName() == debugFrameName then print("Have to show it again!") end
frame:Show()
end
end
frame.ludius_shownBeforeFadeOut = nil
end
-- To prevent other addons (Immersion, I'm looking in your direction) from
-- setting Minimap's and MinimapCluster's ignoreParentAlpha to false, when DynamicCam does not.
local function ParentAlphaGuard(self, ignoreParentAlpha)
-- print(self:GetName(), "SetIgnoreParentAlpha", ignoreParentAlpha, self.ludius_intendedIgnoreParentAlpha)
if self.ludius_intendedIgnoreParentAlpha ~= nil and ignoreParentAlpha ~= self.ludius_intendedIgnoreParentAlpha then
-- print("no")
self:SetIgnoreParentAlpha(self.ludius_intendedIgnoreParentAlpha)
-- else
-- print("ok")
end
end
hooksecurefunc(MinimapCluster, "SetIgnoreParentAlpha", ParentAlphaGuard)
hooksecurefunc(Minimap, "SetIgnoreParentAlpha", ParentAlphaGuard)
-- To restore frames to their pre-hide ignore-parent-alpha state,
-- we remember it in the ludius_ignoreParentAlphaBeforeFadeOut variable.
local function ConditionalSetIgnoreParentAlpha(frame, ignoreParentAlpha)
-- if frame:GetName() == debugFrameName then print("ConditionalSetIgnoreParentAlpha", ignoreParentAlpha) end
if not frame or ignoreParentAlpha == nil then return end
if frame.ludius_ignoreParentAlphaBeforeFadeOut == nil then
frame.ludius_ignoreParentAlphaBeforeFadeOut = frame:IsIgnoringParentAlpha()
end
if frame:IsIgnoringParentAlpha() ~= ignoreParentAlpha then
frame.ludius_intendedIgnoreParentAlpha = ignoreParentAlpha
frame:SetIgnoreParentAlpha(ignoreParentAlpha)
end
end
local function ConditionalResetIgnoreParentAlpha(frame)
-- if frame:GetName() == debugFrameName then print("ConditionalSetIgnoreParentAlpha", ignoreParentAlpha) end
if not frame or frame.ludius_ignoreParentAlphaBeforeFadeOut == nil then return end
if frame:IsIgnoringParentAlpha() ~= frame.ludius_ignoreParentAlphaBeforeFadeOut then
frame.ludius_intendedIgnoreParentAlpha = frame.ludius_ignoreParentAlphaBeforeFadeOut
frame:SetIgnoreParentAlpha(frame.ludius_ignoreParentAlphaBeforeFadeOut)
end
frame.ludius_ignoreParentAlphaBeforeFadeOut = nil
end
-- The alert frames have to be dealt with as they are created.
-- https://www.wowinterface.com/forums/showthread.php?p=337803
-- For testing:
-- /run UIParent:SetAlpha(0.5)
-- /run NewMountAlertSystem:ShowAlert("123") NewMountAlertSystem:ShowAlert("123")
-- /run CovenantRenownToast:ShowRenownLevelUpToast(C_Covenants.GetActiveCovenantID(), 40)
-- A flag for alert frames that are created/collected while the UI is hidden.
local currentAlertFramesIgnoreParentAlpha = false
local function AlertFramesSetIgnoreParentAlpha(ignoreParentAlpha)
currentAlertFramesIgnoreParentAlpha = ignoreParentAlpha
for _, v in pairs(collectedAlertFrames) do
ConditionalSetIgnoreParentAlpha(v, ignoreParentAlpha)
end
end
local function AlertFramesResetIgnoreParentAlpha()
currentAlertFramesIgnoreParentAlpha = false
for _, v in pairs(collectedAlertFrames) do
ConditionalResetIgnoreParentAlpha(v)
end
end
local function CollectAlertFrame(_, frame)
-- print("CollectAlertFrame", frame, currentAlertFramesIgnoreParentAlpha, frame.ludius_collected)
if frame and not frame.ludius_collected then
tinsert(collectedAlertFrames, frame)
frame.ludius_collected = true
end
if currentAlertFramesIgnoreParentAlpha and not frame:IsIgnoringParentAlpha() then
ConditionalSetIgnoreParentAlpha(frame, currentAlertFramesIgnoreParentAlpha)
end
end
for _, subSystem in pairs(AlertFrame.alertFrameSubSystems) do
local pool = type(subSystem) == "table" and subSystem.alertFramePool
if type(pool) == "table" and type(pool.resetterFunc) == "function" then
hooksecurefunc(pool, "resetterFunc", CollectAlertFrame)
end
end
-- targetIgnoreParentAlpha == true: frame ignores parent alpha, and itself fades to targetAlpha (maybe different from UIParent's alpha).
-- targetIgnoreParentAlpha == false: frame adheres to parent alpha, but gets hidden, if targetAlpha (UIParent's alpha) is 0.
--
-- targetIgnoreParentAlpha == nil: Ignoring this frame!
-- This is needed for example, if the keeping or fading of a frame should be governed by another addon.
-- Like MinimapCluster is governed by Immersion and should therefore not be modified by IEF.
-- FadeInFrame() will automatically ignore non-faded frames as it will not find our ludius_ flags.
local function FadeOutFrame(frame, duration, targetIgnoreParentAlpha, targetAlpha)
if not frame or targetIgnoreParentAlpha == nil then return end
-- If another addon is already handling this, we don't touch it.
if frame.ludius_alreadyOnIt ~= nil and frame.ludius_alreadyOnIt ~= folderName then
return
else
frame.ludius_alreadyOnIt = folderName
end
assert(targetAlpha)
-- Prevent callback functions of currently active timers.
UIFrameFadeRemoveFrame(frame)
-- if frame:GetName() == debugFrameName then print("FadeOutFrame", frame:GetName(), duration, targetIgnoreParentAlpha, frame:IsIgnoringParentAlpha(), targetAlpha, frame:GetAlpha()) end
-- If a frame to be kept is not a direct child of UIParent,
-- we have to make sure that the parent gets not hidden later.
-- (e.g. In classic, the status tracking bars are children of MainMenuBar,
-- which normally is in defaultHiddenFrames.)
if targetIgnoreParentAlpha and targetAlpha > 0 then
local currentParent = frame:GetParent()
while currentParent and currentParent ~= UIParent and currentParrent ~= WorldFrame do
keepDefaultHiddenFramesAsParent[currentParent] = true
currentParent = currentParent:GetParent()
end
end
-- ludius_alphaBeforeFadeOut is only set, if this is a fresh FadeOutFrame().
-- It is set to nil after a FadeOutFrame() is completed.
-- Otherwise, we might falsely asume a wrong ludius_alphaBeforeFadeOut
-- value while a fade-in is still in progress.
if frame.ludius_alphaBeforeFadeOut == nil then
frame.ludius_alphaBeforeFadeOut = frame:GetAlpha()
end
-- To use UIFrameFade() which is the same as UIFrameFadeOut, but with a callback function.
local fadeInfo = {}
fadeInfo.mode = "OUT"
fadeInfo.timeToFade = duration
fadeInfo.finishedArg1 = frame
fadeInfo.finishedArg2 = targetAlpha
fadeInfo.finishedFunc = function(finishedArg1, finishedArg2)
-- if finishedArg1:GetName() == debugFrameName then print("Fade out finished", finishedArg1:GetName(), finishedArg2) end
if finishedArg2 == 0 and (not finishedArg1:IsProtected() or not InCombatLockdown()) and not keepDefaultHiddenFramesAsParent[finishedArg1] then
-- if finishedArg1:GetName() == debugFrameName then print("...and hiding!", finishedArg2) end
ConditionalHide(finishedArg1)
end
finishedArg1.ludius_alreadyOnIt = nil
end
-- Frame should henceforth ignore parent alpha.
if targetIgnoreParentAlpha then
-- This is to let SetMouseOverAlpha() know whether we are
-- currently fading/faded in or fading/faded out.
-- Notice that we cannot use ludius_alphaBeforeFadeOut or ludius_alphaAfterFadeOut as this flag,
-- because ludius_fadeout is unset at the beginning of a fade out
-- and ludius_alphaBeforeFadeOut is unset at the end of a fade out.
-- For an OnEnable/OnLeave during fade out, we do not want the alpha to change.
frame.ludius_fadeout = true
-- This is to let SetMouseOverAlpha() know which
-- alpha to go back to OnLeave while the frame is faded or fading out.
frame.ludius_alphaAfterFadeOut = targetAlpha
SetMouseOverAlpha(frame)
-- Frame was adhering to parent alpha before.
-- Start the fade with parent's current alpha.
if not frame:IsIgnoringParentAlpha() then
local parent = frame:GetParent()
fadeInfo.startAlpha = parent and parent:GetAlpha() or 1
-- Frame was already ignoring parent alpha before.
else
fadeInfo.startAlpha = frame:GetAlpha()
end
fadeInfo.endAlpha = targetAlpha
ConditionalSetIgnoreParentAlpha(frame, true)
-- Frame should henceforth adhere to parent alpha.
else
-- Frame was ignoring parent alpha before.
-- Start the fade with the frame's alpha, fade to UIParent's target alpha
-- and only then unset ignore parent alpha.
-- Notice that the frame's alpha is not overriden by parent alpha but combined.
-- So we have to set the child's alpha to 1 at the same time as we stop ignoring
-- parent alpha.
if frame:IsIgnoringParentAlpha() then
fadeInfo.startAlpha = frame:GetAlpha()
fadeInfo.endAlpha = targetAlpha
fadeInfo.finishedFunc = function(finishedArg1, finishedArg2)
-- if finishedArg1:GetName() == debugFrameName then print("Fade out finished", finishedArg1:GetName(), finishedArg2) end
finishedArg1:SetAlpha(1)
ConditionalSetIgnoreParentAlpha(finishedArg1, false)
if finishedArg2 == 0 and (not finishedArg1:IsProtected() or not InCombatLockdown()) and not keepDefaultHiddenFramesAsParent[finishedArg1] then
ConditionalHide(finishedArg1)
end
finishedArg1.ludius_alreadyOnIt = nil
end
-- Frame was already adhering to parent alpha.
-- We are not changing it.
else
-- if frame:GetName() == debugFrameName then print("was already adhering to parent alpha") end
fadeInfo.startAlpha = frame:GetAlpha()
fadeInfo.endAlpha = frame:GetAlpha()
end
end
-- Cannot rely on UIFrameFade to finish within the same frame.
if duration == 0 then
frame:SetAlpha(fadeInfo.endAlpha)
fadeInfo.finishedFunc(frame, targetAlpha)
-- This is for some frames to not being shown in between situations that are both hiding them.
elseif (frame == MinimapCluster or frame == ObjectiveTrackerFrame) and targetAlpha == 0 and targetIgnoreParentAlpha == false and frame:GetParent():GetAlpha() == 0 and frame:IsShown() then
fadeInfo.finishedFunc(frame, targetAlpha)
else
-- if frame:GetName() == debugFrameName then print("Starting fade with", fadeInfo.startAlpha, fadeInfo.endAlpha, fadeInfo.mode, fadeInfo.timeToFade) end
UIFrameFade(frame, fadeInfo)
end
end
local function FadeInFrame(frame, duration, enteringCombat)
if not frame then return end
-- If another addon is already handling this, we don't touch it.
if frame.ludius_alreadyOnIt ~= nil and frame.ludius_alreadyOnIt ~= folderName then
-- print(folderName, "not touching", frame:GetName())
return
else
frame.ludius_alreadyOnIt = folderName
end
-- Prevent callback functions of currently active timers.
UIFrameFadeRemoveFrame(frame)
-- Only do something if we have touched this frame before.
if frame.ludius_shownBeforeFadeOut == nil and frame.ludius_alphaBeforeFadeOut == nil and frame.ludius_ignoreParentAlphaBeforeFadeOut == nil then
frame.ludius_alreadyOnIt = nil
return
end
-- if frame:GetName() == debugFrameName then print("FadeInFrame", frame:GetName(), frame:IsIgnoringParentAlpha()) end
if enteringCombat then
-- When entering combat we have to show protected frames, which cannot be shown any more during combat.
if frame:IsProtected() then
ConditionalShow(frame)
end
frame.ludius_alreadyOnIt = nil
-- But we do not yet do the fade in.
return
else
ConditionalShow(frame)
end
-- To use UIFrameFade() which is the same as UIFrameFadeOut, but with a callback function.
local fadeInfo = {}
fadeInfo.mode = "IN"
fadeInfo.timeToFade = duration
fadeInfo.finishedArg1 = frame
fadeInfo.finishedFunc = function(finishedArg1)
finishedArg1.ludius_alphaBeforeFadeOut = nil
finishedArg1.ludius_alphaAfterFadeOut = nil
finishedArg1.ludius_alreadyOnIt = nil
end
-- Frame should henceforth ignore parent alpha.
if frame.ludius_ignoreParentAlphaBeforeFadeOut == true then
-- Frame was adhering to parent alpha before.
-- Start the fade with parent's current alpha.
if not frame:IsIgnoringParentAlpha() then
fadeInfo.startAlpha = frame:GetParent():GetAlpha()
-- Frame was already ignoring parent alpha before.
else
fadeInfo.startAlpha = frame:GetAlpha()
end
fadeInfo.endAlpha = frame.ludius_alphaBeforeFadeOut
ConditionalResetIgnoreParentAlpha(frame)
-- Frame should henceforth adhere to parent alpha.
elseif frame.ludius_ignoreParentAlphaBeforeFadeOut == false then
-- Frame was ignoring parent alpha before.
-- Start the fade with the frame's alpha, fade to UIParent's target alpha
-- (which is always 1 when we fade the UI back in) and only then unset
-- ignore parent alpha.
if frame:IsIgnoringParentAlpha() then
fadeInfo.startAlpha = frame:GetAlpha()
fadeInfo.endAlpha = 1
fadeInfo.finishedFunc = function(finishedArg1)
ConditionalResetIgnoreParentAlpha(finishedArg1)
finishedArg1.ludius_alphaBeforeFadeOut = nil
finishedArg1.ludius_alphaAfterFadeOut = nil
finishedArg1.ludius_alreadyOnIt = nil
end
-- Frame was already adhering to parent alpha.
-- We are not changing it.
else
fadeInfo.startAlpha = frame:GetAlpha()
fadeInfo.endAlpha = frame:GetAlpha()
end
-- No stored value in ludius_ignoreParentAlphaBeforeFadeOut.
else
fadeInfo.startAlpha = frame:GetAlpha()
fadeInfo.endAlpha = frame.ludius_alphaBeforeFadeOut or frame:GetAlpha()
end
-- if frame:GetName() == debugFrameName then print("Starting fade with", fadeInfo.startAlpha, fadeInfo.endAlpha, fadeInfo.mode) end
-- Cannot rely on UIFrameFade to finish within the same frame.
if duration == 0 then
frame:SetAlpha(fadeInfo.endAlpha)
fadeInfo.finishedFunc(frame)
else
UIFrameFade(frame, fadeInfo)
end
-- We can do this always when fading in.
frame.ludius_fadeout = nil
SetMouseOverAlpha(frame)
end
-- So the GameTooltip stays hidden while UI is faded.
local hideGameTooltip = nil
GameTooltip:HookScript("OnShow", function(self)
if hideGameTooltip and self:GetOwner() == UIParent then
self:Hide()
end
end)
Addon.HideUI = function(fadeOutTime, config)
-- print("HideUI", folderName, fadeOutTime, config.UIParentAlpha)
keepDefaultHiddenFramesAsParent = {}
-- Remember that the UI is faded.
ludius_UiHideModule.uiHiddenTime = GetTime()
ludius_UiHideModule.addonsHiddenStatus[folderName] = true
currentConfig = config
if config.hideFrameRate then
-- The framerate label is a child of WorldFrame, while we just fade UIParent.
-- That's why we have to set targetIgnoreParentAlpha to true.
FadeOutFrame(FramerateLabel, fadeOutTime, true, config.UIParentAlpha)
FadeOutFrame(FramerateText, fadeOutTime, true, config.UIParentAlpha)
end
AlertFramesSetIgnoreParentAlpha(config.keepAlertFrames)
FadeOutFrame(CovenantRenownToast, fadeOutTime, config.keepAlertFrames, config.keepAlertFrames and 1 or config.UIParentAlpha)
FadeOutFrame(MinimapCluster, fadeOutTime, config.keepMinimap, config.keepMinimap and 1 or config.UIParentAlpha)
-- Minimap is needed, because Immersion sets it to IgnoreParentAlpha.
FadeOutFrame(Minimap, fadeOutTime, config.keepMinimap, config.keepMinimap and 1 or config.UIParentAlpha)
FadeOutFrame(GameTooltip, fadeOutTime, config.keepTooltip, config.keepTooltip and 1 or config.UIParentAlpha)
C_Timer.After(fadeOutTime, function() hideGameTooltip = (config.keepTooltip == false) end)
local shoppingTooltip1, shoppingTooltip2 = unpack(GameTooltip.shoppingTooltips)
FadeOutFrame(shoppingTooltip1, fadeOutTime, config.keepTooltip, config.keepTooltip and 1 or config.UIParentAlpha)
FadeOutFrame(shoppingTooltip2, fadeOutTime, config.keepTooltip, config.keepTooltip and 1 or config.UIParentAlpha)
FadeOutFrame(AceGUITooltip, fadeOutTime, config.keepTooltip, config.keepTooltip and 1 or config.UIParentAlpha)
FadeOutFrame(AceConfigDialogTooltip, fadeOutTime, config.keepTooltip, config.keepTooltip and 1 or config.UIParentAlpha)
for i = 1, 12, 1 do
if _G["ChatFrame" .. i] then
FadeOutFrame(_G["ChatFrame" .. i], fadeOutTime, config.keepChatFrame, config.keepChatFrame and 1 or config.UIParentAlpha)
FadeOutFrame(_G["ChatFrame" .. i .. "Tab"], fadeOutTime, config.keepChatFrame, config.keepChatFrame and 1 or config.UIParentAlpha)
FadeOutFrame(_G["ChatFrame" .. i .. "EditBox"], fadeOutTime, config.keepChatFrame, config.keepChatFrame and 1 or config.UIParentAlpha)
end
if _G["GwChatContainer" .. i] then
FadeOutFrame(_G["GwChatContainer" .. i], fadeOutTime, config.keepChatFrame, config.keepChatFrame and 1 or config.UIParentAlpha)
end
end
-- Status tracking bars.
-- Retail
FadeOutFrame(StatusTrackingBarManager, fadeOutTime, config.keepTrackingBar, config.keepTrackingBar and config.trackingBarAlpha or config.UIParentAlpha)
FadeOutFrame(BT4BarStatus, fadeOutTime, config.keepTrackingBar, config.keepTrackingBar and config.trackingBarAlpha or config.UIParentAlpha)
-- Classic
FadeOutFrame(MainMenuExpBar, fadeOutTime, config.keepTrackingBar, config.keepTrackingBar and config.trackingBarAlpha or config.UIParentAlpha)
FadeOutFrame(ReputationWatchBar, fadeOutTime, config.keepTrackingBar, config.keepTrackingBar and config.trackingBarAlpha or config.UIParentAlpha)
-- GW2 UI
FadeOutFrame(GwExperienceFrame, fadeOutTime, config.keepTrackingBar, config.keepTrackingBar and config.trackingBarAlpha or config.UIParentAlpha)
FadeOutFrame(EncounterBar, fadeOutTime, config.keepEncounterBar, config.keepEncounterBar and 1 or config.UIParentAlpha)
FadeOutFrame(CompactRaidFrameContainer, fadeOutTime, config.keepPartyRaidFrame, config.keepPartyRaidFrame and 1 or config.UIParentAlpha)
-- Non-configurable frames that we just want to hide in case UIParentAlpha is 0.
for k in pairs(defaultHiddenFrames) do
-- Using "not not" to convert nil to false.
local keepFrame = not not config.keepCustomFrames and not not config.customFramesToKeep[k]
FadeOutFrame(_G[k], fadeOutTime, keepFrame, keepFrame and 1 or config.UIParentAlpha)
end
-- Keep frames that are in config.customFramesToKeep but not in defaultHiddenFrames or flagFrames.
if config.keepCustomFrames then
for k in pairs(config.customFramesToKeep) do
-- print(k, _G[k])
if not defaultHiddenFrames[k] and not flagFrames[k] then
-- If the frame does not exist yet (e.g. ClassTrainerFrame), try again after a short time.
if not _G[k] then
C_Timer.After(0.3, function() FadeOutFrame(_G[k], fadeOutTime, true, 1) end)
else
-- At the moment we are not supporting custom alphas for kept frames, so we set it to 1.
FadeOutFrame(_G[k], fadeOutTime, true, 1)
end
end
end
end
if Addon.frameShowTimer then LibStub("AceTimer-3.0"):CancelTimer(Addon.frameShowTimer) end
end
-- If enteringCombat we only show the hidden frames (which cannot be shown
-- during combat lockdown). But we skip the SetIgnoreParentAlpha(false).
-- This can be done when the intended ShowUI() is called.
Addon.ShowUI = function(fadeInTime, enteringCombat)
-- Just to be on the safe side.
keepDefaultHiddenFramesAsParent = {}