feat(market): combine portfolio address filter + selection onto one row
Merge the two address-section rows into one: the All/Shielded/Transparent segmented type filter sits on the left and Select all / Clear / Funded are right-aligned on the same line, both vertically centered. Select-all is deferred to a flag applied after the filtered set is built, so it still targets the current filter (and stays idempotent via PortfolioEntryAdd's dedup). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -987,18 +987,34 @@ static void RenderPortfolioEditor(App* app)
|
||||
ImGui::SetNextItemWidth(-1);
|
||||
ImGui::InputTextWithHint("##pfSearch", TR("portfolio_search"), s_pf_search, sizeof(s_pf_search));
|
||||
ImGui::Dummy(ImVec2(0, Layout::spacingXs()));
|
||||
// Type filter — segmented control on its own row (compact).
|
||||
// Filter + selection on one row: type-filter segmented (left) + Select all / Clear /
|
||||
// Funded (right). Select-all is deferred so it applies to the freshly-filtered set below.
|
||||
bool selAllClicked = false;
|
||||
{
|
||||
const char* flabels[3] = { TR("portfolio_select_all"), TR("shielded"), TR("transparent") };
|
||||
const char* selLbl = TR("portfolio_select_shown");
|
||||
const char* clrLbl = TR("portfolio_clear_sel");
|
||||
ImGuiStyle& st = ImGui::GetStyle();
|
||||
ImVec2 pillPad(Layout::spacingLg(), Layout::spacingSm()); // roomier text padding
|
||||
float defFrameH = ImGui::GetFrameHeight();
|
||||
float fundedW = defFrameH + st.ItemInnerSpacing.x + ImGui::CalcTextSize(TR("portfolio_funded")).x;
|
||||
float pillH = ImGui::GetTextLineHeight() + pillPad.y * 2.0f;
|
||||
float selW = ImGui::CalcTextSize(selLbl).x + pillPad.x * 2.0f;
|
||||
float clrW = ImGui::CalcTextSize(clrLbl).x + pillPad.x * 2.0f;
|
||||
float groupW = selW + clrW + fundedW + st.ItemSpacing.x * 2.0f;
|
||||
float segH = 26.0f * dp;
|
||||
float availW = ImGui::GetContentRegionAvail().x;
|
||||
float segW = std::min(availW, 360.0f * dp);
|
||||
float rowW = ImGui::GetContentRegionAvail().x;
|
||||
float segW = std::min(360.0f * dp, std::max(160.0f * dp, rowW - groupW - Layout::spacingMd()));
|
||||
float rowH = std::max(segH, pillH);
|
||||
ImVec2 rowStart = ImGui::GetCursorScreenPos();
|
||||
// Segmented type filter (left), vertically centered in the row.
|
||||
float segY = rowStart.y + (rowH - segH) * 0.5f;
|
||||
float cellW = segW / 3.0f;
|
||||
ImVec2 sMin = ImGui::GetCursorScreenPos();
|
||||
ImDrawList* fdl = ImGui::GetWindowDrawList();
|
||||
fdl->AddRectFilled(sMin, ImVec2(sMin.x + segW, sMin.y + segH), WithAlpha(OnSurface(), 20), segH * 0.5f);
|
||||
fdl->AddRectFilled(ImVec2(rowStart.x, segY), ImVec2(rowStart.x + segW, segY + segH),
|
||||
WithAlpha(OnSurface(), 20), segH * 0.5f);
|
||||
for (int f = 0; f < 3; f++) {
|
||||
ImVec2 cMin(sMin.x + f * cellW, sMin.y), cMax(cMin.x + cellW, sMin.y + segH);
|
||||
ImVec2 cMin(rowStart.x + f * cellW, segY), cMax(cMin.x + cellW, segY + segH);
|
||||
bool active = (s_pf_type_filter == f);
|
||||
bool hov = ImGui::IsMouseHoveringRect(cMin, cMax);
|
||||
if (active)
|
||||
@@ -1016,8 +1032,21 @@ static void RenderPortfolioEditor(App* app)
|
||||
if (ImGui::IsItemHovered()) ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
|
||||
ImGui::PopID();
|
||||
}
|
||||
ImGui::SetCursorScreenPos(ImVec2(sMin.x, sMin.y + segH));
|
||||
ImGui::Dummy(ImVec2(availW, 0));
|
||||
// Select all / Clear (rounded pills) + Funded toggle (right), vertically centered.
|
||||
float grpX = rowStart.x + std::max(0.0f, rowW - groupW);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 12.0f * dp);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, pillPad);
|
||||
ImGui::SetCursorScreenPos(ImVec2(grpX, rowStart.y + (rowH - pillH) * 0.5f));
|
||||
if (ImGui::Button(selLbl)) selAllClicked = true;
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(clrLbl)) s_pf_addrs.clear();
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorScreenPos(ImVec2(ImGui::GetCursorScreenPos().x,
|
||||
rowStart.y + (rowH - defFrameH) * 0.5f)); // center vs. pills
|
||||
ImGui::Checkbox(TR("portfolio_funded"), &s_pf_funded_only);
|
||||
ImGui::SetCursorScreenPos(ImVec2(rowStart.x, rowStart.y + rowH));
|
||||
ImGui::Dummy(ImVec2(rowW, 0));
|
||||
}
|
||||
ImGui::Dummy(ImVec2(0, Layout::spacingXs()));
|
||||
std::string search = s_pf_search;
|
||||
@@ -1038,36 +1067,8 @@ static void RenderPortfolioEditor(App* app)
|
||||
if (sx != sy) return sx;
|
||||
return x->balance > y->balance;
|
||||
});
|
||||
// Select all / Clear (rounded pills) + Funded toggle — one row, right-aligned.
|
||||
{
|
||||
const char* selLbl = TR("portfolio_select_shown");
|
||||
const char* clrLbl = TR("portfolio_clear_sel");
|
||||
ImGuiStyle& st = ImGui::GetStyle();
|
||||
ImVec2 pillPad(Layout::spacingLg(), Layout::spacingSm()); // roomier text padding
|
||||
// Measure the checkbox at default padding and the pills at their (larger) padding, so
|
||||
// the whole group can be right-aligned before it's drawn.
|
||||
float defFrameH = ImGui::GetFrameHeight();
|
||||
float fundedW = defFrameH + st.ItemInnerSpacing.x + ImGui::CalcTextSize(TR("portfolio_funded")).x;
|
||||
float pillH = ImGui::GetTextLineHeight() + pillPad.y * 2.0f;
|
||||
float selW = ImGui::CalcTextSize(selLbl).x + pillPad.x * 2.0f;
|
||||
float clrW = ImGui::CalcTextSize(clrLbl).x + pillPad.x * 2.0f;
|
||||
float groupW = selW + clrW + fundedW + st.ItemSpacing.x * 2.0f;
|
||||
float rowH = std::max(pillH, defFrameH);
|
||||
float rowY = ImGui::GetCursorPosY();
|
||||
float availW = ImGui::GetContentRegionAvail().x;
|
||||
if (availW > groupW) ImGui::SetCursorPosX(ImGui::GetCursorPosX() + availW - groupW);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 12.0f * dp);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, pillPad);
|
||||
ImGui::SetCursorPosY(rowY + (rowH - pillH) * 0.5f);
|
||||
if (ImGui::Button(selLbl))
|
||||
for (const AddressInfo* a : filtered) data::PortfolioEntryAdd(s_pf_addrs, a->address);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(clrLbl)) s_pf_addrs.clear();
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosY(rowY + (rowH - defFrameH) * 0.5f); // center vs. pills
|
||||
ImGui::Checkbox(TR("portfolio_funded"), &s_pf_funded_only);
|
||||
}
|
||||
if (selAllClicked)
|
||||
for (const AddressInfo* a : filtered) data::PortfolioEntryAdd(s_pf_addrs, a->address);
|
||||
ImGui::Dummy(ImVec2(0, Layout::spacingXs()));
|
||||
ImDrawList* ldl = pfBeginScrollChild("##pfAddrList", s_pf_addr_fade,
|
||||
ImVec2(Layout::spacingMd(), Layout::spacingSm()), dp);
|
||||
|
||||
Reference in New Issue
Block a user