feat(sidebar): show unread counts as accent badges
The unread marker was a 4px dot in StatusDanger. Red reads as an error, and an unread message is not one. It is now a count badge in AccentEmber, which is what the theme preview in settings has always shown. It has to be drawn outside the FontAwesome scope: that atlas carries no ASCII digits, so the number would have come out blank inside it. The icon width is still measured inside the scope and handed out. Placement follows the mode. Expanded puts the badge right-aligned ahead of the popout slot, where a three-digit count still fits; icon-only keeps it over the icon like the old dot. The frozen vertical offsets go at the same time. The 8f was (32 - 16) / 2 for a 16px font and stayed wrong at every other Config.FontSizeV2, which display scaling does not feed into. Both the icon and the label now centre against the measured line height, and the label starts after the measured icon width instead of a hard 32f.
This commit is contained in:
@@ -141,7 +141,6 @@ internal sealed class Sidebar
|
||||
var textAbgr = ColourUtil.RgbaToAbgr(theme.Colors.TextPrimary);
|
||||
var mutedAbgr = ColourUtil.RgbaToAbgr(theme.Colors.TextMuted);
|
||||
var dimAbgr = ColourUtil.RgbaToAbgr(theme.Colors.TextDim);
|
||||
var dangerAbgr = ColourUtil.RgbaToAbgr(theme.Colors.StatusDanger);
|
||||
var dl = ImGui.GetWindowDrawList();
|
||||
|
||||
// B3-4 sectioned render order (1.5.6 parity): persistent → pinned
|
||||
@@ -181,17 +180,7 @@ internal sealed class Sidebar
|
||||
unpinnedHeaderRendered = true;
|
||||
}
|
||||
|
||||
DrawRow(
|
||||
tab,
|
||||
expanded,
|
||||
accentRgba,
|
||||
textAbgr,
|
||||
mutedAbgr,
|
||||
dimAbgr,
|
||||
dangerAbgr,
|
||||
dl,
|
||||
ref activeTab
|
||||
);
|
||||
DrawRow(tab, expanded, accentRgba, textAbgr, mutedAbgr, dimAbgr, dl, ref activeTab);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +210,6 @@ internal sealed class Sidebar
|
||||
uint textAbgr,
|
||||
uint mutedAbgr,
|
||||
uint dimAbgr,
|
||||
uint dangerAbgr,
|
||||
ImDrawListPtr dl,
|
||||
ref Tab? activeTab
|
||||
)
|
||||
@@ -328,24 +316,44 @@ internal sealed class Sidebar
|
||||
|
||||
// Icon and label shift right by the greeted slot when it is shown.
|
||||
var contentX = showGreeted ? GreetedHitWidth : 0f;
|
||||
var scale = Metrics.Scale;
|
||||
var iconInset = 10f * scale;
|
||||
|
||||
// Centred, not a frozen offset: the old 8f was (32 - 16) / 2 for a 16px
|
||||
// font and stays wrong at any other Config.FontSizeV2.
|
||||
var contentY = Metrics.CenterY(RowHeight);
|
||||
|
||||
float iconRight;
|
||||
using (_fonts.FontAwesome.Push())
|
||||
{
|
||||
var iconStr = icon.ToIconString();
|
||||
dl.AddText(origin + new Vector2(10f + contentX, 8f), iconColor, iconStr);
|
||||
|
||||
// 1.5.6-parity unread dot, top-right of the icon. The active tab is
|
||||
// zeroed every frame (MainWindow.Draw), so the dot never shows on the
|
||||
// tab you're viewing; UnreadMode.None opts a tab out entirely.
|
||||
if (!isCurrentTab && tab.UnreadMode != UnreadMode.None && tab.Unread > 0)
|
||||
{
|
||||
var iconRight = 10f + contentX + ImGui.CalcTextSize(iconStr).X;
|
||||
dl.AddCircleFilled(origin + new Vector2(iconRight - 2f, 6f), 4f, dangerAbgr, 12);
|
||||
LastRenderedUnreadDotCount++;
|
||||
}
|
||||
dl.AddText(origin + new Vector2(iconInset + contentX, contentY), iconColor, iconStr);
|
||||
iconRight = iconInset + contentX + ImGui.CalcTextSize(iconStr).X;
|
||||
}
|
||||
|
||||
if (expanded)
|
||||
dl.AddText(origin + new Vector2(32f + contentX, 8f), textAbgr, tab.Name);
|
||||
dl.AddText(origin + new Vector2(iconRight + 6f * scale, contentY), textAbgr, tab.Name);
|
||||
|
||||
// Unread count. Drawn outside the icon-font scope on purpose: the
|
||||
// FontAwesome atlas carries no ASCII digits, so the number would come out
|
||||
// blank. The active tab is zeroed every frame (MainWindow.Draw), so it
|
||||
// never shows on the tab you are viewing; UnreadMode.None opts out.
|
||||
if (!isCurrentTab && tab.UnreadMode != UnreadMode.None && tab.Unread > 0)
|
||||
{
|
||||
var unread = (int)Math.Min(tab.Unread, int.MaxValue);
|
||||
var badgeSize = Badge.CalcSize(unread);
|
||||
var badgeX = expanded
|
||||
? avail - PopOutHitWidth - badgeSize.X - 4f * scale
|
||||
: iconRight - badgeSize.X * 0.5f;
|
||||
|
||||
Badge.Draw(
|
||||
origin + new Vector2(badgeX, MetricsMath.CenterY(RowHeight, badgeSize.Y)),
|
||||
unread,
|
||||
_palette.Abgr(Token.AccentEmber, colors),
|
||||
textAbgr
|
||||
);
|
||||
LastRenderedUnreadDotCount++;
|
||||
}
|
||||
|
||||
TabContextMenu.Draw(tab, "ctx", _pool);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user