Fade in/out window system windows

This commit is contained in:
goaaats 2025-05-09 23:40:49 +02:00
parent 2c735e9ec3
commit b1c874c123
2 changed files with 64 additions and 6 deletions

View file

@ -32,6 +32,9 @@ namespace Dalamud.Interface.Windowing;
/// </summary>
public abstract class Window
{
private const float FadeInOutTime = 1f;
private const float FadeInOutStep = 0.09f;
private static readonly ModuleLog Log = new("WindowSystem");
private static bool wasEscPressedLastFrame = false;
@ -48,6 +51,12 @@ public abstract class Window
private PresetModel.PresetWindow? presetWindow;
private bool presetDirty = false;
private float fadeInTimer = 1f;
private float fadeOutTimer = 0f;
private IDrawListTextureWrap? fadeOutTexture = null;
private Vector2 fadeOutSize = Vector2.Zero;
private Vector2 fadeOutOrigin = Vector2.Zero;
/// <summary>
/// Initializes a new instance of the <see cref="Window"/> class.
/// </summary>
@ -89,6 +98,11 @@ public abstract class Window
/// Enable the built-in "additional options" menu on the title bar.
/// </summary>
UseAdditionalOptions = 1 << 2,
/// <summary>
/// Do not draw non-critical animations.
/// </summary>
IsReducedMotion = 1 << 3,
}
/// <summary>
@ -316,6 +330,7 @@ public abstract class Window
internal void DrawInternal(WindowDrawFlags internalDrawFlags, WindowSystemPersistence? persistence)
{
this.PreOpenCheck();
var isReducedMotion = internalDrawFlags.HasFlag(WindowDrawFlags.IsReducedMotion);
if (!this.IsOpen)
{
@ -330,9 +345,35 @@ public abstract class Window
UIGlobals.PlaySoundEffect(this.OnCloseSfxId);
}
if (this.fadeOutTexture != null)
{
this.fadeOutTimer -= FadeInOutStep;
if (this.fadeOutTimer <= 0f)
{
this.fadeOutTexture.Dispose();
this.fadeOutTexture = null;
}
else
{
var dl = ImGui.GetBackgroundDrawList();
dl.AddImage(
this.fadeOutTexture.ImGuiHandle,
this.fadeOutOrigin,
this.fadeOutOrigin + this.fadeOutSize,
Vector2.Zero,
Vector2.One,
ImGui.ColorConvertFloat4ToU32(new(1f, 1f, 1f, Math.Clamp(this.fadeOutTimer / FadeInOutTime, 0f, 1f))));
}
}
this.fadeInTimer = !isReducedMotion ? 0f : FadeInOutTime;
return;
}
this.fadeInTimer += FadeInOutStep;
if (this.fadeInTimer > FadeInOutTime)
this.fadeInTimer = FadeInOutTime;
this.Update();
if (!this.DrawConditions())
return;
@ -546,8 +587,19 @@ public abstract class Window
}
}
this.fadeOutSize = ImGui.GetWindowSize();
this.fadeOutOrigin = ImGui.GetWindowPos();
ImGui.End();
if (!this.internalIsOpen && this.fadeOutTexture == null && !isReducedMotion)
{
this.fadeOutTexture = Service<TextureManager>.Get().CreateDrawListTexture(
"WindowFadeOutTexture");
this.fadeOutTexture.ResizeAndDrawWindow(this.WindowName, Vector2.One);
this.fadeOutTimer = FadeInOutTime;
}
if (printWindow)
{
var tex = Service<TextureManager>.Get().CreateDrawListTexture(
@ -567,7 +619,7 @@ public abstract class Window
ImGui.PopID();
}
private void ApplyConditionals()
private unsafe void ApplyConditionals()
{
if (this.Position.HasValue)
{
@ -594,15 +646,18 @@ public abstract class Window
ImGui.SetNextWindowSizeConstraints(this.SizeConstraints.Value.MinimumSize * ImGuiHelpers.GlobalScale, this.SizeConstraints.Value.MaximumSize * ImGuiHelpers.GlobalScale);
}
if (this.BgAlpha.HasValue)
var maxBgAlpha = this.internalAlpha ?? this.BgAlpha;
var fadeInAlpha = this.fadeInTimer / FadeInOutTime;
if (fadeInAlpha < 1f)
{
ImGui.SetNextWindowBgAlpha(this.BgAlpha.Value);
maxBgAlpha = maxBgAlpha.HasValue ?
Math.Clamp(maxBgAlpha.Value * fadeInAlpha, 0f, 1f) :
(*ImGui.GetStyleColorVec4(ImGuiCol.WindowBg)).W * fadeInAlpha;
}
// Manually set alpha takes precedence, if devs don't want that, they should turn it off
if (this.internalAlpha.HasValue)
if (maxBgAlpha.HasValue)
{
ImGui.SetNextWindowBgAlpha(this.internalAlpha.Value);
ImGui.SetNextWindowBgAlpha(maxBgAlpha.Value);
}
}

View file

@ -119,6 +119,9 @@ public class WindowSystem
if (config?.IsFocusManagementEnabled ?? false)
flags |= Window.WindowDrawFlags.UseFocusManagement;
if (config?.ReduceMotions ?? false)
flags |= Window.WindowDrawFlags.IsReducedMotion;
// Shallow clone the list of windows so that we can edit it without modifying it while the loop is iterating
foreach (var window in this.windows.ToArray())
{