refactor(market): extract pfSegmentedControl helper
Collapse the two identical equal-width segmented controls (the detail section switcher Appearance/Price/Addresses and the address type filter All/Shielded/Transparent) into one pfSegmentedControl(dl, origin, w, h, labels, count, selected, font, idBase, dp) that returns the clicked index. Same track / active-pill / centered-label drawing and per-cell hit-test as before; the variable-width chart-interval strip is left as-is. No behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -286,6 +286,40 @@ static void pfRightAlignX(float w)
|
||||
if (avail > w) ImGui::SetCursorPosX(ImGui::GetCursorPosX() + avail - w);
|
||||
}
|
||||
|
||||
// Draw an equal-width segmented control (rounded track + N cells, each with a centered label and an
|
||||
// active pill) at screen-space `origin`, spanning `totalW` x `height`. Every cell is a hit-tested
|
||||
// InvisibleButton (Hand cursor on hover), disambiguated by `idBase`. Does NOT move the layout cursor
|
||||
// afterward — the caller positions the next content. Returns the clicked cell index, or -1.
|
||||
static int pfSegmentedControl(ImDrawList* dl, ImVec2 origin, float totalW, float height,
|
||||
const char* const* labels, int count, int selected,
|
||||
ImFont* font, const char* idBase, float dp)
|
||||
{
|
||||
int clicked = -1;
|
||||
float cellW = totalW / (float)count;
|
||||
dl->AddRectFilled(origin, ImVec2(origin.x + totalW, origin.y + height),
|
||||
WithAlpha(OnSurface(), 20), height * 0.5f);
|
||||
for (int i = 0; i < count; i++) {
|
||||
ImVec2 cMin(origin.x + i * cellW, origin.y), cMax(cMin.x + cellW, origin.y + height);
|
||||
bool active = (selected == i);
|
||||
bool hov = ImGui::IsMouseHoveringRect(cMin, cMax);
|
||||
if (active)
|
||||
dl->AddRectFilled(ImVec2(cMin.x + 2.0f * dp, cMin.y + 2.0f * dp),
|
||||
ImVec2(cMax.x - 2.0f * dp, cMax.y - 2.0f * dp),
|
||||
WithAlpha(Primary(), 210), (height - 4.0f * dp) * 0.5f);
|
||||
ImVec2 ts = font->CalcTextSizeA(font->LegacySize, FLT_MAX, 0, labels[i]);
|
||||
dl->AddText(font, font->LegacySize,
|
||||
ImVec2(cMin.x + (cellW - ts.x) * 0.5f, cMin.y + (height - ts.y) * 0.5f),
|
||||
active ? IM_COL32(255, 255, 255, 255) : (hov ? OnSurface() : OnSurfaceMedium()),
|
||||
labels[i]);
|
||||
ImGui::PushID(i);
|
||||
ImGui::SetCursorScreenPos(cMin);
|
||||
if (ImGui::InvisibleButton(idBase, ImVec2(cellW, height))) clicked = i;
|
||||
if (ImGui::IsItemHovered()) ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
|
||||
ImGui::PopID();
|
||||
}
|
||||
return clicked;
|
||||
}
|
||||
|
||||
static void pfDrawSparkline(ImDrawList* dl, ImVec2 mn, ImVec2 mx,
|
||||
const std::vector<double>& hist, ImU32 col)
|
||||
{
|
||||
@@ -757,29 +791,10 @@ static void RenderPortfolioEditor(App* app)
|
||||
TR("portfolio_addresses_hdr") };
|
||||
float segH = 30.0f * dp;
|
||||
float segW = ImGui::GetContentRegionAvail().x;
|
||||
float cellW = segW / 3.0f;
|
||||
ImVec2 sMin = ImGui::GetCursorScreenPos();
|
||||
ImDrawList* sdl = ImGui::GetWindowDrawList();
|
||||
sdl->AddRectFilled(sMin, ImVec2(sMin.x + segW, sMin.y + segH), WithAlpha(OnSurface(), 20), segH * 0.5f);
|
||||
for (int s = 0; s < 3; s++) {
|
||||
ImVec2 cMin(sMin.x + s * cellW, sMin.y), cMax(cMin.x + cellW, sMin.y + segH);
|
||||
bool active = (s_pf_section == s);
|
||||
bool hov = ImGui::IsMouseHoveringRect(cMin, cMax);
|
||||
if (active)
|
||||
sdl->AddRectFilled(ImVec2(cMin.x + 2.0f * dp, cMin.y + 2.0f * dp),
|
||||
ImVec2(cMax.x - 2.0f * dp, cMax.y - 2.0f * dp),
|
||||
WithAlpha(Primary(), 210), (segH - 4.0f * dp) * 0.5f);
|
||||
ImVec2 ts = body2f->CalcTextSizeA(body2f->LegacySize, FLT_MAX, 0, secs[s]);
|
||||
sdl->AddText(body2f, body2f->LegacySize,
|
||||
ImVec2(cMin.x + (cellW - ts.x) * 0.5f, cMin.y + (segH - ts.y) * 0.5f),
|
||||
active ? IM_COL32(255, 255, 255, 255) : (hov ? OnSurface() : OnSurfaceMedium()),
|
||||
secs[s]);
|
||||
ImGui::PushID(s);
|
||||
ImGui::SetCursorScreenPos(cMin);
|
||||
if (ImGui::InvisibleButton("##pfseg", ImVec2(cellW, segH))) s_pf_section = s;
|
||||
if (ImGui::IsItemHovered()) ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
|
||||
ImGui::PopID();
|
||||
}
|
||||
int clk = pfSegmentedControl(ImGui::GetWindowDrawList(), sMin, segW, segH,
|
||||
secs, 3, s_pf_section, body2f, "##pfseg", dp);
|
||||
if (clk >= 0) s_pf_section = clk;
|
||||
ImGui::SetCursorScreenPos(ImVec2(sMin.x, sMin.y + segH));
|
||||
ImGui::Dummy(ImVec2(segW, 0));
|
||||
}
|
||||
@@ -1016,29 +1031,9 @@ static void RenderPortfolioEditor(App* app)
|
||||
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;
|
||||
ImDrawList* fdl = ImGui::GetWindowDrawList();
|
||||
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(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)
|
||||
fdl->AddRectFilled(ImVec2(cMin.x + 2.0f * dp, cMin.y + 2.0f * dp),
|
||||
ImVec2(cMax.x - 2.0f * dp, cMax.y - 2.0f * dp),
|
||||
WithAlpha(Primary(), 210), (segH - 4.0f * dp) * 0.5f);
|
||||
ImVec2 ts = capF->CalcTextSizeA(capF->LegacySize, FLT_MAX, 0, flabels[f]);
|
||||
fdl->AddText(capF, capF->LegacySize,
|
||||
ImVec2(cMin.x + (cellW - ts.x) * 0.5f, cMin.y + (segH - ts.y) * 0.5f),
|
||||
active ? IM_COL32(255, 255, 255, 255) : (hov ? OnSurface() : OnSurfaceMedium()),
|
||||
flabels[f]);
|
||||
ImGui::PushID(3100 + f);
|
||||
ImGui::SetCursorScreenPos(cMin);
|
||||
if (ImGui::InvisibleButton("##pftf", ImVec2(cellW, segH))) s_pf_type_filter = f;
|
||||
if (ImGui::IsItemHovered()) ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
|
||||
ImGui::PopID();
|
||||
}
|
||||
int tclk = pfSegmentedControl(ImGui::GetWindowDrawList(), ImVec2(rowStart.x, segY),
|
||||
segW, segH, flabels, 3, s_pf_type_filter, capF, "##pftf", dp);
|
||||
if (tclk >= 0) s_pf_type_filter = tclk;
|
||||
// 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);
|
||||
|
||||
Reference in New Issue
Block a user