refactor(sidebar): move popout and greeted toggles onto the icon-button widget

Both were hand-rolled: an InvisibleButton, then a glyph pushed through the
FontAwesome handle onto the draw list, with a frozen 8px vertical offset and a
4px inset. IconButton does the hit area, the hover fill and the centred glyph,
and centres against the measured line height instead of the frozen offset.

Their order is unchanged. Both still sit after TabContextMenu.Draw, which is
the ordering the popup trigger depends on, and the caller keeps what actually
differs between them: cursor placement (SameLine vs. absolute), the visibility
rule, the glyph choice and the greeted glyph counter that
SidebarGreetedGlyphStep pins.

The popout glyph now follows the row surface rather than rowHovered ||
popHovered. That pair needed the button's own hover state one line before it
existed, and the button sits inside the row anyway, so the row's hover covers
both cases.
This commit is contained in:
2026-08-17 23:52:07 +02:00
parent eacefb355d
commit 293d56bdbe
+25 -19
View File
@@ -269,7 +269,6 @@ internal sealed class Sidebar
}
ImGui.InvisibleButton("row", new Vector2(tabHitWidth, RowHeight));
var rowHovered = ImGui.IsItemHovered();
if (ImGui.IsItemClicked())
{
var previous = activeTab;
@@ -350,23 +349,23 @@ internal sealed class Sidebar
TabContextMenu.Draw(tab, "ctx", _pool);
var popHovered = false;
if (hasPopOut)
{
ImGui.SameLine(0f, 0f);
ImGui.InvisibleButton("popout", new Vector2(PopOutHitWidth, RowHeight));
popHovered = ImGui.IsItemHovered();
if (ImGui.IsItemClicked())
_pool.TryOpen(tab);
}
if (hasPopOut && (rowHovered || popHovered))
{
using (_fonts.FontAwesome.Push())
{
var glyph = FontAwesomeIcon.ArrowUpRightFromSquare.ToIconString();
dl.AddText(origin + new Vector2(avail - PopOutHitWidth + 4f, 8f), mutedAbgr, glyph);
}
// Glyph follows the row surface, not the button's own hover: the
// button sits inside the row, and the old pairing needed a hover
// state one line before it existed.
var (popClicked, _) = IconButton.Draw(
ImGui.GetID("popout"u8),
new Vector2(PopOutHitWidth, RowHeight),
surfaceHovered ? FontAwesomeIcon.ArrowUpRightFromSquare : null,
mutedAbgr,
_palette.Abgr(Token.SurfaceHover, colors),
_fonts.FontAwesome
);
if (popClicked)
_pool.TryOpen(tab);
}
if (showGreeted)
@@ -376,16 +375,23 @@ internal sealed class Sidebar
// between the row button and the popup call would steal the
// right-click trigger (B3-1 ordering constraint).
ImGui.SetCursorScreenPos(origin);
ImGui.InvisibleButton("greeted", new Vector2(GreetedHitWidth, RowHeight));
if (ImGui.IsItemClicked())
ToggleGreetedForSelfTest(tab);
// CheckCircle = greeted, plain Check = still pending (1.5.6 mapping).
var greetedGlyph = Plugin.Instance.AutoTellTabsService.IsGreeted(tab)
? FontAwesomeIcon.CheckCircle
: FontAwesomeIcon.Check;
using (_fonts.FontAwesome.Push())
dl.AddText(origin + new Vector2(4f, 8f), mutedAbgr, greetedGlyph.ToIconString());
var (greetedClicked, _) = IconButton.Draw(
ImGui.GetID("greeted"u8),
new Vector2(GreetedHitWidth, RowHeight),
greetedGlyph,
mutedAbgr,
_palette.Abgr(Token.SurfaceHover, colors),
_fonts.FontAwesome
);
if (greetedClicked)
ToggleGreetedForSelfTest(tab);
LastRenderedGreetedGlyphCount++;
}