diff --git a/HellionChat/Configuration.cs b/HellionChat/Configuration.cs
index 51a1941..5381ed4 100755
--- a/HellionChat/Configuration.cs
+++ b/HellionChat/Configuration.cs
@@ -113,6 +113,11 @@ public class Configuration : IPluginConfiguration
public int AutoTellTabsLimit = 15;
public bool AutoTellTabsCompactDisplay;
public int AutoTellTabsHistoryPreload = 20;
+
+ // Sidebar width in pixels. Default 44 mirrors the icon-only layout from
+ // v1.2.0; users can widen up to 160 to fit a section-header line like
+ // "Active Tells (3)" without truncation.
+ public int SidebarWidth = 44;
public bool AutoTellTabsShowGreetedToggle;
public bool SeenPopOutInputHint;
public bool PopOutInputEnabled = true;
@@ -339,6 +344,7 @@ public class Configuration : IPluginConfiguration
AutoTellTabsLimit = other.AutoTellTabsLimit;
AutoTellTabsCompactDisplay = other.AutoTellTabsCompactDisplay;
AutoTellTabsHistoryPreload = other.AutoTellTabsHistoryPreload;
+ SidebarWidth = other.SidebarWidth;
AutoTellTabsShowGreetedToggle = other.AutoTellTabsShowGreetedToggle;
SeenPopOutInputHint = other.SeenPopOutInputHint;
diff --git a/HellionChat/Resources/HellionStrings.Designer.cs b/HellionChat/Resources/HellionStrings.Designer.cs
index 3282998..2aaddc8 100644
--- a/HellionChat/Resources/HellionStrings.Designer.cs
+++ b/HellionChat/Resources/HellionStrings.Designer.cs
@@ -177,6 +177,9 @@ internal class HellionStrings
internal static string PinTab_LimitReached => Get(nameof(PinTab_LimitReached));
internal static string PinTab_PinnedTooltip => Get(nameof(PinTab_PinnedTooltip));
internal static string PinTab_PinTooltip => Get(nameof(PinTab_PinTooltip));
+ internal static string PinTab_SectionHeader => Get(nameof(PinTab_SectionHeader));
+ internal static string Settings_ThemeAndLayout_SidebarWidth_Name => Get(nameof(Settings_ThemeAndLayout_SidebarWidth_Name));
+ internal static string Settings_ThemeAndLayout_SidebarWidth_Description => Get(nameof(Settings_ThemeAndLayout_SidebarWidth_Description));
// Hellion Chat — Auto-Tell-Tabs Chat settings tab
internal static string ChatLog_AutoTellTabs_Section_Title => Get(nameof(ChatLog_AutoTellTabs_Section_Title));
diff --git a/HellionChat/Resources/HellionStrings.de.resx b/HellionChat/Resources/HellionStrings.de.resx
index 766e2bf..e9fc2ff 100644
--- a/HellionChat/Resources/HellionStrings.de.resx
+++ b/HellionChat/Resources/HellionStrings.de.resx
@@ -404,6 +404,15 @@
Angepinnte Tabs überleben Relog und behalten die Bindung an die Tell-Person.
+
+ Angepinnt
+
+
+ Sidebar-Breite
+
+
+ Breite der Tab-Sidebar in Pixeln. Default (44 px) ist Icon-only; breiter machen damit Sektion-Header wie „Aktive Tells (3)" nicht abgeschnitten werden.
+
diff --git a/HellionChat/Resources/HellionStrings.resx b/HellionChat/Resources/HellionStrings.resx
index 101a6eb..8940f46 100644
--- a/HellionChat/Resources/HellionStrings.resx
+++ b/HellionChat/Resources/HellionStrings.resx
@@ -398,6 +398,15 @@
Pinned tabs survive relog and stay bound to this conversation partner.
+
+ Pinned
+
+
+ Sidebar width
+
+
+ Width of the tab sidebar in pixels. The default (44 px) is icon-only; widen it to fit the section headers like "Active Tells (3)" without truncation.
+
Maximum of {0} pinned tell tabs reached. Unpin one first, or use Promote to permanent.
diff --git a/HellionChat/Ui/ChatLogWindow.cs b/HellionChat/Ui/ChatLogWindow.cs
index bab4bfc..e67f85c 100644
--- a/HellionChat/Ui/ChatLogWindow.cs
+++ b/HellionChat/Ui/ChatLogWindow.cs
@@ -1673,6 +1673,30 @@ public sealed class ChatLogWindow : Window
Plugin.WantedTab = null;
}
+ // Sidebar render order: persistent tabs in their original Plugin.Config.Tabs
+ // position, then pinned TempTabs, then unpinned TempTabs. Returns indices
+ // into Plugin.Config.Tabs so tabI in the loop body still mirrors the real
+ // list position (LastTab / WantedTab stay consistent).
+ private static List BuildSidebarRenderOrder()
+ {
+ var tabs = Plugin.Config.Tabs;
+ var persistent = new List(tabs.Count);
+ var pinned = new List();
+ var unpinned = new List();
+ for (var i = 0; i < tabs.Count; i++)
+ {
+ if (TabLifecycleHelpers.IsInPinnedPool(tabs[i]))
+ pinned.Add(i);
+ else if (TabLifecycleHelpers.IsInUnpinnedPool(tabs[i]))
+ unpinned.Add(i);
+ else
+ persistent.Add(i);
+ }
+ persistent.AddRange(pinned);
+ persistent.AddRange(unpinned);
+ return persistent;
+ }
+
private void DrawTabSidebar()
{
var currentTab = -1;
@@ -1685,7 +1709,8 @@ public sealed class ChatLogWindow : Window
if (!tabTable.Success)
return;
- ImGui.TableSetupColumn("tabs", ImGuiTableColumnFlags.WidthFixed, 44f);
+ var sidebarWidth = Math.Clamp(Plugin.Config.SidebarWidth, 44, 160);
+ ImGui.TableSetupColumn("tabs", ImGuiTableColumnFlags.WidthFixed, sidebarWidth);
ImGui.TableSetupColumn("chat", ImGuiTableColumnFlags.WidthStretch, 1);
ImGui.TableNextColumn();
@@ -1704,23 +1729,42 @@ public sealed class ChatLogWindow : Window
ImGui.Dummy(new Vector2(0, ImGui.GetFrameHeightWithSpacing()));
var previousTab = Plugin.CurrentTab;
- // Divider rendered once before the first temp tab with a live unit counter.
+ // Render order: persistent → pinned TempTabs → unpinned TempTabs.
+ // Underlying Plugin.Config.Tabs order is untouched (tabI mirrors
+ // the real list index), only the display sequence groups by
+ // section so each section can carry its own divider header.
+ var renderOrder = BuildSidebarRenderOrder();
+ var pinnedHeaderRendered = false;
var tempTabHeaderRendered = false;
- var tempTabCount = Plugin.Config.Tabs.Count(t => t.IsTempTab);
+ var pinnedCount = Plugin.Config.Tabs.Count(TabLifecycleHelpers.IsInPinnedPool);
+ var unpinnedTempCount = Plugin.Config.Tabs.Count(
+ TabLifecycleHelpers.IsInUnpinnedPool
+ );
- for (var tabI = 0; tabI < Plugin.Config.Tabs.Count; tabI++)
+ foreach (var tabI in renderOrder)
{
var tab = Plugin.Config.Tabs[tabI];
if (tab.PopOut)
continue;
- if (tab.IsTempTab && !tempTabHeaderRendered)
+ if (TabLifecycleHelpers.IsInPinnedPool(tab) && !pinnedHeaderRendered)
{
ImGui.Separator();
if (!Plugin.Config.AutoTellTabsCompactDisplay)
{
ImGui.TextDisabled(
- $"{HellionStrings.AutoTellTabs_SectionHeader} ({tempTabCount})"
+ $"{HellionStrings.PinTab_SectionHeader} ({pinnedCount})"
+ );
+ }
+ pinnedHeaderRendered = true;
+ }
+ else if (TabLifecycleHelpers.IsInUnpinnedPool(tab) && !tempTabHeaderRendered)
+ {
+ ImGui.Separator();
+ if (!Plugin.Config.AutoTellTabsCompactDisplay)
+ {
+ ImGui.TextDisabled(
+ $"{HellionStrings.AutoTellTabs_SectionHeader} ({unpinnedTempCount})"
);
}
tempTabHeaderRendered = true;
@@ -1809,9 +1853,12 @@ public sealed class ChatLogWindow : Window
using (ImRaii.PushColor(ImGuiCol.Text, ColourUtil.RgbaToAbgr(iconColor)))
using (Plugin.FontManager.FontAwesome.Push())
{
+ // Button stretches with the configured sidebar width so a
+ // user-widened sidebar feels intentional, not a 36px icon
+ // floating in empty space.
clicked = ImGui.Button(
$"{icon.ToIconString()}##sidebar-tab-{tabI}",
- new Vector2(36f, ImGui.GetFrameHeight())
+ new Vector2(sidebarWidth - 8f, ImGui.GetFrameHeight())
);
}
@@ -1871,22 +1918,23 @@ public sealed class ChatLogWindow : Window
);
}
- // Pin indicator: small thumbtack glyph top-left of the icon.
- // Sits opposite the unread dot so they never collide.
+ // Pin indicator: subtle thumbtack glyph top-left of the icon.
+ // Muted colour because the "Pinned" section header already
+ // groups these tabs visually — this is just a per-tab
+ // confirmation glyph, not the primary discoverability cue.
if (tab.IsPinned)
{
var min = ImGui.GetItemRectMin();
- const float pinPadding = 2f;
+ const float pinPadding = 1f;
var pinPos = new Vector2(min.X + pinPadding, min.Y + pinPadding);
+ var pinColor = theme.Colors.TextMuted;
+ // Dim further so the glyph reads as a hint, not a badge.
+ var pinAbgr = ColourUtil.RgbaToAbgr(pinColor) & 0x77FFFFFFu;
using (Plugin.FontManager.FontAwesome.Push())
{
ImGui
.GetWindowDrawList()
- .AddText(
- pinPos,
- ColourUtil.RgbaToAbgr(theme.Colors.Accent),
- FontAwesomeIcon.Thumbtack.ToIconString()
- );
+ .AddText(pinPos, pinAbgr, FontAwesomeIcon.Thumbtack.ToIconString());
}
}
diff --git a/HellionChat/Ui/SettingsTabs/ThemeAndLayout.cs b/HellionChat/Ui/SettingsTabs/ThemeAndLayout.cs
index 890b76f..34baf54 100644
--- a/HellionChat/Ui/SettingsTabs/ThemeAndLayout.cs
+++ b/HellionChat/Ui/SettingsTabs/ThemeAndLayout.cs
@@ -250,6 +250,26 @@ internal sealed class ThemeAndLayout : ISettingsTab
string.Format(Language.Options_SidebarTabView_Description, Plugin.PluginName)
);
+ if (Mutable.SidebarTabView)
+ {
+ var sidebarWidth = Mutable.SidebarWidth;
+ if (
+ ImGui.SliderInt(
+ HellionStrings.Settings_ThemeAndLayout_SidebarWidth_Name,
+ ref sidebarWidth,
+ 44,
+ 160,
+ $"{sidebarWidth} px"
+ )
+ )
+ {
+ Mutable.SidebarWidth = sidebarWidth;
+ }
+ ImGuiUtil.HelpMarker(
+ HellionStrings.Settings_ThemeAndLayout_SidebarWidth_Description
+ );
+ }
+
ImGui.Spacing();
ImGui.Separator();
ImGui.Spacing();