feat(market): fix portfolio Add button clipping; add accordion summaries
- Add button can no longer be cut off: it's now a normal widget below the group
list (in a group with the scroll child) instead of nested inside the list child.
- Stop the modal's 28x20 WindowPadding from cascading into the nested master/detail/
list children (pop it right after the card child begins) — that double-padding
was squeezing the master column and the Add button.
- Right pane navigability: collapsed accordion sections now show a compact summary
on the right (Appearance -> icon, Price -> basis, Addresses -> N selected), so a
group's state is readable without expanding. Section titles are consistent
title-case ("Appearance"/"Price"/"Addresses").
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -427,6 +427,7 @@ static void RenderPortfolioEditor(App* app)
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(28.0f, 20.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(0, 0, 0, 0));
|
||||
ImGui::BeginChild("##pfCard", ImVec2(cardW, cardH), ImGuiChildFlags_None, ImGuiWindowFlags_NoScrollbar);
|
||||
ImGui::PopStyleVar(); // pop WindowPadding — the 28x20 applies to ##pfCard only, not nested children
|
||||
|
||||
material::DrawDialogTitleBar(TR("portfolio_manage_title"), &s_portfolio_editor_open);
|
||||
if (ImGui::IsKeyPressed(ImGuiKey_Escape)) s_portfolio_editor_open = false;
|
||||
@@ -443,13 +444,12 @@ static void RenderPortfolioEditor(App* app)
|
||||
float masterW = std::min(std::max(contentW * 0.28f, 240.0f * dp), 320.0f * dp);
|
||||
float detailW = contentW - masterW - gap;
|
||||
|
||||
// ================= MASTER: group list =================
|
||||
ImGui::BeginChild("##pfMaster", ImVec2(masterW, bodyH), false, ImGuiWindowFlags_NoScrollbar);
|
||||
// ================= MASTER: scrollable group list + a pinned Add button below it =================
|
||||
float addH = 34.0f * dp;
|
||||
ImGui::BeginGroup();
|
||||
{
|
||||
const auto& entries = settings->getPortfolioEntries();
|
||||
float addH = 30.0f * dp;
|
||||
ImGui::BeginChild("##pfMasterList",
|
||||
ImVec2(0, std::max(48.0f, ImGui::GetContentRegionAvail().y - addH - Layout::spacingXs())), false);
|
||||
ImGui::BeginChild("##pfMasterList", ImVec2(masterW, std::max(48.0f, bodyH - addH - Layout::spacingSm())), false);
|
||||
{
|
||||
ImDrawList* mdl = ImGui::GetWindowDrawList();
|
||||
if (entries.empty())
|
||||
@@ -489,10 +489,11 @@ static void RenderPortfolioEditor(App* app)
|
||||
if (clickedSel != -999) { commitIfNeeded(); PortfolioBeginEdit(app, clickedSel); }
|
||||
}
|
||||
ImGui::EndChild();
|
||||
ImGui::Dummy(ImVec2(0, Layout::spacingXs()));
|
||||
if (ImGui::Button(TR("portfolio_add_entry"), ImVec2(-1, addH))) { commitIfNeeded(); PortfolioBeginEdit(app, -2); }
|
||||
ImGui::Dummy(ImVec2(0, Layout::spacingSm()));
|
||||
// Add button lives outside the scroll child (a normal widget) so it can never be clipped.
|
||||
if (ImGui::Button(TR("portfolio_add_entry"), ImVec2(masterW, addH))) { commitIfNeeded(); PortfolioBeginEdit(app, -2); }
|
||||
}
|
||||
ImGui::EndChild();
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::SameLine(0, gap);
|
||||
|
||||
@@ -574,16 +575,30 @@ static void RenderPortfolioEditor(App* app)
|
||||
ImGui::InputTextWithHint("##pfLabel", TR("portfolio_group_name"), s_pf_label, sizeof(s_pf_label));
|
||||
ImGui::Dummy(ImVec2(0, Layout::spacingSm()));
|
||||
|
||||
// Accordion: exactly one section expanded at a time.
|
||||
auto section = [&](const char* label, bool& openFlag) -> bool {
|
||||
// Accordion: exactly one section expanded at a time. Collapsed sections show a compact
|
||||
// summary on the right so a group's state is readable at a glance without expanding.
|
||||
auto section = [&](const char* label, bool& openFlag, const std::string& summary) -> bool {
|
||||
ImGui::SetNextItemOpen(openFlag, ImGuiCond_Always);
|
||||
bool now = ImGui::CollapsingHeader(label);
|
||||
if (!now && !summary.empty()) {
|
||||
ImVec2 hmn = ImGui::GetItemRectMin(), hmx = ImGui::GetItemRectMax();
|
||||
float sw2 = capF->CalcTextSizeA(capF->LegacySize, FLT_MAX, 0, summary.c_str()).x;
|
||||
ImGui::GetWindowDrawList()->AddText(capF, capF->LegacySize,
|
||||
ImVec2(hmx.x - sw2 - Layout::spacingMd(), (hmn.y + hmx.y) * 0.5f - capF->LegacySize * 0.5f),
|
||||
OnSurfaceMedium(), summary.c_str());
|
||||
}
|
||||
if (now != openFlag) { s_pf_sec_appearance = s_pf_sec_price = s_pf_sec_addresses = false; openFlag = now; }
|
||||
return openFlag;
|
||||
};
|
||||
// Collapsed-section summaries.
|
||||
const char* basisNames[4] = { TR("portfolio_price_usd"), TR("portfolio_price_btc"),
|
||||
TR("portfolio_price_drgx"), TR("portfolio_price_manual") };
|
||||
std::string apSummary = s_pf_icon.empty() ? std::string(TR("portfolio_no_icon")) : s_pf_icon;
|
||||
std::string prSummary = basisNames[std::max(0, std::min(3, s_pf_price_basis))];
|
||||
char adSummary[48]; snprintf(adSummary, sizeof(adSummary), TR("portfolio_addresses_sel"), (int)s_pf_addrs.size());
|
||||
|
||||
// ---- APPEARANCE (color + outline opacity + icon) ----
|
||||
if (section(TR("portfolio_appearance"), s_pf_sec_appearance)) {
|
||||
if (section(TR("portfolio_appearance"), s_pf_sec_appearance, apSummary)) {
|
||||
ImGui::Indent(Layout::spacingSm());
|
||||
// Color picker: preset swatches + a custom-color circle that opens a picker popup.
|
||||
{
|
||||
@@ -698,7 +713,7 @@ static void RenderPortfolioEditor(App* app)
|
||||
}
|
||||
|
||||
// ---- PRICE (basis, manual price, shown fields, sparkline) ----
|
||||
if (section(TR("portfolio_price"), s_pf_sec_price)) {
|
||||
if (section(TR("portfolio_price"), s_pf_sec_price, prSummary)) {
|
||||
ImGui::Indent(Layout::spacingSm());
|
||||
const char* basisItems[4] = { TR("portfolio_price_usd"), TR("portfolio_price_btc"),
|
||||
TR("portfolio_price_drgx"), TR("portfolio_price_manual") };
|
||||
@@ -737,7 +752,7 @@ static void RenderPortfolioEditor(App* app)
|
||||
}
|
||||
|
||||
// ---- ADDRESSES (search, filter, select) ----
|
||||
if (section(TR("portfolio_addresses_hdr"), s_pf_sec_addresses)) {
|
||||
if (section(TR("portfolio_addresses_hdr"), s_pf_sec_addresses, adSummary)) {
|
||||
ImGui::Indent(Layout::spacingSm());
|
||||
{
|
||||
char selc[48];
|
||||
@@ -884,7 +899,7 @@ static void RenderPortfolioEditor(App* app)
|
||||
|
||||
ImGui::EndChild(); // ##pfCard
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::PopStyleVar(2);
|
||||
ImGui::PopStyleVar(); // ChildRounding (WindowPadding was popped right after BeginChild)
|
||||
|
||||
// Outside-click dismiss (guarded against the appearing frame and open popups).
|
||||
if (!popupOpen && !ImGui::IsWindowAppearing() && ImGui::IsMouseClicked(ImGuiMouseButton_Left)
|
||||
|
||||
@@ -1144,8 +1144,8 @@ void I18n::loadBuiltinEnglish()
|
||||
strings_["portfolio_spark_day"] = "Day";
|
||||
strings_["portfolio_spark_week"] = "Week";
|
||||
strings_["portfolio_spark_month"] = "Month";
|
||||
strings_["portfolio_appearance"] = "APPEARANCE";
|
||||
strings_["portfolio_addresses_hdr"] = "ADDRESSES";
|
||||
strings_["portfolio_appearance"] = "Appearance";
|
||||
strings_["portfolio_addresses_hdr"] = "Addresses";
|
||||
strings_["portfolio_search"] = "Search addresses\xE2\x80\xA6";
|
||||
strings_["portfolio_funded"] = "Funded";
|
||||
strings_["portfolio_select_all"] = "All";
|
||||
|
||||
Reference in New Issue
Block a user