style(balance): use the shared SegmentedControl for the earnings toolbar
The Overview earnings controls (interval 1H/1D/1M/1Y, received/net mode, and the global show-all toggle) were ad-hoc ImGui buttons. They now use material::SegmentedControl -- the same rounded-track pill the Receive tab's All/Shielded/Mining filter uses -- so the interval is a text segmented control, the mode is two icon segments with per-segment tooltips, and the toggle is a single matching segment (highlighted when on). Verified in a headless GL capture. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -260,45 +260,64 @@ void RenderSharedAddressList(App* app, float listH, float availW,
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Inline period-earnings controls: interval pills (1H/1D/1M/1Y), mode toggle (received /
|
||||
// net), and a global show-all toggle. The create-address buttons moved below the list (footer). ----
|
||||
// ---- Inline period-earnings controls: interval (1H/1D/1M/1Y) + mode (received / net) + a global
|
||||
// show-all toggle, all drawn as Material segmented controls to match the Receive-tab filter. The
|
||||
// create-address buttons moved below the list (footer) to make room. ----
|
||||
if (app->settings()) {
|
||||
auto* est = app->settings();
|
||||
ImFont* capF = Type().caption();
|
||||
ImFont* icoF = Type().iconSmall();
|
||||
const float segH = ImGui::GetFrameHeight(); // fixed height so pills + icon buttons align
|
||||
// A compact selected/unselected toggle. `font` nullptr = default font (text pills).
|
||||
auto segBtn = [&](const char* idlabel, bool selected, const char* tip, ImFont* font) -> bool {
|
||||
if (font) ImGui::PushFont(font);
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, selected ? WithAlpha(Primary(), 70) : IM_COL32(255, 255, 255, 12));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, WithAlpha(Primary(), 110));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, WithAlpha(Primary(), 140));
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(selected ? OnSurface() : OnSurfaceMedium()));
|
||||
bool clk = ImGui::Button(idlabel, ImVec2(0, segH));
|
||||
ImGui::PopStyleColor(4);
|
||||
if (font) ImGui::PopFont();
|
||||
if (tip && ImGui::IsItemHovered()) material::Tooltip("%s", tip);
|
||||
return clk;
|
||||
};
|
||||
ImDrawList* wdl = ImGui::GetWindowDrawList();
|
||||
const float segH = ImGui::GetFrameHeight();
|
||||
|
||||
ImGui::SameLine(0, Layout::spacingLg());
|
||||
// Interval pills
|
||||
const float rowStartX = ImGui::GetCursorScreenPos().x;
|
||||
const float rowY = ImGui::GetCursorScreenPos().y;
|
||||
float x = rowStartX;
|
||||
|
||||
// Interval (1H/1D/1M/1Y) — text segments sized to the widest label, like the Receive filter.
|
||||
const char* ivText[4] = { "1H", "1D", "1M", "1Y" };
|
||||
float ivCellW = segH;
|
||||
for (const char* t : ivText)
|
||||
ivCellW = std::max(ivCellW, capF->CalcTextSizeA(capF->LegacySize, FLT_MAX, 0, t).x + 2.0f * Layout::spacingMd());
|
||||
const float ivTotalW = ivCellW * 4;
|
||||
int iv = est->getEarningsInterval();
|
||||
for (int k = 0; k < 4; ++k) {
|
||||
char lbl[16]; snprintf(lbl, sizeof(lbl), "%s##earniv%d", ivText[k], k);
|
||||
if (segBtn(lbl, iv == k, TR("tt_earn_interval"), nullptr)) { est->setEarningsInterval(k); est->save(); }
|
||||
if (k < 3) ImGui::SameLine(0, 2.0f * dp);
|
||||
}
|
||||
// Mode toggle (received-only vs net)
|
||||
ImGui::SameLine(0, Layout::spacingMd());
|
||||
int ivClk = material::SegmentedControl(wdl, ImVec2(x, rowY), ivTotalW, segH, ivText, 4, iv, capF, "##earniv", dp);
|
||||
if (ivClk >= 0) { est->setEarningsInterval(ivClk); est->save(); }
|
||||
if (ImGui::IsMouseHoveringRect(ImVec2(x, rowY), ImVec2(x + ivTotalW, rowY + segH)))
|
||||
material::Tooltip("%s", TR("tt_earn_interval"));
|
||||
x += ivTotalW + Layout::spacingMd();
|
||||
|
||||
// Mode (received-only vs net) — two icon segments.
|
||||
const char* modeIcons[2] = { ICON_MD_CALL_RECEIVED, ICON_MD_SWAP_VERT };
|
||||
float modeCellW = segH;
|
||||
for (const char* t : modeIcons)
|
||||
modeCellW = std::max(modeCellW, icoF->CalcTextSizeA(icoF->LegacySize, FLT_MAX, 0, t).x + 2.0f * Layout::spacingSm());
|
||||
const float modeTotalW = modeCellW * 2;
|
||||
int emode = est->getEarningsMode();
|
||||
if (segBtn(ICON_MD_CALL_RECEIVED "##earnmodein", emode == 0, TR("tt_earn_mode_inflows"), icoF)) { est->setEarningsMode(0); est->save(); }
|
||||
ImGui::SameLine(0, 2.0f * dp);
|
||||
if (segBtn(ICON_MD_SWAP_VERT "##earnmodenet", emode == 1, TR("tt_earn_mode_net"), icoF)) { est->setEarningsMode(1); est->save(); }
|
||||
// Global earnings-column toggle
|
||||
ImGui::SameLine(0, Layout::spacingMd());
|
||||
int modeClk = material::SegmentedControl(wdl, ImVec2(x, rowY), modeTotalW, segH, modeIcons, 2, emode, icoF, "##earnmode", dp);
|
||||
if (modeClk >= 0) { est->setEarningsMode(modeClk); est->save(); }
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
ImVec2 cMin(x + i * modeCellW, rowY), cMax(cMin.x + modeCellW, rowY + segH);
|
||||
if (ImGui::IsMouseHoveringRect(cMin, cMax))
|
||||
material::Tooltip("%s", i == 0 ? TR("tt_earn_mode_inflows") : TR("tt_earn_mode_net"));
|
||||
}
|
||||
x += modeTotalW + Layout::spacingMd();
|
||||
|
||||
// Global earnings-column toggle — a single matching segment (highlighted when on).
|
||||
const char* togIcon[1] = { ICON_MD_TRENDING_UP };
|
||||
float togW = std::max(segH, icoF->CalcTextSizeA(icoF->LegacySize, FLT_MAX, 0, togIcon[0]).x + 2.0f * Layout::spacingSm());
|
||||
bool showAll = est->getEarningsShowAll();
|
||||
if (segBtn(ICON_MD_TRENDING_UP "##earnshowall", showAll, TR("tt_earn_show_all"), icoF)) { est->setEarningsShowAll(!showAll); est->save(); }
|
||||
int togClk = material::SegmentedControl(wdl, ImVec2(x, rowY), togW, segH, togIcon, 1, showAll ? 0 : -1, icoF, "##earnshowall", dp);
|
||||
if (togClk == 0) { est->setEarningsShowAll(!showAll); est->save(); }
|
||||
if (ImGui::IsMouseHoveringRect(ImVec2(x, rowY), ImVec2(x + togW, rowY + segH)))
|
||||
material::Tooltip("%s", TR("tt_earn_show_all"));
|
||||
x += togW;
|
||||
|
||||
// Reserve the controls' row as one layout item so the cursor drops below it (the segmented
|
||||
// controls draw absolutely + hit-test with their own InvisibleButtons).
|
||||
ImGui::SetCursorScreenPos(ImVec2(rowStartX, rowY));
|
||||
ImGui::Dummy(ImVec2(x - rowStartX, segH));
|
||||
}
|
||||
|
||||
ImGui::Dummy(ImVec2(0, Layout::spacingXs()));
|
||||
|
||||
Reference in New Issue
Block a user