From de48414c65ebbc32f92cb52764a4dd229659e690 Mon Sep 17 00:00:00 2001 From: DanS Date: Tue, 21 Jul 2026 21:01:04 -0500 Subject: [PATCH] =?UTF-8?q?feat(settings):=20hybrid=20masonry=20=E2=80=94?= =?UTF-8?q?=20full-width=20Theme=20+=20About,=20columns=20between?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per feedback, keep Theme & Language and About/Debug full width (they read better wide), and put only Wallet / Node & Security (left) and Explorer / Chat & Contacts (right) in the two-column band. The band captures its top anchor below the Theme card and restores full width before About. Also fix an Explorer bug the two-column band exposed: row 1 placed the Address column with an absolute SameLine(pad + halfW + …) that ignores the right-column Indent, so "Address URL" leaked into the left column. Anchor it to the row's indent-inclusive start X instead (identical result at full width). Co-Authored-By: Claude Opus 4.8 (1M context) --- src/ui/pages/settings_page.cpp | 58 ++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/src/ui/pages/settings_page.cpp b/src/ui/pages/settings_page.cpp index dbd6507..c015c0a 100644 --- a/src/ui/pages/settings_page.cpp +++ b/src/ui/pages/settings_page.cpp @@ -644,13 +644,13 @@ void RenderSettingsPage(App* app) { ImFont* sub1 = Type().subtitle1(); // ==================================================================== - // Masonry: render the section cards in two columns when the page is wide - // enough. Left column: Theme, Wallet, Node & Security. Right column: - // Explorer, Chat & Contacts, About. Debug spans full width below. We shadow - // `availWidth` to the column width for the whole card region (every card - // reads it), and float the right column with Indent() (a one-shot cursor - // set can't hold a column across line-advances). Each card's own responsive - // gates collapse their internal columns at this narrower width. + // Masonry: a full-width Theme & Language card, then a two-column band + // (Wallet / Node & Security on the left; Explorer / Chat & Contacts on the + // right) when the page is wide enough, then full-width About + Debug below. + // Within the band we shadow `availWidth` to the column width (every card + // reads it) and float the right column with Indent() — a one-shot cursor set + // can't hold a column across line-advances. Each card's own responsive gates + // collapse their internal columns at this narrower width. // ==================================================================== const float msFullWidth = availWidth; const float msColGap = Layout::spacingXl(); @@ -659,13 +659,8 @@ void RenderSettingsPage(App* app) { // where the panel's real-px width is smaller in logical terms. const bool msTwoCol = availWidth > 780.0f * Layout::dpiScale(); const float msColW = msTwoCol ? (msFullWidth - msColGap) * 0.5f : msFullWidth; - const ImVec2 msColTop = ImGui::GetCursorPos(); - float msLeftBottomY = 0.0f; - if (msTwoCol) { - availWidth = msColW; - inputW = std::max(S.drawElement("components.settings-page", "input-min-width").size, - availWidth - labelW - pad * 2); - } + ImVec2 msColTop(0.0f, 0.0f); // captured when the two-column band begins (below Theme) + float msLeftBottomY = 0.0f; // ==================================================================== // THEME & LANGUAGE — card (draw-first approach; avoids ChannelsSplit @@ -1323,6 +1318,12 @@ void RenderSettingsPage(App* app) { ImGui::Dummy(ImVec2(0, gap)); + // Begin the two-column band: Wallet / Node & Security fill the left column. + if (msTwoCol) { + msColTop = ImGui::GetCursorPos(); + availWidth = msColW; + } + // ==================================================================== // WALLET — card (privacy/daemon toggles + collapsible tools) // ==================================================================== @@ -2374,9 +2375,9 @@ void RenderSettingsPage(App* app) { } } - // End of the left column (Theme / Wallet / Node & Security). In two-column - // mode jump back to the top and indent so Explorer / Chat / About stack in - // the right column; otherwise just add the usual inter-card gap. + // End of the left column (Wallet / Node & Security). In two-column mode jump + // back to the band's top and indent so Explorer / Chat fill the right column; + // otherwise just add the usual inter-card gap. if (msTwoCol) { msLeftBottomY = ImGui::GetCursorPosY(); ImGui::SetCursorPosY(msColTop.y); @@ -2405,13 +2406,16 @@ void RenderSettingsPage(App* app) { float inputTxW = std::max(80.0f, halfW - lblTxW); float inputAddrW = std::max(80.0f, halfW - lblAddrW); + // Row start X (indent-inclusive) — the Address column is placed relative + // to it, not to a fixed `pad`, so it lands correctly in the right column. + const float expRowX = ImGui::GetCursorPosX(); ImGui::AlignTextToFramePadding(); ImGui::TextUnformatted(TR("transaction_url")); ImGui::SameLine(0, Layout::spacingXs()); ImGui::SetNextItemWidth(inputTxW); ImGui::InputText("##TxExplorer", s_settingsState.tx_explorer, sizeof(s_settingsState.tx_explorer)); if (ImGui::IsItemHovered()) material::Tooltip("%s", TR("tt_tx_url")); - ImGui::SameLine(pad + halfW + Layout::spacingLg()); + ImGui::SameLine(expRowX + halfW + Layout::spacingLg()); ImGui::AlignTextToFramePadding(); ImGui::TextUnformatted(TR("address_url")); ImGui::SameLine(0, Layout::spacingXs()); @@ -2458,6 +2462,15 @@ void RenderSettingsPage(App* app) { ImGui::PopFont(); } + // End of the two-column band. Un-indent, drop below the taller column, and + // restore full width so About + Debug span the page. + if (msTwoCol) { + ImGui::Unindent(msColW + msColGap); + const float msRightBottomY = ImGui::GetCursorPosY(); + ImGui::SetCursorPosX(msColTop.x); + ImGui::SetCursorPosY(std::max(msLeftBottomY, msRightBottomY)); + availWidth = msFullWidth; + } ImGui::Dummy(ImVec2(0, gap)); // ==================================================================== @@ -2599,15 +2612,6 @@ void RenderSettingsPage(App* app) { ImGui::Dummy(ImVec2(availWidth, 0)); } - // End of the right column. Un-indent, drop below the taller of the two - // columns, and restore full width so Debug spans the page. - if (msTwoCol) { - ImGui::Unindent(msColW + msColGap); - const float msRightBottomY = ImGui::GetCursorPosY(); - ImGui::SetCursorPosX(msColTop.x); - ImGui::SetCursorPosY(std::max(msLeftBottomY, msRightBottomY)); - availWidth = msFullWidth; - } ImGui::Dummy(ImVec2(0, gap)); // ====================================================================