mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
Add IconSource
This commit is contained in:
parent
7aba15ef5b
commit
3a6aa13c3b
13 changed files with 506 additions and 119 deletions
|
|
@ -1,5 +1,4 @@
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Dalamud.Interface.Internal.Notifications;
|
||||
|
||||
|
|
@ -57,8 +56,10 @@ public interface IActiveNotification : INotification
|
|||
/// <inheritdoc cref="INotification.Type"/>
|
||||
new NotificationType Type { get; set; }
|
||||
|
||||
/// <inheritdoc cref="INotification.IconCreator"/>
|
||||
new Func<Task<object>>? IconCreator { get; set; }
|
||||
/// <summary>Gets or sets the icon source.</summary>
|
||||
/// <remarks>Setting a new value to this property does not change the icon. Use <see cref="UpdateIcon"/> to do so.
|
||||
/// </remarks>
|
||||
new INotificationIconSource? IconSource { get; set; }
|
||||
|
||||
/// <inheritdoc cref="INotification.Expiry"/>
|
||||
new DateTime Expiry { get; set; }
|
||||
|
|
@ -91,13 +92,13 @@ public interface IActiveNotification : INotification
|
|||
|
||||
/// <summary>Updates the notification data.</summary>
|
||||
/// <remarks>
|
||||
/// Call <see cref="UpdateIcon"/> to update the icon using the new <see cref="INotification.IconCreator"/>.
|
||||
/// Call <see cref="UpdateIcon"/> to update the icon using the new <see cref="INotification.IconSource"/>.
|
||||
/// If <see cref="IsDismissed"/> is <c>true</c>, then this function is a no-op.
|
||||
/// </remarks>
|
||||
/// <param name="newNotification">The new notification entry.</param>
|
||||
void Update(INotification newNotification);
|
||||
|
||||
/// <summary>Loads the icon again using <see cref="INotification.IconCreator"/>.</summary>
|
||||
/// <summary>Loads the icon again using <see cref="INotification.IconSource"/>.</summary>
|
||||
/// <remarks>If <see cref="IsDismissed"/> is <c>true</c>, then this function is a no-op.</remarks>
|
||||
void UpdateIcon();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
using Dalamud.Game.Text;
|
||||
using Dalamud.Interface.Internal;
|
||||
using Dalamud.Interface.ImGuiNotification.IconSource;
|
||||
using Dalamud.Interface.Internal.Notifications;
|
||||
|
||||
namespace Dalamud.Interface.ImGuiNotification;
|
||||
|
|
@ -18,18 +15,17 @@ public interface INotification
|
|||
/// <summary>Gets the type of the notification.</summary>
|
||||
NotificationType Type { get; }
|
||||
|
||||
/// <summary>Gets the icon creator function for the notification.<br />
|
||||
/// Currently <see cref="IDalamudTextureWrap"/>, <see cref="SeIconChar"/>, and <see cref="FontAwesomeIcon"/> types
|
||||
/// are accepted.</summary>
|
||||
/// <remarks>
|
||||
/// The icon created by the task returned will be owned by Dalamud,
|
||||
/// i.e. it will be <see cref="IDisposable.Dispose"/>d automatically as needed.<br />
|
||||
/// If <c>null</c> is supplied for this property or <see cref="Task.IsCompletedSuccessfully"/> of the returned task
|
||||
/// is <c>false</c>, then the corresponding icon with <see cref="Type"/> will be used.<br />
|
||||
/// Use <see cref="Task.FromResult{TResult}"/> if you have an instance of <see cref="IDalamudTextureWrap"/> that you
|
||||
/// can transfer ownership to Dalamud and is available for use right away.
|
||||
/// <summary>Gets the icon source.</summary>
|
||||
/// <remarks>The following icon sources are currently available.<br />
|
||||
/// <ul>
|
||||
/// <li><see cref="SeIconCharIconSource"/></li>
|
||||
/// <li><see cref="FontAwesomeIconIconSource"/></li>
|
||||
/// <li><see cref="TextureWrapTaskIconSource"/></li>
|
||||
/// <li><see cref="GamePathIconSource"/></li>
|
||||
/// <li><see cref="FilePathIconSource"/></li>
|
||||
/// </ul>
|
||||
/// </remarks>
|
||||
Func<Task<object>>? IconCreator { get; }
|
||||
INotificationIconSource? IconSource { get; }
|
||||
|
||||
/// <summary>Gets the expiry.</summary>
|
||||
/// <remarks>Set to <see cref="DateTime.MaxValue"/> to make the notification not have an expiry time
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
namespace Dalamud.Interface.ImGuiNotification;
|
||||
|
||||
/// <summary>Icon source for <see cref="INotification"/>.</summary>
|
||||
/// <remarks>Plugins should NOT implement this interface.</remarks>
|
||||
public interface INotificationIconSource : ICloneable, IDisposable
|
||||
{
|
||||
/// <summary>The internal interface.</summary>
|
||||
internal interface IInternal : INotificationIconSource
|
||||
{
|
||||
/// <summary>Materializes the icon resource.</summary>
|
||||
/// <returns>The materialized resource.</returns>
|
||||
INotificationMaterializedIcon Materialize();
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="ICloneable.Clone"/>
|
||||
new INotificationIconSource Clone();
|
||||
|
||||
/// <inheritdoc/>
|
||||
object ICloneable.Clone() => this.Clone();
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
using System.Numerics;
|
||||
|
||||
using Dalamud.Plugin.Internal.Types;
|
||||
|
||||
namespace Dalamud.Interface.ImGuiNotification;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a materialized icon.
|
||||
/// </summary>
|
||||
internal interface INotificationMaterializedIcon : IDisposable
|
||||
{
|
||||
/// <summary>Draws the icon.</summary>
|
||||
/// <param name="minCoord">The coordinates of the top left of the icon area.</param>
|
||||
/// <param name="maxCoord">The coordinates of the bottom right of the icon area.</param>
|
||||
/// <param name="color">The foreground color.</param>
|
||||
/// <param name="initiatorPlugin">The initiator plugin.</param>
|
||||
void DrawIcon(Vector2 minCoord, Vector2 maxCoord, Vector4 color, LocalPlugin? initiatorPlugin);
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
using System.IO;
|
||||
using System.Numerics;
|
||||
|
||||
using Dalamud.Interface.ImGuiNotification.Internal;
|
||||
using Dalamud.Interface.Internal;
|
||||
using Dalamud.Plugin.Internal.Types;
|
||||
|
||||
namespace Dalamud.Interface.ImGuiNotification.IconSource;
|
||||
|
||||
/// <summary>Represents the use of a texture from a file as the icon of a notification.</summary>
|
||||
/// <remarks>If there was no texture loaded for any reason, the plugin icon will be displayed instead.</remarks>
|
||||
public readonly struct FilePathIconSource : INotificationIconSource.IInternal
|
||||
{
|
||||
/// <summary>The path to a .tex file inside the game resources.</summary>
|
||||
public readonly string FilePath;
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="FilePathIconSource"/> struct.</summary>
|
||||
/// <param name="filePath">The path to a .tex file inside the game resources.</param>
|
||||
public FilePathIconSource(string filePath) => this.FilePath = filePath;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public INotificationIconSource Clone() => this;
|
||||
|
||||
/// <inheritdoc/>
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
INotificationMaterializedIcon INotificationIconSource.IInternal.Materialize() =>
|
||||
new MaterializedIcon(this.FilePath);
|
||||
|
||||
private sealed class MaterializedIcon : INotificationMaterializedIcon
|
||||
{
|
||||
private readonly FileInfo fileInfo;
|
||||
|
||||
public MaterializedIcon(string filePath) => this.fileInfo = new(filePath);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public void DrawIcon(Vector2 minCoord, Vector2 maxCoord, Vector4 color, LocalPlugin? initiatorPlugin) =>
|
||||
NotificationUtilities.DrawTexture(
|
||||
Service<TextureManager>.Get().GetTextureFromFile(this.fileInfo),
|
||||
minCoord,
|
||||
maxCoord,
|
||||
initiatorPlugin);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
using System.Numerics;
|
||||
|
||||
using Dalamud.Interface.ImGuiNotification.Internal;
|
||||
using Dalamud.Plugin.Internal.Types;
|
||||
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.ImGuiNotification.IconSource;
|
||||
|
||||
/// <summary>Represents the use of <see cref="FontAwesomeIcon"/> as the icon of a notification.</summary>
|
||||
public readonly struct FontAwesomeIconIconSource : INotificationIconSource.IInternal
|
||||
{
|
||||
/// <summary>The icon character.</summary>
|
||||
public readonly FontAwesomeIcon Char;
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="FontAwesomeIconIconSource"/> struct.</summary>
|
||||
/// <param name="c">The character.</param>
|
||||
public FontAwesomeIconIconSource(FontAwesomeIcon c) => this.Char = c;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public INotificationIconSource Clone() => this;
|
||||
|
||||
/// <inheritdoc/>
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
INotificationMaterializedIcon INotificationIconSource.IInternal.Materialize() => new MaterializedIcon(this.Char);
|
||||
|
||||
/// <summary>Draws the icon.</summary>
|
||||
/// <param name="iconString">The icon string.</param>
|
||||
/// <param name="minCoord">The coordinates of the top left of the icon area.</param>
|
||||
/// <param name="maxCoord">The coordinates of the bottom right of the icon area.</param>
|
||||
/// <param name="color">The foreground color.</param>
|
||||
internal static void DrawIconStatic(string iconString, Vector2 minCoord, Vector2 maxCoord, Vector4 color)
|
||||
{
|
||||
using (Service<NotificationManager>.Get().IconFontAwesomeFontHandle.Push())
|
||||
{
|
||||
var size = ImGui.CalcTextSize(iconString);
|
||||
var pos = ((minCoord + maxCoord) - size) / 2;
|
||||
ImGui.SetCursorPos(pos);
|
||||
ImGui.PushStyleColor(ImGuiCol.Text, color);
|
||||
ImGui.TextUnformatted(iconString);
|
||||
ImGui.PopStyleColor();
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class MaterializedIcon : INotificationMaterializedIcon
|
||||
{
|
||||
private readonly string iconString;
|
||||
|
||||
public MaterializedIcon(FontAwesomeIcon c) => this.iconString = c.ToIconString();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public void DrawIcon(Vector2 minCoord, Vector2 maxCoord, Vector4 color, LocalPlugin? initiatorPlugin) =>
|
||||
DrawIconStatic(this.iconString, minCoord, maxCoord, color);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
using System.Numerics;
|
||||
|
||||
using Dalamud.Interface.ImGuiNotification.Internal;
|
||||
using Dalamud.Interface.Internal;
|
||||
using Dalamud.Plugin.Internal.Types;
|
||||
using Dalamud.Plugin.Services;
|
||||
|
||||
namespace Dalamud.Interface.ImGuiNotification.IconSource;
|
||||
|
||||
/// <summary>Represents the use of a game-shipped texture as the icon of a notification.</summary>
|
||||
/// <remarks>If there was no texture loaded for any reason, the plugin icon will be displayed instead.</remarks>
|
||||
public readonly struct GamePathIconSource : INotificationIconSource.IInternal
|
||||
{
|
||||
/// <summary>The path to a .tex file inside the game resources.</summary>
|
||||
public readonly string GamePath;
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="GamePathIconSource"/> struct.</summary>
|
||||
/// <param name="gamePath">The path to a .tex file inside the game resources.</param>
|
||||
/// <remarks>Use <see cref="ITextureProvider.GetIconPath"/> to get the game path from icon IDs.</remarks>
|
||||
public GamePathIconSource(string gamePath) => this.GamePath = gamePath;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public INotificationIconSource Clone() => this;
|
||||
|
||||
/// <inheritdoc/>
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
INotificationMaterializedIcon INotificationIconSource.IInternal.Materialize() =>
|
||||
new MaterializedIcon(this.GamePath);
|
||||
|
||||
private sealed class MaterializedIcon : INotificationMaterializedIcon
|
||||
{
|
||||
private readonly string gamePath;
|
||||
|
||||
public MaterializedIcon(string gamePath) => this.gamePath = gamePath;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public void DrawIcon(Vector2 minCoord, Vector2 maxCoord, Vector4 color, LocalPlugin? initiatorPlugin) =>
|
||||
NotificationUtilities.DrawTexture(
|
||||
Service<TextureManager>.Get().GetTextureFromGame(this.gamePath),
|
||||
minCoord,
|
||||
maxCoord,
|
||||
initiatorPlugin);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
using System.Numerics;
|
||||
|
||||
using Dalamud.Game.Text;
|
||||
using Dalamud.Interface.ImGuiNotification.Internal;
|
||||
using Dalamud.Plugin.Internal.Types;
|
||||
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.ImGuiNotification.IconSource;
|
||||
|
||||
/// <summary>Represents the use of <see cref="SeIconChar"/> as the icon of a notification.</summary>
|
||||
public readonly struct SeIconCharIconSource : INotificationIconSource.IInternal
|
||||
{
|
||||
/// <summary>The icon character.</summary>
|
||||
public readonly SeIconChar Char;
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="SeIconCharIconSource"/> struct.</summary>
|
||||
/// <param name="c">The character.</param>
|
||||
public SeIconCharIconSource(SeIconChar c) => this.Char = c;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public INotificationIconSource Clone() => this;
|
||||
|
||||
/// <inheritdoc/>
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
INotificationMaterializedIcon INotificationIconSource.IInternal.Materialize() => new MaterializedIcon(this.Char);
|
||||
|
||||
private sealed class MaterializedIcon : INotificationMaterializedIcon
|
||||
{
|
||||
private readonly string iconString;
|
||||
|
||||
public MaterializedIcon(SeIconChar c) => this.iconString = c.ToIconString();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public void DrawIcon(Vector2 minCoord, Vector2 maxCoord, Vector4 color, LocalPlugin? initiatorPlugin)
|
||||
{
|
||||
using (Service<NotificationManager>.Get().IconAxisFontHandle.Push())
|
||||
{
|
||||
var size = ImGui.CalcTextSize(this.iconString);
|
||||
var pos = ((minCoord + maxCoord) - size) / 2;
|
||||
ImGui.SetCursorPos(pos);
|
||||
ImGui.PushStyleColor(ImGuiCol.Text, color);
|
||||
ImGui.TextUnformatted(this.iconString);
|
||||
ImGui.PopStyleColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
using System.Numerics;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Dalamud.Interface.ImGuiNotification.Internal;
|
||||
using Dalamud.Interface.Internal;
|
||||
using Dalamud.Plugin.Internal.Types;
|
||||
using Dalamud.Utility;
|
||||
|
||||
namespace Dalamud.Interface.ImGuiNotification.IconSource;
|
||||
|
||||
/// <summary>Represents the use of future <see cref="IDalamudTextureWrap"/> as the icon of a notification.</summary>
|
||||
/// <remarks>If there was no texture loaded for any reason, the plugin icon will be displayed instead.</remarks>
|
||||
public readonly struct TextureWrapTaskIconSource : INotificationIconSource.IInternal
|
||||
{
|
||||
/// <summary>The function that returns a task resulting in a new instance of <see cref="IDalamudTextureWrap"/>.
|
||||
/// </summary>
|
||||
/// <remarks>Dalamud will take ownership of the result. Do not call <see cref="IDisposable.Dispose"/>.</remarks>
|
||||
public readonly Func<Task<IDalamudTextureWrap?>?>? TextureWrapTaskFunc;
|
||||
|
||||
/// <summary>Gets the default materialized icon, for the purpose of displaying the plugin icon.</summary>
|
||||
internal static readonly INotificationMaterializedIcon DefaultMaterializedIcon = new MaterializedIcon(null);
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="TextureWrapTaskIconSource"/> struct.</summary>
|
||||
/// <param name="taskFunc">The function.</param>
|
||||
public TextureWrapTaskIconSource(Func<Task<IDalamudTextureWrap?>?>? taskFunc) =>
|
||||
this.TextureWrapTaskFunc = taskFunc;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public INotificationIconSource Clone() => this;
|
||||
|
||||
/// <inheritdoc/>
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
INotificationMaterializedIcon INotificationIconSource.IInternal.Materialize() =>
|
||||
new MaterializedIcon(this.TextureWrapTaskFunc);
|
||||
|
||||
private sealed class MaterializedIcon : INotificationMaterializedIcon
|
||||
{
|
||||
private Task<IDalamudTextureWrap>? task;
|
||||
|
||||
public MaterializedIcon(Func<Task<IDalamudTextureWrap?>?>? taskFunc) => this.task = taskFunc?.Invoke();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
this.task?.ToContentDisposedTask(true);
|
||||
this.task = null;
|
||||
}
|
||||
|
||||
public void DrawIcon(Vector2 minCoord, Vector2 maxCoord, Vector4 color, LocalPlugin? initiatorPlugin) =>
|
||||
NotificationUtilities.DrawTexture(
|
||||
this.task?.IsCompletedSuccessfully is true ? this.task.Result : null,
|
||||
minCoord,
|
||||
maxCoord,
|
||||
initiatorPlugin);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +1,21 @@
|
|||
using System.Numerics;
|
||||
using System.Runtime.Loader;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Dalamud.Game.Text;
|
||||
using Dalamud.Interface.Animation;
|
||||
using Dalamud.Interface.Animation.EasingFunctions;
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.ImGuiNotification;
|
||||
using Dalamud.Interface.ImGuiNotification.Internal;
|
||||
using Dalamud.Interface.Internal.Windows;
|
||||
using Dalamud.Interface.ManagedFontAtlas;
|
||||
using Dalamud.Interface.ImGuiNotification.IconSource;
|
||||
using Dalamud.Interface.Internal;
|
||||
using Dalamud.Interface.Internal.Notifications;
|
||||
using Dalamud.Interface.Utility;
|
||||
using Dalamud.Plugin.Internal.Types;
|
||||
using Dalamud.Storage.Assets;
|
||||
using Dalamud.Utility;
|
||||
|
||||
using ImGuiNET;
|
||||
|
||||
using Serilog;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Notifications;
|
||||
namespace Dalamud.Interface.ImGuiNotification.Internal;
|
||||
|
||||
/// <summary>Represents an active notification.</summary>
|
||||
internal sealed class ActiveNotification : IActiveNotification, IDisposable
|
||||
|
|
@ -115,15 +111,15 @@ internal sealed class ActiveNotification : IActiveNotification, IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IActiveNotification.IconCreator"/>
|
||||
public Func<Task<object>>? IconCreator
|
||||
/// <inheritdoc cref="IActiveNotification.IconSource"/>
|
||||
public INotificationIconSource? IconSource
|
||||
{
|
||||
get => this.underlyingNotification.IconCreator;
|
||||
get => this.underlyingNotification.IconSource;
|
||||
set
|
||||
{
|
||||
if (this.IsDismissed)
|
||||
return;
|
||||
this.underlyingNotification.IconCreator = value;
|
||||
this.underlyingNotification.IconSource = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -192,7 +188,7 @@ internal sealed class ActiveNotification : IActiveNotification, IDisposable
|
|||
public LocalPlugin? InitiatorPlugin { get; set; }
|
||||
|
||||
/// <summary>Gets or sets the icon of this notification.</summary>
|
||||
public Task<object>? IconTask { get; set; }
|
||||
public INotificationMaterializedIcon? MaterializedIcon { get; set; }
|
||||
|
||||
/// <summary>Gets the eased progress.</summary>
|
||||
private float ProgressEased
|
||||
|
|
@ -255,7 +251,7 @@ internal sealed class ActiveNotification : IActiveNotification, IDisposable
|
|||
public void Dispose()
|
||||
{
|
||||
this.ClearIconTask();
|
||||
this.underlyingNotification.IconCreator = null;
|
||||
this.underlyingNotification.IconSource = null;
|
||||
this.Dismiss = null;
|
||||
this.Click = null;
|
||||
this.DrawActions = null;
|
||||
|
|
@ -487,7 +483,7 @@ internal sealed class ActiveNotification : IActiveNotification, IDisposable
|
|||
this.Content = newNotification.Content;
|
||||
this.Title = newNotification.Title;
|
||||
this.Type = newNotification.Type;
|
||||
this.IconCreator = newNotification.IconCreator;
|
||||
this.IconSource = newNotification.IconSource;
|
||||
this.Expiry = newNotification.Expiry;
|
||||
this.Interactible = newNotification.Interactible;
|
||||
this.HoverExtendDuration = newNotification.HoverExtendDuration;
|
||||
|
|
@ -500,7 +496,7 @@ internal sealed class ActiveNotification : IActiveNotification, IDisposable
|
|||
if (this.IsDismissed)
|
||||
return;
|
||||
this.ClearIconTask();
|
||||
this.IconTask = this.IconCreator?.Invoke();
|
||||
this.MaterializedIcon = (this.IconSource as INotificationIconSource.IInternal)?.Materialize();
|
||||
}
|
||||
|
||||
/// <summary>Removes non-Dalamud invocation targets from events.</summary>
|
||||
|
|
@ -546,20 +542,14 @@ internal sealed class ActiveNotification : IActiveNotification, IDisposable
|
|||
|
||||
private void ClearIconTask()
|
||||
{
|
||||
_ = this.IconTask?.ContinueWith(
|
||||
r =>
|
||||
{
|
||||
if (r.IsCompletedSuccessfully && r.Result is IDisposable d)
|
||||
d.Dispose();
|
||||
});
|
||||
this.IconTask = null;
|
||||
this.MaterializedIcon?.Dispose();
|
||||
this.MaterializedIcon = null;
|
||||
}
|
||||
|
||||
private void DrawNotificationMainWindowContent(NotificationManager notificationManager, float width)
|
||||
{
|
||||
var basePos = ImGui.GetCursorPos();
|
||||
this.DrawIcon(
|
||||
notificationManager,
|
||||
basePos,
|
||||
basePos + new Vector2(NotificationConstants.ScaledIconSize));
|
||||
basePos.X += NotificationConstants.ScaledIconSize + NotificationConstants.ScaledWindowPadding;
|
||||
|
|
@ -633,84 +623,26 @@ internal sealed class ActiveNotification : IActiveNotification, IDisposable
|
|||
ImGui.PopClipRect();
|
||||
}
|
||||
|
||||
private void DrawIcon(NotificationManager notificationManager, Vector2 minCoord, Vector2 maxCoord)
|
||||
private void DrawIcon(Vector2 minCoord, Vector2 maxCoord)
|
||||
{
|
||||
string? iconString = null;
|
||||
IFontHandle? fontHandle = null;
|
||||
IDalamudTextureWrap? iconTexture = null;
|
||||
switch (this.IconTask?.IsCompletedSuccessfully is true ? this.IconTask.Result : null)
|
||||
if (this.MaterializedIcon is not null)
|
||||
{
|
||||
case IDalamudTextureWrap wrap:
|
||||
iconTexture = wrap;
|
||||
break;
|
||||
case SeIconChar icon:
|
||||
iconString = string.Empty + (char)icon;
|
||||
fontHandle = notificationManager.IconAxisFontHandle;
|
||||
break;
|
||||
case FontAwesomeIcon icon:
|
||||
iconString = icon.ToIconString();
|
||||
fontHandle = notificationManager.IconFontAwesomeFontHandle;
|
||||
break;
|
||||
default:
|
||||
iconString = this.DefaultIconString;
|
||||
fontHandle = notificationManager.IconFontAwesomeFontHandle;
|
||||
break;
|
||||
this.MaterializedIcon.DrawIcon(minCoord, maxCoord, this.DefaultIconColor, this.InitiatorPlugin);
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(iconString))
|
||||
var defaultIconString = this.DefaultIconString;
|
||||
if (!string.IsNullOrWhiteSpace(defaultIconString))
|
||||
{
|
||||
var dam = Service<DalamudAssetManager>.Get();
|
||||
if (this.InitiatorPlugin is null)
|
||||
{
|
||||
iconTexture = dam.GetDalamudTextureWrap(DalamudAsset.LogoSmall);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Service<PluginImageCache>.Get().TryGetIcon(
|
||||
this.InitiatorPlugin,
|
||||
this.InitiatorPlugin.Manifest,
|
||||
this.InitiatorPlugin.IsThirdParty,
|
||||
out iconTexture) || iconTexture is null)
|
||||
{
|
||||
iconTexture = this.InitiatorPlugin switch
|
||||
{
|
||||
{ IsDev: true } => dam.GetDalamudTextureWrap(DalamudAsset.DevPluginIcon),
|
||||
{ IsThirdParty: true } => dam.GetDalamudTextureWrap(DalamudAsset.ThirdInstalledIcon),
|
||||
_ => dam.GetDalamudTextureWrap(DalamudAsset.InstalledIcon),
|
||||
};
|
||||
}
|
||||
}
|
||||
FontAwesomeIconIconSource.DrawIconStatic(defaultIconString, minCoord, maxCoord, this.DefaultIconColor);
|
||||
return;
|
||||
}
|
||||
|
||||
if (iconTexture is not null)
|
||||
{
|
||||
var size = iconTexture.Size;
|
||||
if (size.X > maxCoord.X - minCoord.X)
|
||||
size *= (maxCoord.X - minCoord.X) / size.X;
|
||||
if (size.Y > maxCoord.Y - minCoord.Y)
|
||||
size *= (maxCoord.Y - minCoord.Y) / size.Y;
|
||||
var pos = ((minCoord + maxCoord) - size) / 2;
|
||||
ImGui.SetCursorPos(pos);
|
||||
ImGui.Image(iconTexture.ImGuiHandle, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just making it extremely sure
|
||||
// ReSharper disable once ConditionIsAlwaysTrueOrFalse
|
||||
if (fontHandle is null || iconString is null)
|
||||
// ReSharper disable once HeuristicUnreachableCode
|
||||
return;
|
||||
|
||||
using (fontHandle.Push())
|
||||
{
|
||||
var size = ImGui.CalcTextSize(iconString);
|
||||
var pos = ((minCoord + maxCoord) - size) / 2;
|
||||
ImGui.SetCursorPos(pos);
|
||||
ImGui.PushStyleColor(ImGuiCol.Text, this.DefaultIconColor);
|
||||
ImGui.TextUnformatted(iconString);
|
||||
ImGui.PopStyleColor();
|
||||
}
|
||||
}
|
||||
TextureWrapTaskIconSource.DefaultMaterializedIcon.DrawIcon(
|
||||
minCoord,
|
||||
maxCoord,
|
||||
this.DefaultIconColor,
|
||||
this.InitiatorPlugin);
|
||||
}
|
||||
|
||||
private void DrawTitle(Vector2 minCoord, Vector2 maxCoord)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
using System.Numerics;
|
||||
|
||||
using Dalamud.Interface.Internal;
|
||||
using Dalamud.Interface.Internal.Windows;
|
||||
using Dalamud.Plugin.Internal.Types;
|
||||
using Dalamud.Storage.Assets;
|
||||
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.ImGuiNotification.Internal;
|
||||
|
||||
/// <summary>
|
||||
/// Utilities for implementing stuff under <see cref="ImGuiNotification"/>.
|
||||
/// </summary>
|
||||
internal static class NotificationUtilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Draws the given texture, or the icon of the plugin if texture is <c>null</c>.
|
||||
/// </summary>
|
||||
/// <param name="texture">The texture.</param>
|
||||
/// <param name="minCoord">The coordinates of the top left of the icon area.</param>
|
||||
/// <param name="maxCoord">The coordinates of the bottom right of the icon area.</param>
|
||||
/// <param name="initiatorPlugin">The initiator plugin.</param>
|
||||
public static void DrawTexture(
|
||||
IDalamudTextureWrap? texture,
|
||||
Vector2 minCoord,
|
||||
Vector2 maxCoord,
|
||||
LocalPlugin? initiatorPlugin)
|
||||
{
|
||||
if (texture is null)
|
||||
{
|
||||
var dam = Service<DalamudAssetManager>.Get();
|
||||
if (initiatorPlugin is null)
|
||||
{
|
||||
texture = dam.GetDalamudTextureWrap(DalamudAsset.LogoSmall);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Service<PluginImageCache>.Get().TryGetIcon(
|
||||
initiatorPlugin,
|
||||
initiatorPlugin.Manifest,
|
||||
initiatorPlugin.IsThirdParty,
|
||||
out texture) || texture is null)
|
||||
{
|
||||
texture = initiatorPlugin switch
|
||||
{
|
||||
{ IsDev: true } => dam.GetDalamudTextureWrap(DalamudAsset.DevPluginIcon),
|
||||
{ IsThirdParty: true } => dam.GetDalamudTextureWrap(DalamudAsset.ThirdInstalledIcon),
|
||||
_ => dam.GetDalamudTextureWrap(DalamudAsset.InstalledIcon),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var size = texture.Size;
|
||||
if (size.X > maxCoord.X - minCoord.X)
|
||||
size *= (maxCoord.X - minCoord.X) / size.X;
|
||||
if (size.Y > maxCoord.Y - minCoord.Y)
|
||||
size *= (maxCoord.Y - minCoord.Y) / size.Y;
|
||||
ImGui.SetCursorPos(((minCoord + maxCoord) - size) / 2);
|
||||
ImGui.Image(texture.ImGuiHandle, size);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
using Dalamud.Interface.ImGuiNotification.Internal;
|
||||
using Dalamud.Interface.Internal.Notifications;
|
||||
|
||||
|
|
@ -20,7 +18,7 @@ public sealed record Notification : INotification
|
|||
public NotificationType Type { get; set; } = NotificationType.None;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Func<Task<object>>? IconCreator { get; set; }
|
||||
public INotificationIconSource? IconSource { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public DateTime Expiry { get; set; } = DateTime.Now + NotificationConstants.DefaultDisplayDuration;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,13 @@
|
|||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Dalamud.Game.Text;
|
||||
using Dalamud.Interface.ImGuiNotification.IconSource;
|
||||
using Dalamud.Interface.ImGuiNotification.Internal;
|
||||
using Dalamud.Interface.Internal.Notifications;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using Dalamud.Storage.Assets;
|
||||
using Dalamud.Utility;
|
||||
|
||||
using ImGuiNET;
|
||||
|
||||
|
|
@ -66,6 +71,41 @@ internal class ImGuiWidget : IDataWindowWidget
|
|||
NotificationTemplate.TypeTitles,
|
||||
NotificationTemplate.TypeTitles.Length);
|
||||
|
||||
ImGui.Combo(
|
||||
"Icon Source##iconSourceCombo",
|
||||
ref this.notificationTemplate.IconSourceInt,
|
||||
NotificationTemplate.IconSourceTitles,
|
||||
NotificationTemplate.IconSourceTitles.Length);
|
||||
switch (this.notificationTemplate.IconSourceInt)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
ImGui.InputText(
|
||||
"Icon Text##iconSourceText",
|
||||
ref this.notificationTemplate.IconSourceText,
|
||||
255);
|
||||
break;
|
||||
case 3:
|
||||
ImGui.Combo(
|
||||
"Icon Source##iconSourceAssetCombo",
|
||||
ref this.notificationTemplate.IconSourceAssetInt,
|
||||
NotificationTemplate.AssetSources,
|
||||
NotificationTemplate.AssetSources.Length);
|
||||
break;
|
||||
case 4:
|
||||
ImGui.InputText(
|
||||
"Game Path##iconSourceText",
|
||||
ref this.notificationTemplate.IconSourceText,
|
||||
255);
|
||||
break;
|
||||
case 5:
|
||||
ImGui.InputText(
|
||||
"File Path##iconSourceText",
|
||||
ref this.notificationTemplate.IconSourceText,
|
||||
255);
|
||||
break;
|
||||
}
|
||||
|
||||
ImGui.Combo(
|
||||
"Duration",
|
||||
ref this.notificationTemplate.DurationInt,
|
||||
|
|
@ -114,6 +154,26 @@ internal class ImGuiWidget : IDataWindowWidget
|
|||
4 => -1f,
|
||||
_ => 0.5f,
|
||||
},
|
||||
IconSource = this.notificationTemplate.IconSourceInt switch
|
||||
{
|
||||
1 => new SeIconCharIconSource(
|
||||
(SeIconChar)(this.notificationTemplate.IconSourceText.Length == 0
|
||||
? 0
|
||||
: this.notificationTemplate.IconSourceText[0])),
|
||||
2 => new FontAwesomeIconIconSource(
|
||||
(FontAwesomeIcon)(this.notificationTemplate.IconSourceText.Length == 0
|
||||
? 0
|
||||
: this.notificationTemplate.IconSourceText[0])),
|
||||
3 => new TextureWrapTaskIconSource(
|
||||
() =>
|
||||
Service<DalamudAssetManager>.Get().GetDalamudTextureWrapAsync(
|
||||
Enum.Parse<DalamudAsset>(
|
||||
NotificationTemplate.AssetSources[
|
||||
this.notificationTemplate.IconSourceAssetInt]))),
|
||||
4 => new GamePathIconSource(this.notificationTemplate.IconSourceText),
|
||||
5 => new FilePathIconSource(this.notificationTemplate.IconSourceText),
|
||||
_ => null,
|
||||
},
|
||||
});
|
||||
switch (this.notificationTemplate.ProgressMode)
|
||||
{
|
||||
|
|
@ -205,6 +265,22 @@ internal class ImGuiWidget : IDataWindowWidget
|
|||
|
||||
private struct NotificationTemplate
|
||||
{
|
||||
public static readonly string[] IconSourceTitles =
|
||||
{
|
||||
"None (use Type)",
|
||||
"SeIconChar",
|
||||
"FontAwesomeIcon",
|
||||
"TextureWrapTask from DalamudAssets",
|
||||
"GamePath",
|
||||
"FilePath",
|
||||
};
|
||||
|
||||
public static readonly string[] AssetSources =
|
||||
Enum.GetValues<DalamudAsset>()
|
||||
.Where(x => x.GetAttribute<DalamudAssetAttribute>()?.Purpose is DalamudAssetPurpose.TextureFromPng)
|
||||
.Select(Enum.GetName)
|
||||
.ToArray();
|
||||
|
||||
public static readonly string[] ProgressModeTitles =
|
||||
{
|
||||
"Default",
|
||||
|
|
@ -243,6 +319,9 @@ internal class ImGuiWidget : IDataWindowWidget
|
|||
public string Content;
|
||||
public bool ManualTitle;
|
||||
public string Title;
|
||||
public int IconSourceInt;
|
||||
public string IconSourceText;
|
||||
public int IconSourceAssetInt;
|
||||
public bool ManualType;
|
||||
public int TypeInt;
|
||||
public int DurationInt;
|
||||
|
|
@ -256,6 +335,9 @@ internal class ImGuiWidget : IDataWindowWidget
|
|||
this.Content = string.Empty;
|
||||
this.ManualTitle = false;
|
||||
this.Title = string.Empty;
|
||||
this.IconSourceInt = 0;
|
||||
this.IconSourceText = "ui/icon/000000/000004_hr1.tex";
|
||||
this.IconSourceAssetInt = 0;
|
||||
this.ManualType = false;
|
||||
this.TypeInt = (int)NotificationType.None;
|
||||
this.DurationInt = 2;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue