mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-14 20:54:16 +01:00
add special indicator for testing and testing-exclusive plugins
This commit is contained in:
parent
33b64e783c
commit
8f36641f36
1 changed files with 95 additions and 19 deletions
|
|
@ -207,6 +207,19 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
EnabledDisabled,
|
EnabledDisabled,
|
||||||
ProfileOrNot,
|
ProfileOrNot,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
private enum PluginHeaderFlags
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
IsThirdParty = 1 << 0,
|
||||||
|
HasTrouble = 1 << 1,
|
||||||
|
UpdateAvailable = 1 << 2,
|
||||||
|
IsNew = 1 << 3,
|
||||||
|
IsInstallableOutdated = 1 << 4,
|
||||||
|
IsOrphan = 1 << 5,
|
||||||
|
IsTesting = 1 << 6,
|
||||||
|
}
|
||||||
|
|
||||||
private bool AnyOperationInProgress => this.installStatus == OperationStatus.InProgress ||
|
private bool AnyOperationInProgress => this.installStatus == OperationStatus.InProgress ||
|
||||||
this.updateStatus == OperationStatus.InProgress ||
|
this.updateStatus == OperationStatus.InProgress ||
|
||||||
|
|
@ -1778,22 +1791,62 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
return ready;
|
return ready;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool DrawPluginCollapsingHeader(string label, LocalPlugin? plugin, IPluginManifest manifest, bool isThirdParty, bool trouble, bool updateAvailable, bool isNew, bool installableOutdated, bool isOrphan, Action drawContextMenuAction, int index)
|
private bool DrawPluginCollapsingHeader(string label, LocalPlugin? plugin, IPluginManifest manifest, PluginHeaderFlags flags, Action drawContextMenuAction, int index)
|
||||||
{
|
{
|
||||||
ImGui.Separator();
|
|
||||||
|
|
||||||
var isOpen = this.openPluginCollapsibles.Contains(index);
|
var isOpen = this.openPluginCollapsibles.Contains(index);
|
||||||
|
|
||||||
var sectionSize = ImGuiHelpers.GlobalScale * 66;
|
var sectionSize = ImGuiHelpers.GlobalScale * 66;
|
||||||
|
var tapeCursor = ImGui.GetCursorPos();
|
||||||
|
|
||||||
|
ImGui.Separator();
|
||||||
|
|
||||||
var startCursor = ImGui.GetCursorPos();
|
var startCursor = ImGui.GetCursorPos();
|
||||||
|
|
||||||
|
if (flags.HasFlag(PluginHeaderFlags.IsTesting))
|
||||||
|
{
|
||||||
|
void DrawCautionTape(Vector2 position, Vector2 size, float stripeWidth, float skewAmount)
|
||||||
|
{
|
||||||
|
var wdl = ImGui.GetWindowDrawList();
|
||||||
|
|
||||||
|
var windowPos = ImGui.GetWindowPos();
|
||||||
|
var scroll = new Vector2(ImGui.GetScrollX(), ImGui.GetScrollY());
|
||||||
|
|
||||||
|
var adjustedPosition = windowPos + position - scroll;
|
||||||
|
|
||||||
|
var yellow = ImGui.ColorConvertFloat4ToU32(new Vector4(1.0f, 0.9f, 0.0f, 0.10f));
|
||||||
|
var numStripes = (int)(size.X / stripeWidth) + (int)(size.Y / skewAmount) + 1; // +1 to cover partial stripe
|
||||||
|
|
||||||
|
for (var i = 0; i < numStripes; i++)
|
||||||
|
{
|
||||||
|
var x0 = adjustedPosition.X + i * stripeWidth;
|
||||||
|
var x1 = x0 + stripeWidth;
|
||||||
|
var y0 = adjustedPosition.Y;
|
||||||
|
var y1 = y0 + size.Y;
|
||||||
|
|
||||||
|
var p0 = new Vector2(x0, y0);
|
||||||
|
var p1 = new Vector2(x1, y0);
|
||||||
|
var p2 = new Vector2(x1 - skewAmount, y1);
|
||||||
|
var p3 = new Vector2(x0 - skewAmount, y1);
|
||||||
|
|
||||||
|
if (i % 2 != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
wdl.AddQuadFilled(p0, p1, p2, p3, yellow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawCautionTape(tapeCursor + new Vector2(0, 1), new Vector2(ImGui.GetWindowWidth(), sectionSize + ImGui.GetStyle().ItemSpacing.Y), ImGuiHelpers.GlobalScale * 40, 20);
|
||||||
|
}
|
||||||
|
|
||||||
ImGui.PushStyleColor(ImGuiCol.Button, isOpen ? new Vector4(0.5f, 0.5f, 0.5f, 0.1f) : Vector4.Zero);
|
ImGui.PushStyleColor(ImGuiCol.Button, isOpen ? new Vector4(0.5f, 0.5f, 0.5f, 0.1f) : Vector4.Zero);
|
||||||
|
|
||||||
ImGui.PushStyleColor(ImGuiCol.ButtonHovered, new Vector4(0.5f, 0.5f, 0.5f, 0.2f));
|
ImGui.PushStyleColor(ImGuiCol.ButtonHovered, new Vector4(0.5f, 0.5f, 0.5f, 0.2f));
|
||||||
ImGui.PushStyleColor(ImGuiCol.ButtonActive, new Vector4(0.5f, 0.5f, 0.5f, 0.35f));
|
ImGui.PushStyleColor(ImGuiCol.ButtonActive, new Vector4(0.5f, 0.5f, 0.5f, 0.35f));
|
||||||
ImGui.PushStyleVar(ImGuiStyleVar.FrameRounding, 0);
|
ImGui.PushStyleVar(ImGuiStyleVar.FrameRounding, 0);
|
||||||
|
|
||||||
|
ImGui.SetCursorPos(tapeCursor);
|
||||||
|
|
||||||
if (ImGui.Button($"###plugin{index}CollapsibleBtn", new Vector2(ImGui.GetContentRegionAvail().X, sectionSize)))
|
if (ImGui.Button($"###plugin{index}CollapsibleBtn", new Vector2(ImGui.GetContentRegionAvail().X, sectionSize + ImGui.GetStyle().ItemSpacing.Y)))
|
||||||
{
|
{
|
||||||
if (isOpen)
|
if (isOpen)
|
||||||
{
|
{
|
||||||
|
|
@ -1825,7 +1878,7 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
if (ImGui.IsRectVisible(rectOffset + cursorBeforeImage, rectOffset + cursorBeforeImage + iconSize))
|
if (ImGui.IsRectVisible(rectOffset + cursorBeforeImage, rectOffset + cursorBeforeImage + iconSize))
|
||||||
{
|
{
|
||||||
var iconTex = this.imageCache.DefaultIcon;
|
var iconTex = this.imageCache.DefaultIcon;
|
||||||
var hasIcon = this.imageCache.TryGetIcon(plugin, manifest, isThirdParty, out var cachedIconTex, out var loadedSince);
|
var hasIcon = this.imageCache.TryGetIcon(plugin, manifest, flags.HasFlag(PluginHeaderFlags.IsThirdParty), out var cachedIconTex, out var loadedSince);
|
||||||
if (hasIcon && cachedIconTex != null)
|
if (hasIcon && cachedIconTex != null)
|
||||||
{
|
{
|
||||||
iconTex = cachedIconTex;
|
iconTex = cachedIconTex;
|
||||||
|
|
@ -1839,7 +1892,7 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
float EaseOutCubic(float t) => 1 - MathF.Pow(1 - t, 3);
|
float EaseOutCubic(float t) => 1 - MathF.Pow(1 - t, 3);
|
||||||
|
|
||||||
var secondsSinceLoad = (float)DateTime.Now.Subtract(loadedSince.Value).TotalSeconds;
|
var secondsSinceLoad = (float)DateTime.Now.Subtract(loadedSince.Value).TotalSeconds;
|
||||||
var fadeTo = pluginDisabled || installableOutdated ? 0.4f : 1f;
|
var fadeTo = pluginDisabled || flags.HasFlag(PluginHeaderFlags.IsInstallableOutdated) ? 0.4f : 1f;
|
||||||
|
|
||||||
float Interp(float to) => Math.Clamp(EaseOutCubic(Math.Min(secondsSinceLoad, fadeTime) / fadeTime) * to, 0, 1);
|
float Interp(float to) => Math.Clamp(EaseOutCubic(Math.Min(secondsSinceLoad, fadeTime) / fadeTime) * to, 0, 1);
|
||||||
iconAlpha = Interp(fadeTo);
|
iconAlpha = Interp(fadeTo);
|
||||||
|
|
@ -1857,11 +1910,11 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
var isLoaded = plugin is { IsLoaded: true };
|
var isLoaded = plugin is { IsLoaded: true };
|
||||||
|
|
||||||
ImGui.PushStyleVar(ImGuiStyleVar.Alpha, overlayAlpha);
|
ImGui.PushStyleVar(ImGuiStyleVar.Alpha, overlayAlpha);
|
||||||
if (updateAvailable)
|
if (flags.HasFlag(PluginHeaderFlags.UpdateAvailable))
|
||||||
ImGui.Image(this.imageCache.UpdateIcon.ImGuiHandle, iconSize);
|
ImGui.Image(this.imageCache.UpdateIcon.ImGuiHandle, iconSize);
|
||||||
else if ((trouble && !pluginDisabled) || isOrphan)
|
else if ((flags.HasFlag(PluginHeaderFlags.HasTrouble) && !pluginDisabled) || flags.HasFlag(PluginHeaderFlags.IsOrphan))
|
||||||
ImGui.Image(this.imageCache.TroubleIcon.ImGuiHandle, iconSize);
|
ImGui.Image(this.imageCache.TroubleIcon.ImGuiHandle, iconSize);
|
||||||
else if (installableOutdated)
|
else if (flags.HasFlag(PluginHeaderFlags.IsInstallableOutdated))
|
||||||
ImGui.Image(this.imageCache.OutdatedInstallableIcon.ImGuiHandle, iconSize);
|
ImGui.Image(this.imageCache.OutdatedInstallableIcon.ImGuiHandle, iconSize);
|
||||||
else if (pluginDisabled)
|
else if (pluginDisabled)
|
||||||
ImGui.Image(this.imageCache.DisabledIcon.ImGuiHandle, iconSize);
|
ImGui.Image(this.imageCache.DisabledIcon.ImGuiHandle, iconSize);
|
||||||
|
|
@ -1905,7 +1958,7 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
this.DrawFontawesomeIconOutlined(FontAwesomeIcon.Wrench, devIconOutlineColor, devIconColor);
|
this.DrawFontawesomeIconOutlined(FontAwesomeIcon.Wrench, devIconOutlineColor, devIconColor);
|
||||||
this.VerifiedCheckmarkFadeTooltip(label, "This is a dev plugin. You added it.");
|
this.VerifiedCheckmarkFadeTooltip(label, "This is a dev plugin. You added it.");
|
||||||
}
|
}
|
||||||
else if (!isThirdParty)
|
else if (!flags.HasFlag(PluginHeaderFlags.IsThirdParty))
|
||||||
{
|
{
|
||||||
this.DrawFontawesomeIconOutlined(FontAwesomeIcon.CheckCircle, verifiedOutlineColor, verifiedIconColor);
|
this.DrawFontawesomeIconOutlined(FontAwesomeIcon.CheckCircle, verifiedOutlineColor, verifiedIconColor);
|
||||||
this.VerifiedCheckmarkFadeTooltip(label, Locs.VerifiedCheckmark_VerifiedTooltip);
|
this.VerifiedCheckmarkFadeTooltip(label, Locs.VerifiedCheckmark_VerifiedTooltip);
|
||||||
|
|
@ -1925,7 +1978,7 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
ImGui.TextColored(ImGuiColors.DalamudGrey3, downloadCountText);
|
ImGui.TextColored(ImGuiColors.DalamudGrey3, downloadCountText);
|
||||||
|
|
||||||
if (isNew)
|
if (flags.HasFlag(PluginHeaderFlags.IsNew))
|
||||||
{
|
{
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
ImGui.TextColored(ImGuiColors.TankBlue, Locs.PluginTitleMod_New);
|
ImGui.TextColored(ImGuiColors.TankBlue, Locs.PluginTitleMod_New);
|
||||||
|
|
@ -1935,12 +1988,12 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
ImGui.SetCursorPos(cursor);
|
ImGui.SetCursorPos(cursor);
|
||||||
|
|
||||||
// Outdated warning
|
// Outdated warning
|
||||||
if (plugin is { IsOutdated: true, IsBanned: false } || installableOutdated)
|
if (plugin is { IsOutdated: true, IsBanned: false } || flags.HasFlag(PluginHeaderFlags.IsInstallableOutdated))
|
||||||
{
|
{
|
||||||
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed);
|
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed);
|
||||||
|
|
||||||
var bodyText = Locs.PluginBody_Outdated + " ";
|
var bodyText = Locs.PluginBody_Outdated + " ";
|
||||||
if (updateAvailable)
|
if (flags.HasFlag(PluginHeaderFlags.UpdateAvailable))
|
||||||
bodyText += Locs.PluginBody_Outdated_CanNowUpdate;
|
bodyText += Locs.PluginBody_Outdated_CanNowUpdate;
|
||||||
else
|
else
|
||||||
bodyText += Locs.PluginBody_Outdated_WaitForUpdate;
|
bodyText += Locs.PluginBody_Outdated_WaitForUpdate;
|
||||||
|
|
@ -1958,7 +2011,7 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
: Locs.PluginBody_BannedReason(plugin.BanReason);
|
: Locs.PluginBody_BannedReason(plugin.BanReason);
|
||||||
bodyText += " ";
|
bodyText += " ";
|
||||||
|
|
||||||
if (updateAvailable)
|
if (flags.HasFlag(PluginHeaderFlags.UpdateAvailable))
|
||||||
bodyText += Locs.PluginBody_Outdated_CanNowUpdate;
|
bodyText += Locs.PluginBody_Outdated_CanNowUpdate;
|
||||||
else
|
else
|
||||||
bodyText += Locs.PluginBody_Outdated_WaitForUpdate;
|
bodyText += Locs.PluginBody_Outdated_WaitForUpdate;
|
||||||
|
|
@ -2002,7 +2055,7 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
ImGui.SetCursorPosX(cursor.X);
|
ImGui.SetCursorPosX(cursor.X);
|
||||||
|
|
||||||
// Description
|
// Description
|
||||||
if (plugin is null or { IsOutdated: false, IsBanned: false } && !trouble)
|
if (plugin is null or { IsOutdated: false, IsBanned: false } && !flags.HasFlag(PluginHeaderFlags.HasTrouble))
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrWhiteSpace(manifest.Punchline))
|
if (!string.IsNullOrWhiteSpace(manifest.Punchline))
|
||||||
{
|
{
|
||||||
|
|
@ -2123,11 +2176,22 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
{
|
{
|
||||||
label += Locs.PluginTitleMod_TestingAvailable;
|
label += Locs.PluginTitleMod_TestingAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isThirdParty = manifest.SourceRepo.IsThirdParty;
|
||||||
|
|
||||||
ImGui.PushID($"available{index}{manifest.InternalName}");
|
ImGui.PushID($"available{index}{manifest.InternalName}");
|
||||||
|
|
||||||
var isThirdParty = manifest.SourceRepo.IsThirdParty;
|
var flags = PluginHeaderFlags.None;
|
||||||
if (this.DrawPluginCollapsingHeader(label, null, manifest, isThirdParty, false, false, !wasSeen, isOutdated, false, () => this.DrawAvailablePluginContextMenu(manifest), index))
|
if (isThirdParty)
|
||||||
|
flags |= PluginHeaderFlags.IsThirdParty;
|
||||||
|
if (!wasSeen)
|
||||||
|
flags |= PluginHeaderFlags.IsNew;
|
||||||
|
if (isOutdated)
|
||||||
|
flags |= PluginHeaderFlags.IsInstallableOutdated;
|
||||||
|
if (useTesting || manifest.IsTestingExclusive)
|
||||||
|
flags |= PluginHeaderFlags.IsTesting;
|
||||||
|
|
||||||
|
if (this.DrawPluginCollapsingHeader(label, null, manifest, flags, () => this.DrawAvailablePluginContextMenu(manifest), index))
|
||||||
{
|
{
|
||||||
if (!wasSeen)
|
if (!wasSeen)
|
||||||
configuration.SeenPluginInternalName.Add(manifest.InternalName);
|
configuration.SeenPluginInternalName.Add(manifest.InternalName);
|
||||||
|
|
@ -2391,7 +2455,19 @@ internal class PluginInstallerWindow : Window, IDisposable
|
||||||
var hasChangelog = !applicableChangelog.IsNullOrWhitespace();
|
var hasChangelog = !applicableChangelog.IsNullOrWhitespace();
|
||||||
var didDrawChangelogInsideCollapsible = false;
|
var didDrawChangelogInsideCollapsible = false;
|
||||||
|
|
||||||
if (this.DrawPluginCollapsingHeader(label, plugin, plugin.Manifest, plugin.IsThirdParty, trouble, availablePluginUpdate != default, false, false, plugin.IsOrphaned, () => this.DrawInstalledPluginContextMenu(plugin, testingOptIn), index))
|
var flags = PluginHeaderFlags.None;
|
||||||
|
if (plugin.IsThirdParty)
|
||||||
|
flags |= PluginHeaderFlags.IsThirdParty;
|
||||||
|
if (trouble)
|
||||||
|
flags |= PluginHeaderFlags.HasTrouble;
|
||||||
|
if (availablePluginUpdate != default)
|
||||||
|
flags |= PluginHeaderFlags.UpdateAvailable;
|
||||||
|
if (plugin.IsOrphaned)
|
||||||
|
flags |= PluginHeaderFlags.IsOrphan;
|
||||||
|
if (plugin.IsTesting)
|
||||||
|
flags |= PluginHeaderFlags.IsTesting;
|
||||||
|
|
||||||
|
if (this.DrawPluginCollapsingHeader(label, plugin, plugin.Manifest, flags, () => this.DrawInstalledPluginContextMenu(plugin, testingOptIn), index))
|
||||||
{
|
{
|
||||||
if (!this.WasPluginSeen(plugin.Manifest.InternalName))
|
if (!this.WasPluginSeen(plugin.Manifest.InternalName))
|
||||||
configuration.SeenPluginInternalName.Add(plugin.Manifest.InternalName);
|
configuration.SeenPluginInternalName.Add(plugin.Manifest.InternalName);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue