From f1e66c08d143b2b7a73314b8bc8f752dc2c76eb5 Mon Sep 17 00:00:00 2001 From: DanS Date: Sat, 4 Jul 2026 20:12:15 -0500 Subject: [PATCH] refactor(ui): adopt material::IconButton for the idle/scale/gpu mining toggles Follow-up to c83348a: convert the three mining solo-mode header toggles (idle-mining, thread-scaling, gpu-aware) from the hand-rolled "draw active pill + glyph, then hit-test" idiom to material::IconButton using the restBg (active-pill) path. Each keeps its exact behavior pixel-for-pixel: a circular Primary-tinted pill when active (alpha 60 idle / 40 scale+gpu), a state-colored glyph (Primary when on, muted when off), hand cursor + tooltip on hover, and the idle button's cursor save/restore (savedCur, restored at block end) is preserved. Completes the clean icon-button adoption; the raw-rect IsRectHovered sites remain intentionally separate (different hit mechanism). Co-Authored-By: Claude Opus 4.8 (1M context) --- src/ui/windows/mining_controls.cpp | 79 +++++++----------------------- 1 file changed, 18 insertions(+), 61 deletions(-) diff --git a/src/ui/windows/mining_controls.cpp b/src/ui/windows/mining_controls.cpp index b7fbe9c..92846c6 100644 --- a/src/ui/windows/mining_controls.cpp +++ b/src/ui/windows/mining_controls.cpp @@ -124,31 +124,17 @@ void RenderMiningControls(App* app, const WalletState& state, const MiningInfo& float btnX = idleRightEdge - btnSz; float btnY = curY + (headerH - btnSz) * 0.5f; - // Pill background when active - if (idleOn) { - dl->AddRectFilled(ImVec2(btnX, btnY), ImVec2(btnX + btnSz, btnY + btnSz), - WithAlpha(Primary(), 60), btnSz * 0.5f); - } - - // Icon centered in button - ImVec2 icoSz = icoFont->CalcTextSizeA(icoFont->LegacySize, FLT_MAX, 0, idleIcon); - ImU32 icoCol = idleOn ? Primary() : OnSurfaceDisabled(); - dl->AddText(icoFont, icoFont->LegacySize, - ImVec2(btnX + (btnSz - icoSz.x) * 0.5f, btnY + (btnSz - icoSz.y) * 0.5f), - icoCol, idleIcon); - - // Click target (save/restore cursor so layout is unaffected) + // Idle toggle: active pill + state-colored glyph (cursor saved/restored at block end). + material::IconButtonStyle st; + st.color = idleOn ? Primary() : OnSurfaceDisabled(); + st.restBg = idleOn ? WithAlpha(Primary(), 60) : 0; + st.tooltip = idleOn ? TR("mining_idle_on_tooltip") : TR("mining_idle_off_tooltip"); ImVec2 savedCur = ImGui::GetCursorScreenPos(); ImGui::SetCursorScreenPos(ImVec2(btnX, btnY)); - ImGui::InvisibleButton("##IdleMining", ImVec2(btnSz, btnSz)); - if (ImGui::IsItemClicked()) { + if (material::IconButton("##IdleMining", idleIcon, icoFont, ImVec2(btnSz, btnSz), st)) { app->settings()->setMineWhenIdle(!idleOn); app->settings()->save(); } - if (ImGui::IsItemHovered()) { - ImGui::SetMouseCursor(ImGuiMouseCursor_Hand); - material::Tooltip("%s", idleOn ? TR("mining_idle_on_tooltip") : TR("mining_idle_off_tooltip")); - } idleRightEdge = btnX - 4.0f * dp; @@ -157,30 +143,16 @@ void RenderMiningControls(App* app, const WalletState& state, const MiningInfo& const char* scaleIcon = threadScaling ? ICON_MD_TUNE : ICON_MD_POWER_SETTINGS_NEW; float sBtnX = idleRightEdge - btnSz; float sBtnY = btnY; - - if (threadScaling) { - dl->AddRectFilled(ImVec2(sBtnX, sBtnY), ImVec2(sBtnX + btnSz, sBtnY + btnSz), - WithAlpha(Primary(), 40), btnSz * 0.5f); - } - - ImVec2 sIcoSz = icoFont->CalcTextSizeA(icoFont->LegacySize, FLT_MAX, 0, scaleIcon); - ImU32 sIcoCol = threadScaling ? Primary() : OnSurfaceMedium(); - dl->AddText(icoFont, icoFont->LegacySize, - ImVec2(sBtnX + (btnSz - sIcoSz.x) * 0.5f, sBtnY + (btnSz - sIcoSz.y) * 0.5f), - sIcoCol, scaleIcon); - + material::IconButtonStyle st; + st.color = threadScaling ? Primary() : OnSurfaceMedium(); + st.restBg = threadScaling ? WithAlpha(Primary(), 40) : 0; + st.tooltip = threadScaling ? TR("mining_idle_scale_on_tooltip") + : TR("mining_idle_scale_off_tooltip"); ImGui::SetCursorScreenPos(ImVec2(sBtnX, sBtnY)); - ImGui::InvisibleButton("##IdleScaleMode", ImVec2(btnSz, btnSz)); - if (ImGui::IsItemClicked()) { + if (material::IconButton("##IdleScaleMode", scaleIcon, icoFont, ImVec2(btnSz, btnSz), st)) { app->settings()->setIdleThreadScaling(!threadScaling); app->settings()->save(); } - if (ImGui::IsItemHovered()) { - ImGui::SetMouseCursor(ImGuiMouseCursor_Hand); - material::Tooltip("%s", threadScaling - ? TR("mining_idle_scale_on_tooltip") - : TR("mining_idle_scale_off_tooltip")); - } idleRightEdge = sBtnX - 4.0f * dp; } @@ -189,33 +161,18 @@ void RenderMiningControls(App* app, const WalletState& state, const MiningInfo& // When OFF: unrestricted mode, only keyboard/mouse input matters if (idleOn) { bool gpuAware = app->settings()->getIdleGpuAware(); - const char* gpuIcon = gpuAware ? ICON_MD_MONITOR : ICON_MD_MONITOR; float gBtnX = idleRightEdge - btnSz; float gBtnY = btnY; - - if (gpuAware) { - dl->AddRectFilled(ImVec2(gBtnX, gBtnY), ImVec2(gBtnX + btnSz, gBtnY + btnSz), - WithAlpha(Primary(), 40), btnSz * 0.5f); - } - - ImVec2 gIcoSz = icoFont->CalcTextSizeA(icoFont->LegacySize, FLT_MAX, 0, gpuIcon); - ImU32 gIcoCol = gpuAware ? Primary() : OnSurfaceDisabled(); - dl->AddText(icoFont, icoFont->LegacySize, - ImVec2(gBtnX + (btnSz - gIcoSz.x) * 0.5f, gBtnY + (btnSz - gIcoSz.y) * 0.5f), - gIcoCol, gpuIcon); - + material::IconButtonStyle st; + st.color = gpuAware ? Primary() : OnSurfaceDisabled(); + st.restBg = gpuAware ? WithAlpha(Primary(), 40) : 0; + st.tooltip = gpuAware ? TR("mining_idle_gpu_on_tooltip") + : TR("mining_idle_gpu_off_tooltip"); ImGui::SetCursorScreenPos(ImVec2(gBtnX, gBtnY)); - ImGui::InvisibleButton("##IdleGpuAware", ImVec2(btnSz, btnSz)); - if (ImGui::IsItemClicked()) { + if (material::IconButton("##IdleGpuAware", ICON_MD_MONITOR, icoFont, ImVec2(btnSz, btnSz), st)) { app->settings()->setIdleGpuAware(!gpuAware); app->settings()->save(); } - if (ImGui::IsItemHovered()) { - ImGui::SetMouseCursor(ImGuiMouseCursor_Hand); - material::Tooltip("%s", gpuAware - ? TR("mining_idle_gpu_on_tooltip") - : TR("mining_idle_gpu_off_tooltip")); - } idleRightEdge = gBtnX - 4.0f * dp; }