diff --git a/HellionChat/Integrations/HonorificService.cs b/HellionChat/Integrations/HonorificService.cs index 957c827..14294b2 100644 --- a/HellionChat/Integrations/HonorificService.cs +++ b/HellionChat/Integrations/HonorificService.cs @@ -17,6 +17,12 @@ internal sealed class HonorificService : IDisposable { private const string IpcNamespace = "Honorific"; + // Major version of the Honorific IPC contract HellionChat is built against. + // Used both by the runtime compatibility check and by the settings tab when + // it tells the user which major version we expected, so the literal lives + // in exactly one place. + internal const uint ExpectedApiMajor = 3; + // IPC gates we subscribe to. Keep them as fields so Dispose can // unsubscribe the same instances we subscribed in the constructor. private readonly ICallGateSubscriber<(uint, uint)> _apiVersion; @@ -221,7 +227,7 @@ internal sealed class HonorificService : IDisposable internal static bool IsApiVersionCompatible((uint Major, uint Minor) apiVersion) { - return apiVersion.Major == 3; + return apiVersion.Major == ExpectedApiMajor; } internal static bool ShouldRenderSlot( diff --git a/HellionChat/Integrations/IntegrationLinks.cs b/HellionChat/Integrations/IntegrationLinks.cs index f9e467e..fd21bc2 100644 --- a/HellionChat/Integrations/IntegrationLinks.cs +++ b/HellionChat/Integrations/IntegrationLinks.cs @@ -7,6 +7,6 @@ namespace HellionChat.Integrations; // brand-links class. internal static class IntegrationLinks { - public const string Honorific_Repo = "https://github.com/Caraxi/Honorific"; - public const string Honorific_Author = "https://github.com/Caraxi"; + public const string HonorificRepo = "https://github.com/Caraxi/Honorific"; + public const string HonorificAuthor = "https://github.com/Caraxi"; } diff --git a/HellionChat/Resources/HellionStrings.de.resx b/HellionChat/Resources/HellionStrings.de.resx index b848362..0729fa8 100644 --- a/HellionChat/Resources/HellionStrings.de.resx +++ b/HellionChat/Resources/HellionStrings.de.resx @@ -750,7 +750,7 @@ Integrationen - Andere Dalamud-Plugins, mit denen HellionChat zusammenarbeitet — auto-detected, mit Vorschau auf kommende Integrationen. + Andere Dalamud-Plugins, mit denen HellionChat zusammenarbeitet. Auto-detected, mit Vorschau auf kommende Integrationen. Theme @@ -867,7 +867,7 @@ Idee? - Idee für eine Plugin-Integration, die nicht auf der Liste steht? Komm auf den Hellion-Forge-Discord und schreib mir — Community-Input bestimmt die Roadmap. + Idee für eine Plugin-Integration, die nicht auf der Liste steht? Komm auf den Hellion-Forge-Discord und schreib mir. Community-Input bestimmt die Roadmap. Hellion Forge öffnen diff --git a/HellionChat/Resources/HellionStrings.resx b/HellionChat/Resources/HellionStrings.resx index 18b7974..c8071b2 100644 --- a/HellionChat/Resources/HellionStrings.resx +++ b/HellionChat/Resources/HellionStrings.resx @@ -750,7 +750,7 @@ Integrations - Other Dalamud plugins HellionChat reacts to — auto-detected, with a "coming soon" preview of upcoming integrations. + Other Dalamud plugins HellionChat reacts to. Auto-detected, with a "coming soon" preview of upcoming integrations. Theme @@ -867,7 +867,7 @@ Got an idea? - Got an idea for a plugin integration that's not on this list? Hop on the Hellion Forge Discord and tell me — community input drives the roadmap. + Got an idea for a plugin integration that's not on this list? Hop on the Hellion Forge Discord and tell me. Community input drives the roadmap. Open Hellion Forge diff --git a/HellionChat/Ui/ChatLogWindow.cs b/HellionChat/Ui/ChatLogWindow.cs index 95cf343..94cc0a9 100644 --- a/HellionChat/Ui/ChatLogWindow.cs +++ b/HellionChat/Ui/ChatLogWindow.cs @@ -1683,7 +1683,7 @@ public sealed class ChatLogWindow : Window // Renders only for the active tab in the main ChatLogWindow; pop-out // windows have their own render path and skip this toolbar. // - // Hellion Chat v1.3.0 — also renders the optional Honorific title slot + // Hellion Chat v1.3.0 also renders the optional Honorific title slot // left of the pop-out button, when HonorificService reports an active // custom title and the user has ShowHonorificTitleInHeader enabled. private void DrawChatHeaderToolbar(Tab tab) @@ -1708,7 +1708,7 @@ public sealed class ChatLogWindow : Window // Renders the Honorific custom title to the left of the pop-out button, // wrapped in guillemets to match how the game itself displays titles. // We lay out the title first, then DrawPopOutButton uses - // GetContentRegionAvail to anchor itself flush right — that's why the + // GetContentRegionAvail to anchor itself flush right, which is why the // call order in DrawChatHeaderToolbar matters: title first, button second. // // The slot stays on the same line as the pop-out button so the chat @@ -1749,7 +1749,7 @@ public sealed class ChatLogWindow : Window } var rendered = "«" + title!.Title + "»"; - rendered = TruncateToWidth(rendered, maxTitleWidth); + rendered = StringUtil.TruncateToFitWidth(rendered, maxTitleWidth); var titleColor = title.Color is { } c ? new Vector4(c.X, c.Y, c.Z, 1f) @@ -1780,34 +1780,6 @@ public sealed class ChatLogWindow : Window ImGui.SameLine(); } - private static string TruncateToWidth(string text, float maxWidth) - { - if (ImGui.CalcTextSize(text).X <= maxWidth) - { - return text; - } - - // Binary-search the longest prefix that fits with an ellipsis. - const string ellipsis = "…"; - var lo = 0; - var hi = text.Length; - while (lo < hi) - { - var mid = (lo + hi + 1) / 2; - var candidate = text[..mid] + ellipsis; - if (ImGui.CalcTextSize(candidate).X <= maxWidth) - { - lo = mid; - } - else - { - hi = mid - 1; - } - } - - return lo == 0 ? ellipsis : text[..lo] + ellipsis; - } - // Hellion Chat v0.6.1 — One-Time-Hint-Banner introducing the chat header // pop-out toolbar button and the right-click pathway. Reuses the visual // pattern from Popout.cs DrawHintBannerIfNeeded so users see a familiar diff --git a/HellionChat/Ui/SettingsTabs/Integrations.cs b/HellionChat/Ui/SettingsTabs/Integrations.cs index 010d540..314a32a 100644 --- a/HellionChat/Ui/SettingsTabs/Integrations.cs +++ b/HellionChat/Ui/SettingsTabs/Integrations.cs @@ -76,12 +76,12 @@ internal sealed class Integrations : ISettingsTab ImGui.Spacing(); if (ImGui.Button(HellionStrings.Settings_Integrations_Honorific_LinkRepo)) { - Dalamud.Utility.Util.OpenLink(IntegrationLinks.Honorific_Repo); + Dalamud.Utility.Util.OpenLink(IntegrationLinks.HonorificRepo); } ImGui.SameLine(); if (ImGui.Button(HellionStrings.Settings_Integrations_Honorific_LinkAuthor)) { - Dalamud.Utility.Util.OpenLink(IntegrationLinks.Honorific_Author); + Dalamud.Utility.Util.OpenLink(IntegrationLinks.HonorificAuthor); } } @@ -104,7 +104,7 @@ internal sealed class Integrations : ISettingsTab ImGui.SameLine(); ImGui.TextUnformatted(string.Format( HellionStrings.Settings_Integrations_Honorific_Status_Incompatible, - 3, incompatibleVersion.Major, incompatibleVersion.Minor)); + HonorificService.ExpectedApiMajor, incompatibleVersion.Major, incompatibleVersion.Minor)); } else { diff --git a/HellionChat/Util/StringUtil.cs b/HellionChat/Util/StringUtil.cs index fdddc0a..b1a54d5 100755 --- a/HellionChat/Util/StringUtil.cs +++ b/HellionChat/Util/StringUtil.cs @@ -1,5 +1,6 @@ using System.Globalization; using System.Text; +using Dalamud.Bindings.ImGui; namespace HellionChat.Util; @@ -29,4 +30,36 @@ internal static class StringUtil // separator to '.' so a German locale doesn't render "1,5GB". return (Math.Sign(byteCount) * num).ToString("0.#", CultureInfo.InvariantCulture) + suf[place]; } + + // Returns the text unchanged when it already fits the width budget, + // otherwise the longest prefix plus a horizontal-ellipsis character that + // still fits. Used by the chat header Honorific title slot and reused by + // the chat-line truncation path in later cycles. + public static string TruncateToFitWidth(string text, float maxWidth) + { + if (ImGui.CalcTextSize(text).X <= maxWidth) + { + return text; + } + + // Binary-search the longest prefix that fits with an ellipsis. + const string ellipsis = "…"; + var lo = 0; + var hi = text.Length; + while (lo < hi) + { + var mid = (lo + hi + 1) / 2; + var candidate = text[..mid] + ellipsis; + if (ImGui.CalcTextSize(candidate).X <= maxWidth) + { + lo = mid; + } + else + { + hi = mid - 1; + } + } + + return lo == 0 ? ellipsis : text[..lo] + ellipsis; + } }