feat(sidebar): restore section headers and compact separators
This commit is contained in:
@@ -3,6 +3,7 @@ using Dalamud.Bindings.ImGui;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using HellionChat.Code;
|
||||
using HellionChat.Resources;
|
||||
using HellionChat.Themes;
|
||||
using HellionChat.Ui.StyleEngine;
|
||||
using HellionChat.Util;
|
||||
@@ -35,6 +36,10 @@ internal sealed class Sidebar
|
||||
// The SelfTest reads it after driving the real Draw — no dead service roundtrip.
|
||||
internal int LastRenderedGreetedGlyphCount;
|
||||
|
||||
// B3-4 render observability: section headers actually drawn this frame.
|
||||
// Incremented only in the real header branch; reset at Draw start.
|
||||
internal int LastDrawnSectionHeaderCount;
|
||||
|
||||
// Inline mirror of the old TabIconMapping table so the Ui layer carries
|
||||
// its own glyph lookup once the standalone file is removed.
|
||||
private static readonly Dictionary<string, FontAwesomeIcon> IconByName = new(
|
||||
@@ -100,6 +105,7 @@ internal sealed class Sidebar
|
||||
public void Draw(float windowWidth, IList<Tab> tabs, ref Tab? activeTab)
|
||||
{
|
||||
LastRenderedGreetedGlyphCount = 0;
|
||||
LastDrawnSectionHeaderCount = 0;
|
||||
|
||||
if (!_fonts.FontsReady)
|
||||
{
|
||||
@@ -120,18 +126,74 @@ internal sealed class Sidebar
|
||||
var dimAbgr = ColourUtil.RgbaToAbgr(theme.Colors.TextDim);
|
||||
var dl = ImGui.GetWindowDrawList();
|
||||
|
||||
// B3-4 sectioned render order (1.5.6 parity): persistent → pinned
|
||||
// TempTabs → unpinned TempTabs. Only the display sequence regroups;
|
||||
// the tab list itself stays untouched and every row keeps its
|
||||
// ORIGINAL list index for PushID, so an open context-menu popup
|
||||
// stays bound to its tab when sectioning moves it visually.
|
||||
var renderOrder = BuildRenderOrder(tabs);
|
||||
var pinnedHeaderRendered = false;
|
||||
var unpinnedHeaderRendered = false;
|
||||
foreach (var i in renderOrder)
|
||||
{
|
||||
var tab = tabs[i];
|
||||
if (TabLifecycleHelpers.IsInPinnedPool(tab) && !pinnedHeaderRendered)
|
||||
{
|
||||
DrawSectionHeader(
|
||||
HellionStrings.PinTab_SectionHeader,
|
||||
Plugin.Instance.AutoTellTabsService.PinnedTempTabCount
|
||||
);
|
||||
pinnedHeaderRendered = true;
|
||||
}
|
||||
else if (TabLifecycleHelpers.IsInUnpinnedPool(tab) && !unpinnedHeaderRendered)
|
||||
{
|
||||
DrawSectionHeader(
|
||||
HellionStrings.AutoTellTabs_SectionHeader,
|
||||
Plugin.Instance.AutoTellTabsService.ActiveTempTabCount
|
||||
);
|
||||
unpinnedHeaderRendered = true;
|
||||
}
|
||||
|
||||
DrawRow(tab, i, expanded, accentRgba, textAbgr, mutedAbgr, dimAbgr, dl, ref activeTab);
|
||||
}
|
||||
}
|
||||
|
||||
// Section transition marker (1.5.6 parity): the separator always renders,
|
||||
// compact mode suppresses only the header text. Real cursor-advancing
|
||||
// widgets on purpose — rows advance the cursor via InvisibleButton, so a
|
||||
// drawlist-only header would overlap the next row.
|
||||
private void DrawSectionHeader(string header, int count)
|
||||
{
|
||||
ImGui.Separator();
|
||||
if (Plugin.Config.AutoTellTabsCompactDisplay)
|
||||
return;
|
||||
|
||||
ImGui.TextDisabled($"{header} ({count})");
|
||||
LastDrawnSectionHeaderCount++;
|
||||
}
|
||||
|
||||
// Mirror of 1.5.6's BuildSidebarRenderOrder: returns indices into the
|
||||
// live tab list grouped by section, so the list order itself is never
|
||||
// mutated and headers gate on the first tab actually reached per pool
|
||||
// (an empty pool draws neither separator nor header).
|
||||
private static List<int> BuildRenderOrder(IList<Tab> tabs)
|
||||
{
|
||||
var persistent = new List<int>(tabs.Count);
|
||||
var pinned = new List<int>();
|
||||
var unpinned = new List<int>();
|
||||
for (var i = 0; i < tabs.Count; i++)
|
||||
DrawRow(
|
||||
tabs[i],
|
||||
i,
|
||||
expanded,
|
||||
accentRgba,
|
||||
textAbgr,
|
||||
mutedAbgr,
|
||||
dimAbgr,
|
||||
dl,
|
||||
ref activeTab
|
||||
);
|
||||
{
|
||||
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 DrawRow(
|
||||
|
||||
Reference in New Issue
Block a user