fix(ui): stop sidebar badges from displacing button text
The Chat/History nav buttons centered their icon+label in a region that shrank when a badge (unread count / mining dot) was present, and the "has badge" test read the LIVE count — so the text jumped sideways the moment a count toggled (e.g. a new chat message arrived). Reserve badge clearance by whether the page CAN show a badge (constant per item), center in the full button width regardless, and cap the label with symmetric clearance so a long label still can't run under the corner badge. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -679,15 +679,18 @@ inline bool RenderSidebar(NavPage& current, float sidebarWidth, float contentHei
|
|||||||
ImU32 textCol = selected ? Primary() : (pageNeedsUnlock ? OnSurfaceDisabled() : OnSurfaceMedium());
|
ImU32 textCol = selected ? Primary() : (pageNeedsUnlock ? OnSurfaceDisabled() : OnSurfaceMedium());
|
||||||
|
|
||||||
if (showLabels) {
|
if (showLabels) {
|
||||||
// Reserve room for a badge (if this item will draw one) so the
|
// The badge is a fixed top-right corner overlay, so it must NOT move
|
||||||
// label centers in the space to the left of it instead of
|
// the icon+label — otherwise the text jumps sideways the moment a live
|
||||||
// running underneath the badge circle.
|
// count toggles the badge on/off. Reserve clearance from whether the
|
||||||
bool itemHasBadge =
|
// page CAN show a badge (constant per item), never from the current
|
||||||
(item.page == NavPage::History && status.unconfirmedTxCount > 0) ||
|
// count, and keep the icon+label centered in the FULL button width so
|
||||||
(item.page == NavPage::Mining && status.miningActive) ||
|
// the text position and size stay identical with or without a badge.
|
||||||
(item.page == NavPage::Chat && status.chatUnreadCount > 0);
|
bool itemBadgeCapable =
|
||||||
|
item.page == NavPage::History ||
|
||||||
|
item.page == NavPage::Mining ||
|
||||||
|
item.page == NavPage::Chat;
|
||||||
float badgeReserve = 0.0f;
|
float badgeReserve = 0.0f;
|
||||||
if (itemHasBadge) {
|
if (itemBadgeCapable) {
|
||||||
bool dotOnlyReserve = (item.page == NavPage::Mining);
|
bool dotOnlyReserve = (item.page == NavPage::Mining);
|
||||||
float badgeRReserve = dotOnlyReserve ? badgeRadiusDot : badgeRadiusNumber;
|
float badgeRReserve = dotOnlyReserve ? badgeRadiusDot : badgeRadiusNumber;
|
||||||
float badgeInsetXReserve = sde("badge-inset-x", 6.0f);
|
float badgeInsetXReserve = sde("badge-inset-x", 6.0f);
|
||||||
@@ -697,14 +700,17 @@ inline bool RenderSidebar(NavPage& current, float sidebarWidth, float contentHei
|
|||||||
ImFont* font = selected ? Type().subtitle2() : Type().body2();
|
ImFont* font = selected ? Type().subtitle2() : Type().body2();
|
||||||
float lblFsz = ScaledFontSize(font);
|
float lblFsz = ScaledFontSize(font);
|
||||||
float btnW = indMax.x - indMin.x;
|
float btnW = indMax.x - indMin.x;
|
||||||
float maxLabelW = btnW - iconS * 2.0f - iconLabelGap - Layout::spacingXs() * 2 - badgeReserve;
|
// Clearance is symmetric (2x) because the group stays centered in the
|
||||||
|
// full width: reserving on both sides keeps the label's right edge clear
|
||||||
|
// of the right-side corner badge without shifting the center off-axis.
|
||||||
|
float maxLabelW = btnW - iconS * 2.0f - iconLabelGap - Layout::spacingXs() * 2 - badgeReserve * 2.0f;
|
||||||
ImVec2 labelSz = font->CalcTextSizeA(lblFsz, 1000.0f, 0.0f, NavLabel(item));
|
ImVec2 labelSz = font->CalcTextSizeA(lblFsz, 1000.0f, 0.0f, NavLabel(item));
|
||||||
if (labelSz.x > maxLabelW && maxLabelW > 0) {
|
if (labelSz.x > maxLabelW && maxLabelW > 0) {
|
||||||
lblFsz *= maxLabelW / labelSz.x;
|
lblFsz *= maxLabelW / labelSz.x;
|
||||||
labelSz = font->CalcTextSizeA(lblFsz, 1000.0f, 0.0f, NavLabel(item));
|
labelSz = font->CalcTextSizeA(lblFsz, 1000.0f, 0.0f, NavLabel(item));
|
||||||
}
|
}
|
||||||
float totalW = iconS * 2.0f + iconLabelGap + labelSz.x;
|
float totalW = iconS * 2.0f + iconLabelGap + labelSz.x;
|
||||||
float btnCX = (indMin.x + indMax.x - badgeReserve) * 0.5f;
|
float btnCX = (indMin.x + indMax.x) * 0.5f;
|
||||||
float startX = btnCX - totalW * 0.5f;
|
float startX = btnCX - totalW * 0.5f;
|
||||||
|
|
||||||
DrawNavIcon(dl, item.page, startX + iconS, iconCY, iconS, textCol);
|
DrawNavIcon(dl, item.page, startX + iconS, iconCY, iconS, textCol);
|
||||||
|
|||||||
Reference in New Issue
Block a user