diff --git a/src/ui/windows/market_tab.cpp b/src/ui/windows/market_tab.cpp index c4423be..b04676d 100644 --- a/src/ui/windows/market_tab.cpp +++ b/src/ui/windows/market_tab.cpp @@ -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& 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);