feat(honorific): render glow outline as opt-in (gradient deferred)

Honorific's TitleData carries Glow / Color3 / GradientColourSet /
GradientAnimationStyle beyond the Title + Color we parsed in Cycle 1.
The DTO now mirrors all four so the JSON roundtrip doesn't silently
drop fields.

Rendering for v1.4.7 covers Glow only: when Config.ShowHonorificGlow
is on and the title has a Glow colour, the chat header title gets an
8-direction ±1px draw-list outline pre-pass in the glow colour at 0.4
alpha, then the primary text on top.

Gradient (Color3 / GradientColourSet / GradientAnimationStyle) is parsed
and stashed for a later cycle — porting the full animation needs
Honorific's hardcoded Pride-palette list and GradientSystem.cs (or an
upstream IPC PR exposing the resolved frame colour). Tracked as
"Honorific Full Gradient Port" in the vault backlog.

ShowHonorificGlow defaults OFF — keeps v1.4.6 visuals untouched and
dodges per-frame DrawList overhead on low-end hardware. Tooltip flags
the gradient deferral so users aren't surprised by static rendering.
This commit is contained in:
2026-05-13 09:34:43 +02:00
parent fd5f970a8b
commit 69fa0fecbd
7 changed files with 74 additions and 6 deletions
+8
View File
@@ -102,6 +102,13 @@ public class Configuration : IPluginConfiguration
public bool FirstRunCompleted; public bool FirstRunCompleted;
public bool UseHellionFont = true; public bool UseHellionFont = true;
public bool ShowHonorificTitleInHeader = true; public bool ShowHonorificTitleInHeader = true;
// v1.4.7 opt-in: renders the Honorific glow outline when the title carries
// a Glow colour. Default OFF — keeps v1.4.6 visuals untouched for users
// who don't care, and dodges the per-frame DrawList overhead on low-end
// hardware. Gradient (Color3 / GradientColourSet) is parsed but rendered
// as the primary Color until a later cycle ports the animation.
public bool ShowHonorificGlow;
public bool EnableAutoTellTabs = true; public bool EnableAutoTellTabs = true;
public int AutoTellTabsLimit = 15; public int AutoTellTabsLimit = 15;
public bool AutoTellTabsCompactDisplay; public bool AutoTellTabsCompactDisplay;
@@ -320,6 +327,7 @@ public class Configuration : IPluginConfiguration
FirstRunCompleted = other.FirstRunCompleted; FirstRunCompleted = other.FirstRunCompleted;
UseHellionFont = other.UseHellionFont; UseHellionFont = other.UseHellionFont;
ShowHonorificTitleInHeader = other.ShowHonorificTitleInHeader; ShowHonorificTitleInHeader = other.ShowHonorificTitleInHeader;
ShowHonorificGlow = other.ShowHonorificGlow;
// v1.1.0 theme engine fields // v1.1.0 theme engine fields
Theme = other.Theme; Theme = other.Theme;
+11 -2
View File
@@ -4,10 +4,19 @@ namespace HellionChat.Integrations;
// Local DTO mirroring Honorific's TitleData — no hard reference to Honorific.dll // Local DTO mirroring Honorific's TitleData — no hard reference to Honorific.dll
// so HellionChat loads cleanly when Honorific is absent. // so HellionChat loads cleanly when Honorific is absent.
// Glow/gradient fields omitted; Cycle 1 renders primary Color only. //
// v1.4.7: render Glow only. Gradient (Color3 / GradientColourSet / Style) is
// parsed and stashed so a future cycle can render it without re-shaping the
// JSON roundtrip — see vault anchor "Honorific Full Gradient Port" (would
// need GradientSystem.cs + the hardcoded Pride-palette list ported, or an
// upstream IPC PR exposing the resolved frame colour).
internal sealed record HonorificTitleData( internal sealed record HonorificTitleData(
string? Title, string? Title,
bool IsPrefix, bool IsPrefix,
bool IsOriginal, bool IsOriginal,
Vector3? Color Vector3? Color,
Vector3? Glow,
Vector3? Color3,
int? GradientColourSet,
string? GradientAnimationStyle
); );
+2
View File
@@ -376,6 +376,8 @@ internal class HellionStrings
internal static string Settings_Integrations_Honorific_Status_Incompatible => Get(nameof(Settings_Integrations_Honorific_Status_Incompatible)); internal static string Settings_Integrations_Honorific_Status_Incompatible => Get(nameof(Settings_Integrations_Honorific_Status_Incompatible));
internal static string Settings_Integrations_Honorific_Toggle => Get(nameof(Settings_Integrations_Honorific_Toggle)); internal static string Settings_Integrations_Honorific_Toggle => Get(nameof(Settings_Integrations_Honorific_Toggle));
internal static string Settings_Integrations_Honorific_ToggleHint => Get(nameof(Settings_Integrations_Honorific_ToggleHint)); internal static string Settings_Integrations_Honorific_ToggleHint => Get(nameof(Settings_Integrations_Honorific_ToggleHint));
internal static string Settings_Integrations_Honorific_Glow_Toggle => Get(nameof(Settings_Integrations_Honorific_Glow_Toggle));
internal static string Settings_Integrations_Honorific_Glow_Hint => Get(nameof(Settings_Integrations_Honorific_Glow_Hint));
internal static string Settings_Integrations_Honorific_LinkRepo => Get(nameof(Settings_Integrations_Honorific_LinkRepo)); internal static string Settings_Integrations_Honorific_LinkRepo => Get(nameof(Settings_Integrations_Honorific_LinkRepo));
internal static string Settings_Integrations_Honorific_LinkAuthor => Get(nameof(Settings_Integrations_Honorific_LinkAuthor)); internal static string Settings_Integrations_Honorific_LinkAuthor => Get(nameof(Settings_Integrations_Honorific_LinkAuthor));
internal static string Settings_Integrations_ComingSoon_SectionHeader => Get(nameof(Settings_Integrations_ComingSoon_SectionHeader)); internal static string Settings_Integrations_ComingSoon_SectionHeader => Get(nameof(Settings_Integrations_ComingSoon_SectionHeader));
@@ -845,6 +845,12 @@
<data name="Settings_Integrations_Honorific_ToggleHint" xml:space="preserve"> <data name="Settings_Integrations_Honorific_ToggleHint" xml:space="preserve">
<value>Zeigt deinen Custom-Titel aus Honorific im Header über dem Chat-Log an, in der von dir gewählten Farbe.</value> <value>Zeigt deinen Custom-Titel aus Honorific im Header über dem Chat-Log an, in der von dir gewählten Farbe.</value>
</data> </data>
<data name="Settings_Integrations_Honorific_Glow_Toggle" xml:space="preserve">
<value>Glow-Outline rendern (Honorific)</value>
</data>
<data name="Settings_Integrations_Honorific_Glow_Hint" xml:space="preserve">
<value>Kann die Framerate auf schwacher Hardware drücken. Rendert die Glow-Outline für Honorific-Titel, die sie nutzen. Gradient-Animation wird noch nicht unterstützt und wird stattdessen als Primärfarbe gezeichnet.</value>
</data>
<data name="Settings_Integrations_Honorific_LinkRepo" xml:space="preserve"> <data name="Settings_Integrations_Honorific_LinkRepo" xml:space="preserve">
<value>Honorific auf GitHub</value> <value>Honorific auf GitHub</value>
</data> </data>
@@ -845,6 +845,12 @@
<data name="Settings_Integrations_Honorific_ToggleHint" xml:space="preserve"> <data name="Settings_Integrations_Honorific_ToggleHint" xml:space="preserve">
<value>Shows your custom title from Honorific in the header above the chat log, in the colour you have chosen.</value> <value>Shows your custom title from Honorific in the header above the chat log, in the colour you have chosen.</value>
</data> </data>
<data name="Settings_Integrations_Honorific_Glow_Toggle" xml:space="preserve">
<value>Render glow outlines (Honorific)</value>
</data>
<data name="Settings_Integrations_Honorific_Glow_Hint" xml:space="preserve">
<value>May reduce frame rate on low-end hardware. Renders glow outlines for Honorific titles that use them. Gradient animation is not yet supported and will render as the primary colour.</value>
</data>
<data name="Settings_Integrations_Honorific_LinkRepo" xml:space="preserve"> <data name="Settings_Integrations_Honorific_LinkRepo" xml:space="preserve">
<value>Honorific on GitHub</value> <value>Honorific on GitHub</value>
</data> </data>
+30 -4
View File
@@ -1999,10 +1999,7 @@ public sealed class ChatLogWindow : Window
ImGui.TextUnformatted(FontAwesomeIcon.Crown.ToIconString()); ImGui.TextUnformatted(FontAwesomeIcon.Crown.ToIconString());
} }
ImGui.SameLine(0f, gapAfterCrown); ImGui.SameLine(0f, gapAfterCrown);
using (ImRaii.PushColor(ImGuiCol.Text, titleColor)) DrawHonorificTitleText(rendered, titleColor, title.Glow);
{
ImGui.TextUnformatted(rendered);
}
ImGui.EndGroup(); ImGui.EndGroup();
if (ImGui.IsItemHovered()) if (ImGui.IsItemHovered())
@@ -2013,6 +2010,35 @@ public sealed class ChatLogWindow : Window
ImGui.SameLine(); ImGui.SameLine();
} }
// Renders the title text, optionally with a glow outline pre-pass. Glow is
// drawn at 8 cardinal offsets (±1 px) in the glow colour at reduced alpha,
// then the primary text on top. The pre-pass uses the window draw list so
// it composites correctly with the regular ImGui text that follows.
private void DrawHonorificTitleText(string rendered, Vector4 titleColor, Vector3? glow)
{
if (Plugin.Config.ShowHonorificGlow && glow is { } g)
{
var pos = ImGui.GetCursorScreenPos();
var glowColor = new Vector4(g.X, g.Y, g.Z, 0.4f);
var glowAbgr = ImGui.ColorConvertFloat4ToU32(glowColor);
var drawList = ImGui.GetWindowDrawList();
for (var dy = -1; dy <= 1; dy++)
{
for (var dx = -1; dx <= 1; dx++)
{
if (dx == 0 && dy == 0)
continue;
drawList.AddText(new Vector2(pos.X + dx, pos.Y + dy), glowAbgr, rendered);
}
}
}
using (ImRaii.PushColor(ImGuiCol.Text, titleColor))
{
ImGui.TextUnformatted(rendered);
}
}
// One-time hint banner for the pop-out header button and right-click pathway. // One-time hint banner for the pop-out header button and right-click pathway.
private float DrawV061HintBannerIfNeeded() private float DrawV061HintBannerIfNeeded()
{ {
@@ -71,6 +71,17 @@ internal sealed class Integrations : ISettingsTab
{ {
ImGui.TextWrapped(HellionStrings.Settings_Integrations_Honorific_ToggleHint); ImGui.TextWrapped(HellionStrings.Settings_Integrations_Honorific_ToggleHint);
} }
if (
ImGui.Checkbox(
HellionStrings.Settings_Integrations_Honorific_Glow_Toggle,
ref Mutable.ShowHonorificGlow
)
)
{
Plugin.SaveConfig();
}
ImGuiUtil.HelpMarker(HellionStrings.Settings_Integrations_Honorific_Glow_Hint);
} }
// Honorific has no LICENSE in its repo so we link upstream and author // Honorific has no LICENSE in its repo so we link upstream and author