From 77a0ad64b0fe7261bc5c5c8cf3619305fbcc7229 Mon Sep 17 00:00:00 2001 From: DanS Date: Tue, 21 Jul 2026 17:15:32 -0500 Subject: [PATCH] =?UTF-8?q?feat(settings):=20two-column=20NODE=20&=20SECUR?= =?UTF-8?q?ITY=20card=20(B)=20=E2=80=94=20fill=20the=20empty=20right=20sid?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The NODE & SECURITY card stacked Node / RPC / Security / Daemon-binary in one full-width column, packing everything on the left. Split it into two columns when the card is wide enough: Node + RPC + Security on the left, Daemon binary on the right — which fills the previously-empty right half and roughly halves the card's height. Falls back to a single column on narrow windows (and when there's no daemon section). Implemented by shadowing contentW + sectionOrigin per column (renderSecuritySection already takes an explicit width/origin), so every sub-section lays out within its column; the card auto-sizes to the taller column. Full-node only for now; the lite Node section stays single-column. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/ui/pages/settings_page.cpp | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/ui/pages/settings_page.cpp b/src/ui/pages/settings_page.cpp index 6941bb1..fd71105 100644 --- a/src/ui/pages/settings_page.cpp +++ b/src/ui/pages/settings_page.cpp @@ -1986,6 +1986,17 @@ void RenderSettingsPage(App* app) { const float spMd = Layout::spacingMd(); + // Two-column layout when wide enough: Node / RPC / Security on the left, Daemon binary on + // the right (fills the empty right side + shortens the card). One column when narrow. + const bool nsHasDaemon = app->supportsFullNodeLifecycleActions(); + const float nsColGap = Layout::spacingXl(); + const bool nsTwoCol = nsHasDaemon && contentW > 760.0f * Layout::dpiScale(); + const float nsColW = nsTwoCol ? (contentW - nsColGap) * 0.5f : contentW; + const ImVec2 nsColTop = ImGui::GetCursorScreenPos(); + { // ---- left column (Node / RPC / Security) ---- + const float contentW = nsColW; + const ImVec2 sectionOrigin(nsColTop.x, nsColTop.y); + // -------------------- NODE / DATA -------------------- Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("node")); ImGui::Dummy(ImVec2(0, Layout::spacingXs())); @@ -2146,6 +2157,13 @@ void RenderSettingsPage(App* app) { Type().textColored(TypeStyle::Overline, OnSurfaceMedium(), TR("security")); ImGui::Dummy(ImVec2(0, Layout::spacingXs())); renderSecuritySection(sectionOrigin.x, contentW, /*includeRpcEncrypt=*/true); + } // ---- end left column ---- + const float nsLeftBottom = ImGui::GetCursorScreenPos().y; + if (nsTwoCol) ImGui::SetCursorScreenPos(ImVec2(nsColTop.x + nsColW + nsColGap, nsColTop.y)); + { // ---- right column (Daemon binary) ---- + const float contentW = nsColW; + const ImVec2 sectionOrigin(nsTwoCol ? nsColTop.x + nsColW + nsColGap : nsColTop.x, + nsTwoCol ? nsColTop.y : ImGui::GetCursorScreenPos().y); // -------------------- DAEMON BINARY -------------------- if (app->supportsFullNodeLifecycleActions()) { @@ -2295,11 +2313,11 @@ void RenderSettingsPage(App* app) { ImGui::EndDisabled(); } } + } // ---- end right column ---- + const float nsRightBottom = ImGui::GetCursorScreenPos().y; + ImGui::SetCursorScreenPos(ImVec2(nsColTop.x, nsTwoCol ? std::max(nsLeftBottom, nsRightBottom) : nsRightBottom)); ImGui::PopFont(); - - // Advance to the true bottom of the single column. - ImGui::SetCursorScreenPos(ImVec2(sectionOrigin.x, ImGui::GetCursorScreenPos().y)); } } }