diff --git a/Dalamud/Interface/Internal/Notifications/ActiveNotification.cs b/Dalamud/Interface/Internal/Notifications/ActiveNotification.cs
index 178cdb041..90c99ab11 100644
--- a/Dalamud/Interface/Internal/Notifications/ActiveNotification.cs
+++ b/Dalamud/Interface/Internal/Notifications/ActiveNotification.cs
@@ -64,9 +64,14 @@ internal sealed class ActiveNotification : IActiveNotification, IDisposable
public long Id { get; } = IActiveNotification.CreateNewId();
///
- /// Gets the tick of creating this notification.
+ /// Gets the time of creating this notification.
///
- public long CreatedAt { get; } = Environment.TickCount64;
+ public DateTime CreatedAt { get; } = DateTime.Now;
+
+ ///
+ /// Gets the time of starting to count the timer for the expiration.
+ ///
+ public DateTime ExpiryRelativeToTime { get; private set; } = DateTime.Now;
///
public string Content => this.underlyingNotification.Content;
@@ -249,6 +254,7 @@ internal sealed class ActiveNotification : IActiveNotification, IDisposable
ImGui.PushID(this.Id.GetHashCode());
ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, new Vector2(NotificationConstants.ScaledWindowPadding));
ImGui.PushStyleVar(ImGuiStyleVar.Alpha, opacity);
+ ImGui.PushStyleVar(ImGuiStyleVar.WindowRounding, 0f);
unsafe
{
ImGui.PushStyleColor(
@@ -289,13 +295,36 @@ internal sealed class ActiveNotification : IActiveNotification, IDisposable
var windowPos = ImGui.GetWindowPos();
var windowSize = ImGui.GetWindowSize();
+ float expiryRatio;
+ if (this.IsDismissed)
+ {
+ expiryRatio = 0f;
+ }
+ else if (this.Expiry == DateTime.MaxValue || (this.HoverExtendDuration > TimeSpan.Zero && this.IsMouseHovered))
+ {
+ expiryRatio = 1f;
+ }
+ else
+ {
+ expiryRatio = (float)((this.Expiry - DateTime.Now).TotalMilliseconds /
+ (this.Expiry - this.ExpiryRelativeToTime).TotalMilliseconds);
+ }
+
+ expiryRatio = Math.Clamp(expiryRatio, 0f, 1f);
+ ImGui.PushClipRect(windowPos, windowPos + windowSize, false);
+ ImGui.GetWindowDrawList().AddRectFilled(
+ windowPos + new Vector2(0, windowSize.Y - NotificationConstants.ScaledExpiryProgressBarHeight),
+ windowPos + windowSize with { X = windowSize.X * expiryRatio },
+ ImGui.GetColorU32(this.DefaultIconColor));
+ ImGui.PopClipRect();
+
ImGui.End();
if (!this.IsDismissed)
this.DrawCloseButton(interfaceManager, windowPos);
ImGui.PopStyleColor();
- ImGui.PopStyleVar(2);
+ ImGui.PopStyleVar(3);
ImGui.PopID();
if (windowPos.X <= ImGui.GetIO().MousePos.X
@@ -315,7 +344,10 @@ internal sealed class ActiveNotification : IActiveNotification, IDisposable
{
var newExpiry = DateTime.Now + this.HoverExtendDuration;
if (newExpiry > this.Expiry)
+ {
this.underlyingNotification.Expiry = newExpiry;
+ this.ExpiryRelativeToTime = DateTime.Now;
+ }
}
this.IsMouseHovered = false;
@@ -332,7 +364,15 @@ internal sealed class ActiveNotification : IActiveNotification, IDisposable
this.underlyingNotification.Title = newNotification.Title;
this.underlyingNotification.Type = newNotification.Type;
this.underlyingNotification.IconCreator = newNotification.IconCreator;
- this.underlyingNotification.Expiry = newNotification.Expiry;
+ if (this.underlyingNotification.Expiry != newNotification.Expiry)
+ {
+ this.underlyingNotification.Expiry = newNotification.Expiry;
+ this.ExpiryRelativeToTime = DateTime.Now;
+ }
+
+ this.underlyingNotification.Interactible = newNotification.Interactible;
+ this.underlyingNotification.ClickIsDismiss = newNotification.ClickIsDismiss;
+ this.underlyingNotification.HoverExtendDuration = newNotification.HoverExtendDuration;
}
///
@@ -491,7 +531,6 @@ internal sealed class ActiveNotification : IActiveNotification, IDisposable
ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, Vector2.Zero);
ImGui.PushStyleVar(ImGuiStyleVar.FrameRounding, 0f);
ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, Vector2.Zero);
- ImGui.PushStyleVar(ImGuiStyleVar.WindowRounding, 0f);
ImGui.PushStyleColor(ImGuiCol.Button, 0);
ImGui.PushStyleColor(ImGuiCol.Text, NotificationConstants.CloseTextColor);
@@ -511,7 +550,7 @@ internal sealed class ActiveNotification : IActiveNotification, IDisposable
ImGui.End();
ImGui.PopStyleColor(2);
- ImGui.PopStyleVar(4);
+ ImGui.PopStyleVar(3);
}
}
diff --git a/Dalamud/Interface/Internal/Notifications/NotificationConstants.cs b/Dalamud/Interface/Internal/Notifications/NotificationConstants.cs
index 44b1fa832..bf71cd87e 100644
--- a/Dalamud/Interface/Internal/Notifications/NotificationConstants.cs
+++ b/Dalamud/Interface/Internal/Notifications/NotificationConstants.cs
@@ -70,5 +70,8 @@ internal static class NotificationConstants
public static float ScaledIconSize => MathF.Round(IconSize * ImGuiHelpers.GlobalScale);
/// Gets the scaled size of the close button.
- public static float ScaledCloseButtonMinSize => MathF.Round(16 * ImGuiHelpers.GlobalScale);
+ public static float ScaledCloseButtonMinSize => MathF.Round(16 * ImGuiHelpers.GlobalScale);
+
+ /// Gets the height of the expiry progress bar.
+ public static float ScaledExpiryProgressBarHeight => MathF.Round(2 * ImGuiHelpers.GlobalScale);
}