fix(ui): make HiDPI-overflowing containers scrollable — wizard, overlay dialogs, balance recent-tx
At font_scale 1.5 (dpiScale 1.5) three fixed, non-scrolling containers clipped content off the bottom with no scroll escape: - First-run wizard: the hand-drawn cards grow ~1.5x past the fixed window, pushing Continue / Encrypt & Continue / Skip off-screen (a setup blocker). Inject a wheel-driven scroll offset into the layout seed + a scroll indicator; gate the wheel on !IsPopupOpen + NoPopupHierarchy so an open combo popup does not scroll the wizard behind it. No-op at 1.0x. - Overlay dialogs (BeginOverlayDialog): auto-height cards taller than the viewport (About, Request Payment) ran their footer off the bottom. Add a sticky per-open overflow flag that clamps the card to the viewport and makes the content child scrollable; short dialogs still center unchanged. Give the nested settings clear-history confirm its own idSuffix so it can't inherit the parent dialog's overflow state or collide on the child window id. - Balance Recent Transactions: the dp-scaled address card evicted the recent-tx list off the non-scrolling tab host. Cap the card inside RenderSharedAddressList against the space that actually remains (minus a caller-provided reserve) so the section below stays on-screen — covers all 10 balance layouts. Verified at font_scale 1.5 across full-node + Lite + Windows (ctest green) and an adversarial diff review (two low-severity regressions found + fixed). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -177,8 +177,28 @@ void App::renderFirstRunWizard() {
|
|||||||
// DPI scale factor — multiply all pixel constants by dp
|
// DPI scale factor — multiply all pixel constants by dp
|
||||||
const float dp = ui::Layout::dpiScale();
|
const float dp = ui::Layout::dpiScale();
|
||||||
|
|
||||||
|
// Vertical scroll: the wizard cards are hand-drawn at absolute Y offsets and grow ~1.5x with the
|
||||||
|
// font-scale setting, so at high scale the focused card's primary button (Continue / Encrypt & Continue
|
||||||
|
// / Skip) can fall below the fixed window. Offset the whole layout by a wheel-driven scroll, clamped to
|
||||||
|
// last frame's measured content height, so every control stays reachable. The window keeps
|
||||||
|
// NoScrollWithMouse, so ImGui doesn't consume the wheel — we read the raw delta and apply our own offset.
|
||||||
|
static float s_wizScroll = 0.0f, s_wizContentH = 0.0f;
|
||||||
|
if (ImGui::IsWindowAppearing()) s_wizScroll = 0.0f;
|
||||||
|
const float wizMaxScroll = std::max(0.0f, s_wizContentH - winSize.y);
|
||||||
|
// Don't steal the wheel from an open combo popup (e.g. the 9-item Language dropdown, which is a
|
||||||
|
// scrollable popup): NoPopupHierarchy stops the popup counting as hovering the wizard, and the
|
||||||
|
// IsPopupOpen guard ensures no wheel is consumed for the whole wizard while any popup is showing.
|
||||||
|
const bool wizPopupOpen = ImGui::IsPopupOpen("", ImGuiPopupFlags_AnyPopupId | ImGuiPopupFlags_AnyPopupLevel);
|
||||||
|
if (wizMaxScroll > 0.0f && !wizPopupOpen &&
|
||||||
|
ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_NoPopupHierarchy)) {
|
||||||
|
float wheel = ImGui::GetIO().MouseWheel;
|
||||||
|
if (wheel != 0.0f) s_wizScroll -= wheel * 60.0f * dp;
|
||||||
|
}
|
||||||
|
s_wizScroll = std::max(0.0f, std::min(s_wizScroll, wizMaxScroll));
|
||||||
|
const float scrollY = s_wizScroll;
|
||||||
|
|
||||||
// --- Header: Logo + Welcome ---
|
// --- Header: Logo + Welcome ---
|
||||||
float headerCy = winPos.y + 20.0f * dp;
|
float headerCy = winPos.y - scrollY + 20.0f * dp;
|
||||||
float logoSize = S.drawElement("screens.first-run", "logo").sizeOr(56.0f);
|
float logoSize = S.drawElement("screens.first-run", "logo").sizeOr(56.0f);
|
||||||
if (logo_tex_ != 0) {
|
if (logo_tex_ != 0) {
|
||||||
float aspect = (logo_h_ > 0) ? (float)logo_w_ / (float)logo_h_ : 1.0f;
|
float aspect = (logo_h_ > 0) ? (float)logo_w_ / (float)logo_h_ : 1.0f;
|
||||||
@@ -1428,6 +1448,21 @@ void App::renderFirstRunWizard() {
|
|||||||
// Merge channels: backgrounds → content → overlays
|
// Merge channels: backgrounds → content → overlays
|
||||||
dl->ChannelsMerge();
|
dl->ChannelsMerge();
|
||||||
|
|
||||||
|
// Measure this frame's content height (feeds next frame's scroll clamp) and, when it overflows the
|
||||||
|
// window, draw a slim scroll indicator so the off-screen content is discoverable.
|
||||||
|
{
|
||||||
|
float contentBottom = std::max(card0Bot, std::max(card1Bot, card2Bot));
|
||||||
|
s_wizContentH = (contentBottom - winPos.y + scrollY) + 24.0f * dp;
|
||||||
|
if (wizMaxScroll > 0.0f && s_wizContentH > 0.0f) {
|
||||||
|
float trackH = winSize.y - 8.0f * dp;
|
||||||
|
float thumbH = std::min(trackH, std::max(32.0f * dp, trackH * (winSize.y / s_wizContentH)));
|
||||||
|
float thumbY = winPos.y + 4.0f * dp + (trackH - thumbH) * (scrollY / wizMaxScroll);
|
||||||
|
float barX = winPos.x + winSize.x - 6.0f * dp;
|
||||||
|
dl->AddRectFilled(ImVec2(barX, thumbY), ImVec2(barX + 3.0f * dp, thumbY + thumbH),
|
||||||
|
ui::material::WithAlpha(ui::material::OnSurface(), 55), 1.5f * dp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1403,6 +1403,7 @@ struct OverlayCardState {
|
|||||||
int stableCount = 0; // consecutive frames the height held steady (within 1px)
|
int stableCount = 0; // consecutive frames the height held steady (within 1px)
|
||||||
int appearFrames = 0; // frames since (re)appearing while still hidden — a safety cap
|
int appearFrames = 0; // frames since (re)appearing while still hidden — a safety cap
|
||||||
bool shown = false; // revealed (centered) at least once this open; don't re-hide after
|
bool shown = false; // revealed (centered) at least once this open; don't re-hide after
|
||||||
|
bool overflow = false; // content once exceeded the viewport → clamp to viewport + scroll (sticky/open)
|
||||||
};
|
};
|
||||||
inline std::unordered_map<std::string, OverlayCardState> g_overlayCardHeights;
|
inline std::unordered_map<std::string, OverlayCardState> g_overlayCardHeights;
|
||||||
inline std::string g_overlayCurrentKey;
|
inline std::string g_overlayCurrentKey;
|
||||||
@@ -1528,6 +1529,7 @@ inline bool BeginOverlayDialog(const OverlayDialogSpec& spec)
|
|||||||
float cardX = vp_pos.x + (vp_size.x - cardWidth) * 0.5f;
|
float cardX = vp_pos.x + (vp_size.x - cardWidth) * 0.5f;
|
||||||
float cardY, cardBottomY;
|
float cardY, cardBottomY;
|
||||||
bool hideForMeasure = false; // true on an auto-height dialog's first (unmeasured) frame
|
bool hideForMeasure = false; // true on an auto-height dialog's first (unmeasured) frame
|
||||||
|
bool autoOverflow = false; // auto-height content taller than the viewport → clamp + scroll
|
||||||
const bool fixedHeight = (spec.cardHeight > 0.0f);
|
const bool fixedHeight = (spec.cardHeight > 0.0f);
|
||||||
if (fixedHeight) {
|
if (fixedHeight) {
|
||||||
float cardH = std::min(spec.cardHeight * dp, vp_size.y - 32.0f);
|
float cardH = std::min(spec.cardHeight * dp, vp_size.y - 32.0f);
|
||||||
@@ -1537,9 +1539,16 @@ inline bool BeginOverlayDialog(const OverlayDialogSpec& spec)
|
|||||||
} else {
|
} else {
|
||||||
g_overlayCurrentKey = childId;
|
g_overlayCurrentKey = childId;
|
||||||
OverlayCardState& cs = g_overlayCardHeights[childId];
|
OverlayCardState& cs = g_overlayCardHeights[childId];
|
||||||
if (scrimAppearing) { cs.shown = false; cs.stableCount = 0; cs.appearFrames = 0; }
|
if (scrimAppearing) { cs.shown = false; cs.stableCount = 0; cs.appearFrames = 0; cs.overflow = false; }
|
||||||
if (!cs.shown) cs.appearFrames++;
|
if (!cs.shown) cs.appearFrames++;
|
||||||
const float measuredH = cs.height;
|
const float measuredH = cs.height;
|
||||||
|
const float maxCardH = vp_size.y - 32.0f;
|
||||||
|
// Once the measured content is taller than the viewport, lock the card to the viewport height and
|
||||||
|
// let its content child scroll (autoOverflow) so the footer/actions stay reachable. Sticky for this
|
||||||
|
// open: clamping makes next frame's measured height the clamped value, so re-deciding from it would
|
||||||
|
// oscillate — decide once and hold until the dialog re-opens.
|
||||||
|
if (measuredH > maxCardH) cs.overflow = true;
|
||||||
|
autoOverflow = cs.overflow;
|
||||||
// Reveal once the measured height has settled (auto-resize converges in ~2 frames) or it's
|
// Reveal once the measured height has settled (auto-resize converges in ~2 frames) or it's
|
||||||
// already been shown this open (don't re-hide on a mid-dialog content change); a frame cap
|
// already been shown this open (don't re-hide on a mid-dialog content change); a frame cap
|
||||||
// guarantees a pathological ever-changing height can't hide the dialog forever.
|
// guarantees a pathological ever-changing height can't hide the dialog forever.
|
||||||
@@ -1547,11 +1556,18 @@ inline bool BeginOverlayDialog(const OverlayDialogSpec& spec)
|
|||||||
(cs.shown || cs.stableCount >= 1 || cs.appearFrames >= 8);
|
(cs.shown || cs.stableCount >= 1 || cs.appearFrames >= 8);
|
||||||
if (ready) {
|
if (ready) {
|
||||||
cs.shown = true;
|
cs.shown = true;
|
||||||
// Center the measured content; if it's taller than the window, anchor at the top margin.
|
if (autoOverflow) {
|
||||||
cardY = (measuredH < vp_size.y - 32.0f)
|
// Taller than the screen: top-anchor at the 16px margin, clamp to the viewport; the
|
||||||
? vp_pos.y + (vp_size.y - measuredH) * 0.5f
|
// content child (below) becomes the scroll region so the footer/actions stay reachable.
|
||||||
: vp_pos.y + 16.0f;
|
cardY = vp_pos.y + 16.0f;
|
||||||
cardBottomY = cardY + measuredH;
|
cardBottomY = cardY + maxCardH;
|
||||||
|
} else {
|
||||||
|
// Center the measured content; if it's taller than the window, anchor at the top margin.
|
||||||
|
cardY = (measuredH < maxCardH)
|
||||||
|
? vp_pos.y + (vp_size.y - measuredH) * 0.5f
|
||||||
|
: vp_pos.y + 16.0f;
|
||||||
|
cardBottomY = cardY + measuredH;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Still settling: lay the content out (so the auto-height child gets measured) but keep
|
// Still settling: lay the content out (so the auto-height child gets measured) but keep
|
||||||
// the card hidden (hideForMeasure below) so it never flashes off-center — it appears,
|
// the card hidden (hideForMeasure below) so it never flashes off-center — it appears,
|
||||||
@@ -1584,14 +1600,21 @@ inline bool BeginOverlayDialog(const OverlayDialogSpec& spec)
|
|||||||
ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, floating ? 20.0f : 16.0f);
|
ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, floating ? 20.0f : 16.0f);
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, floating ? ImVec2(28, 20) : ImVec2(28, 24));
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, floating ? ImVec2(28, 20) : ImVec2(28, 24));
|
||||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0, 0, 0, 0)); // transparent (glass/blur behind)
|
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0, 0, 0, 0)); // transparent (glass/blur behind)
|
||||||
ImGuiChildFlags cflags = ImGuiChildFlags_AlwaysUseWindowPadding | (fixedHeight ? 0 : ImGuiChildFlags_AutoResizeY);
|
// A card with a known height is a fixed frame (fixed-height dialogs, and auto-height dialogs whose
|
||||||
|
// content overflowed the viewport); otherwise the child auto-resizes to its content.
|
||||||
|
const bool clampedCard = fixedHeight || autoOverflow;
|
||||||
|
ImGuiChildFlags cflags = ImGuiChildFlags_AlwaysUseWindowPadding | (clampedCard ? 0 : ImGuiChildFlags_AutoResizeY);
|
||||||
// NoScrollWithMouse (not just NoScrollbar): a modal is a fixed frame — the wheel must never drift
|
// NoScrollWithMouse (not just NoScrollbar): a modal is a fixed frame — the wheel must never drift
|
||||||
// the WHOLE card. If content marginally overflows a fixed card, the wheel would otherwise scroll
|
// the WHOLE card. If content marginally overflows a fixed card, the wheel would otherwise scroll
|
||||||
// the entire dialog (title + footer and all). Inner scroll regions (lists, notes) still scroll on
|
// the entire dialog (title + footer and all). Inner scroll regions (lists, notes) still scroll on
|
||||||
// their own; auto-height cards resize to content so they never overflow anyway.
|
// their own; auto-height cards resize to content so they normally never overflow — EXCEPT when the
|
||||||
|
// content is taller than the viewport (autoOverflow), where the card itself IS the scroll region.
|
||||||
|
ImGuiWindowFlags childScroll = autoOverflow
|
||||||
|
? ImGuiWindowFlags_None
|
||||||
|
: (ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
|
||||||
bool childVisible = ImGui::BeginChild(childId.c_str(),
|
bool childVisible = ImGui::BeginChild(childId.c_str(),
|
||||||
ImVec2(cardWidth, fixedHeight ? (cardBottomY - cardY) : 0.0f),
|
ImVec2(cardWidth, clampedCard ? (cardBottomY - cardY) : 0.0f),
|
||||||
cflags, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
|
cflags, childScroll);
|
||||||
// Floating (portfolio-style) cards: the padding applies to this content child only, so pop it
|
// Floating (portfolio-style) cards: the padding applies to this content child only, so pop it
|
||||||
// now (nested children mustn't inherit it), and center button labels. Net style-var count stays
|
// now (nested children mustn't inherit it), and center button labels. Net style-var count stays
|
||||||
// at 2 (ChildRounding + ButtonTextAlign) so EndOverlayDialog's PopStyleVar(2) is unchanged.
|
// at 2 (ChildRounding + ButtonTextAlign) so EndOverlayDialog's PopStyleVar(2) is unchanged.
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ void RenderCompactHero(App* app, ImDrawList* dl, float availW, float hs, float v
|
|||||||
|
|
||||||
// Render the shared address list section (used by all layouts)
|
// Render the shared address list section (used by all layouts)
|
||||||
void RenderSharedAddressList(App* app, float listH, float availW,
|
void RenderSharedAddressList(App* app, float listH, float availW,
|
||||||
float glassRound, float hs, float vs) {
|
float glassRound, float hs, float vs, float reserveBelow) {
|
||||||
using namespace material;
|
using namespace material;
|
||||||
const auto& S = schema::UISchema::instance();
|
const auto& S = schema::UISchema::instance();
|
||||||
const float dp = Layout::dpiScale();
|
const float dp = Layout::dpiScale();
|
||||||
@@ -225,6 +225,14 @@ void RenderSharedAddressList(App* app, float listH, float availW,
|
|||||||
|
|
||||||
// ---- Glass panel container ----
|
// ---- Glass panel container ----
|
||||||
float addrListH = listH;
|
float addrListH = listH;
|
||||||
|
// Cap the card to the space that actually remains here (measured AFTER the title + toolbar are laid
|
||||||
|
// out, so no chrome modelling is needed) minus what the caller reserves for the section below it
|
||||||
|
// (recent-tx). Without this, a fixed dp-scaled listH grows ~1.5x at high font scale and evicts the
|
||||||
|
// Recent Transactions list off the bottom of the fixed, non-scrolling tab host.
|
||||||
|
if (reserveBelow > 0.0f) {
|
||||||
|
float maxH = ImGui::GetContentRegionAvail().y - reserveBelow;
|
||||||
|
if (maxH < addrListH) addrListH = maxH;
|
||||||
|
}
|
||||||
if (addrListH < 40.0f * dp) addrListH = 40.0f * dp;
|
if (addrListH < 40.0f * dp) addrListH = 40.0f * dp;
|
||||||
|
|
||||||
ImDrawList* dlPanel = ImGui::GetWindowDrawList();
|
ImDrawList* dlPanel = ImGui::GetWindowDrawList();
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ extern bool s_generating_z_address;
|
|||||||
void UpdateBalanceLerp(App* app);
|
void UpdateBalanceLerp(App* app);
|
||||||
void RenderCompactHero(App* app, ImDrawList* dl, float availW, float hs, float vs,
|
void RenderCompactHero(App* app, ImDrawList* dl, float availW, float hs, float vs,
|
||||||
float heroHeightOverride = -1.0f);
|
float heroHeightOverride = -1.0f);
|
||||||
void RenderSharedAddressList(App* app, float listH, float availW, float glassRound, float hs, float vs);
|
void RenderSharedAddressList(App* app, float listH, float availW, float glassRound, float hs, float vs,
|
||||||
|
float reserveBelow = 0.0f);
|
||||||
void RenderSharedRecentTx(App* app, float recentH, float availW, float hs, float vs);
|
void RenderSharedRecentTx(App* app, float recentH, float availW, float hs, float vs);
|
||||||
void RenderSyncBar(App* app, ImDrawList* dl, float vs);
|
void RenderSyncBar(App* app, ImDrawList* dl, float vs);
|
||||||
|
|
||||||
|
|||||||
@@ -661,7 +661,7 @@ static void RenderBalanceClassic(App* app)
|
|||||||
float addrH = (classicAddrH >= 0.0f) ? classicAddrH * dp
|
float addrH = (classicAddrH >= 0.0f) ? classicAddrH * dp
|
||||||
: ImGui::GetContentRegionAvail().y - recentReserve
|
: ImGui::GetContentRegionAvail().y - recentReserve
|
||||||
- Layout::spacingXl() - Type().h6()->LegacySize - Layout::spacingMd();
|
- Layout::spacingXl() - Type().h6()->LegacySize - Layout::spacingMd();
|
||||||
RenderSharedAddressList(app, addrH, contentAvail.x, glassRound, hs, vs);
|
RenderSharedAddressList(app, addrH, contentAvail.x, glassRound, hs, vs, recentReserve);
|
||||||
RenderSharedRecentTx(app, recentReserve, contentAvail.x, hs, vs);
|
RenderSharedRecentTx(app, recentReserve, contentAvail.x, hs, vs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -835,7 +835,7 @@ static void RenderBalanceDonut(App* app) {
|
|||||||
float addrH = (donutAddrOverride >= 0.0f) ? donutAddrOverride * dp
|
float addrH = (donutAddrOverride >= 0.0f) ? donutAddrOverride * dp
|
||||||
: ImGui::GetContentRegionAvail().y - recentReserve
|
: ImGui::GetContentRegionAvail().y - recentReserve
|
||||||
- Layout::spacingXl() - Type().h6()->LegacySize - Layout::spacingMd();
|
- Layout::spacingXl() - Type().h6()->LegacySize - Layout::spacingMd();
|
||||||
RenderSharedAddressList(app, addrH, availW, glassRound, hs, vs);
|
RenderSharedAddressList(app, addrH, availW, glassRound, hs, vs, recentReserve);
|
||||||
RenderSharedRecentTx(app, recentReserve, availW, hs, vs);
|
RenderSharedRecentTx(app, recentReserve, availW, hs, vs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1018,7 +1018,7 @@ static void RenderBalanceConsolidated(App* app) {
|
|||||||
float addrH = (consAddrOverride >= 0.0f) ? consAddrOverride * dp
|
float addrH = (consAddrOverride >= 0.0f) ? consAddrOverride * dp
|
||||||
: ImGui::GetContentRegionAvail().y - recentReserve
|
: ImGui::GetContentRegionAvail().y - recentReserve
|
||||||
- Layout::spacingXl() - Type().h6()->LegacySize - Layout::spacingMd();
|
- Layout::spacingXl() - Type().h6()->LegacySize - Layout::spacingMd();
|
||||||
RenderSharedAddressList(app, addrH, availW, glassRound, hs, vs);
|
RenderSharedAddressList(app, addrH, availW, glassRound, hs, vs, recentReserve);
|
||||||
RenderSharedRecentTx(app, recentReserve, availW, hs, vs);
|
RenderSharedRecentTx(app, recentReserve, availW, hs, vs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1175,7 +1175,7 @@ static void RenderBalanceDashboard(App* app) {
|
|||||||
float addrH = (dashAddrOverride >= 0.0f) ? dashAddrOverride * dp
|
float addrH = (dashAddrOverride >= 0.0f) ? dashAddrOverride * dp
|
||||||
: ImGui::GetContentRegionAvail().y - recentReserve
|
: ImGui::GetContentRegionAvail().y - recentReserve
|
||||||
- Layout::spacingXl() - Type().h6()->LegacySize - Layout::spacingMd();
|
- Layout::spacingXl() - Type().h6()->LegacySize - Layout::spacingMd();
|
||||||
RenderSharedAddressList(app, addrH, availW, glassRound, hs, vs);
|
RenderSharedAddressList(app, addrH, availW, glassRound, hs, vs, recentReserve);
|
||||||
RenderSharedRecentTx(app, recentReserve, availW, hs, vs);
|
RenderSharedRecentTx(app, recentReserve, availW, hs, vs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1354,7 +1354,7 @@ static void RenderBalanceVerticalStack(App* app) {
|
|||||||
float addrH = (vstackAddrOverride >= 0.0f) ? vstackAddrOverride * dp
|
float addrH = (vstackAddrOverride >= 0.0f) ? vstackAddrOverride * dp
|
||||||
: ImGui::GetContentRegionAvail().y - recentReserve
|
: ImGui::GetContentRegionAvail().y - recentReserve
|
||||||
- Layout::spacingXl() - Type().h6()->LegacySize - Layout::spacingMd();
|
- Layout::spacingXl() - Type().h6()->LegacySize - Layout::spacingMd();
|
||||||
RenderSharedAddressList(app, addrH, availW, glassRound, hs, vs);
|
RenderSharedAddressList(app, addrH, availW, glassRound, hs, vs, recentReserve);
|
||||||
RenderSharedRecentTx(app, recentReserve, availW, hs, vs);
|
RenderSharedRecentTx(app, recentReserve, availW, hs, vs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1549,7 +1549,7 @@ static void RenderBalanceVertical2x2(App* app) {
|
|||||||
float addrH = (addrOverride >= 0.0f) ? addrOverride * dp
|
float addrH = (addrOverride >= 0.0f) ? addrOverride * dp
|
||||||
: ImGui::GetContentRegionAvail().y - recentReserve
|
: ImGui::GetContentRegionAvail().y - recentReserve
|
||||||
- Layout::spacingXl() - Type().h6()->LegacySize - Layout::spacingMd();
|
- Layout::spacingXl() - Type().h6()->LegacySize - Layout::spacingMd();
|
||||||
RenderSharedAddressList(app, addrH, availW, glassRound, hs, vs);
|
RenderSharedAddressList(app, addrH, availW, glassRound, hs, vs, recentReserve);
|
||||||
RenderSharedRecentTx(app, recentReserve, availW, hs, vs);
|
RenderSharedRecentTx(app, recentReserve, availW, hs, vs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1731,7 +1731,7 @@ static void RenderBalanceShield(App* app) {
|
|||||||
float addrH = (shieldAddrOverride >= 0.0f) ? shieldAddrOverride * dp
|
float addrH = (shieldAddrOverride >= 0.0f) ? shieldAddrOverride * dp
|
||||||
: ImGui::GetContentRegionAvail().y - recentReserve
|
: ImGui::GetContentRegionAvail().y - recentReserve
|
||||||
- Layout::spacingXl() - Type().h6()->LegacySize - Layout::spacingMd();
|
- Layout::spacingXl() - Type().h6()->LegacySize - Layout::spacingMd();
|
||||||
RenderSharedAddressList(app, addrH, availW, glassRound, hs, vs);
|
RenderSharedAddressList(app, addrH, availW, glassRound, hs, vs, recentReserve);
|
||||||
RenderSharedRecentTx(app, recentReserve, availW, hs, vs);
|
RenderSharedRecentTx(app, recentReserve, availW, hs, vs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1890,7 +1890,7 @@ static void RenderBalanceTimeline(App* app) {
|
|||||||
float addrH = (tlAddrOverride >= 0.0f) ? tlAddrOverride * dp
|
float addrH = (tlAddrOverride >= 0.0f) ? tlAddrOverride * dp
|
||||||
: ImGui::GetContentRegionAvail().y - recentReserve
|
: ImGui::GetContentRegionAvail().y - recentReserve
|
||||||
- Layout::spacingXl() - Type().h6()->LegacySize - Layout::spacingMd();
|
- Layout::spacingXl() - Type().h6()->LegacySize - Layout::spacingMd();
|
||||||
RenderSharedAddressList(app, addrH, availW, glassRound, hs, vs);
|
RenderSharedAddressList(app, addrH, availW, glassRound, hs, vs, recentReserve);
|
||||||
RenderSharedRecentTx(app, recentReserve, availW, hs, vs);
|
RenderSharedRecentTx(app, recentReserve, availW, hs, vs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2081,7 +2081,7 @@ static void RenderBalanceTwoRow(App* app) {
|
|||||||
float addrH = (twoRowAddrOverride >= 0.0f) ? twoRowAddrOverride * dp
|
float addrH = (twoRowAddrOverride >= 0.0f) ? twoRowAddrOverride * dp
|
||||||
: ImGui::GetContentRegionAvail().y - recentReserve
|
: ImGui::GetContentRegionAvail().y - recentReserve
|
||||||
- Layout::spacingXl() - Type().h6()->LegacySize - Layout::spacingMd();
|
- Layout::spacingXl() - Type().h6()->LegacySize - Layout::spacingMd();
|
||||||
RenderSharedAddressList(app, addrH, availW, glassRound, hs, vs);
|
RenderSharedAddressList(app, addrH, availW, glassRound, hs, vs, recentReserve);
|
||||||
RenderSharedRecentTx(app, recentReserve, availW, hs, vs);
|
RenderSharedRecentTx(app, recentReserve, availW, hs, vs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2174,7 +2174,7 @@ static void RenderBalanceMinimal(App* app) {
|
|||||||
float addrH = (minAddrOverride >= 0.0f) ? minAddrOverride * dp
|
float addrH = (minAddrOverride >= 0.0f) ? minAddrOverride * dp
|
||||||
: ImGui::GetContentRegionAvail().y - recentReserve
|
: ImGui::GetContentRegionAvail().y - recentReserve
|
||||||
- Layout::spacingXl() - Type().h6()->LegacySize - Layout::spacingMd();
|
- Layout::spacingXl() - Type().h6()->LegacySize - Layout::spacingMd();
|
||||||
RenderSharedAddressList(app, addrH, availW, glassRound, hs, vs);
|
RenderSharedAddressList(app, addrH, availW, glassRound, hs, vs, recentReserve);
|
||||||
RenderSharedRecentTx(app, recentReserve, availW, hs, vs);
|
RenderSharedRecentTx(app, recentReserve, availW, hs, vs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -478,7 +478,12 @@ void RenderSettingsWindow(App* app, bool* p_open)
|
|||||||
|
|
||||||
// Confirmation dialog
|
// Confirmation dialog
|
||||||
if (s_confirm_clear_ztx) {
|
if (s_confirm_clear_ztx) {
|
||||||
if (material::BeginOverlayDialog(TR("confirm_clear_ztx_title"), &s_confirm_clear_ztx, 480.0f, 0.94f)) {
|
// Distinct idSuffix: this confirm renders nested inside (and the same frame as) the parent
|
||||||
|
// settings dialog, so it must not share the default ##OverlayDialogContent key — otherwise it
|
||||||
|
// inherits the parent's OverlayCardState (incl. the sticky overflow flag) and collides on the
|
||||||
|
// child window id.
|
||||||
|
if (material::BeginOverlayDialog(TR("confirm_clear_ztx_title"), &s_confirm_clear_ztx, 480.0f,
|
||||||
|
0.94f, 0.85f, "settings_clearztx")) {
|
||||||
material::DialogWarningHeader(TR("warning"), ImVec4(1.0f, 0.6f, 0.0f, 1.0f));
|
material::DialogWarningHeader(TR("warning"), ImVec4(1.0f, 0.6f, 0.0f, 1.0f));
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
|
|||||||
Reference in New Issue
Block a user