diff --git a/src/ui/windows/market_tab.cpp b/src/ui/windows/market_tab.cpp index f800a67..2403f70 100644 --- a/src/ui/windows/market_tab.cpp +++ b/src/ui/windows/market_tab.cpp @@ -102,6 +102,7 @@ static unsigned int s_pf_color = 0; // selected accent (packed IM_COL32; 0 = de static char s_pf_search[64] = {0}; // address-list filter text static int s_pf_type_filter = 0; // 0 = all, 1 = shielded, 2 = transparent static bool s_pf_funded_only = false; +static float s_pf_custom_rgb[3] = {0.31f, 0.62f, 1.0f}; // working RGB for the custom color picker // Preset accent palette for portfolio groups (0 slot = "default / no color"). static const ImU32 kPfPalette[] = { @@ -256,11 +257,74 @@ static void RenderPortfolioEditor(App* app) ImGui::InputText("##pfLabel", s_pf_label, sizeof(s_pf_label)); ImGui::Dummy(ImVec2(0, Layout::spacingSm())); - // Icon picker + // Color picker: preset swatches + a custom-color circle that opens a picker popup. + { + float sw = 22.0f * dp; + ImGui::TextUnformatted(TR("portfolio_color")); + ImDrawList* cdl = ImGui::GetWindowDrawList(); + int nColors = (int)(sizeof(kPfPalette) / sizeof(kPfPalette[0])); + for (int c = 0; c <= nColors; c++) { // slot 0 = default / no color + if (c != 0) ImGui::SameLine(0, 5.0f * dp); + ImVec2 mn = ImGui::GetCursorScreenPos(); + ImVec2 cc(mn.x + sw * 0.5f, mn.y + sw * 0.5f); + bool isDefault = (c == 0); + bool sel = isDefault ? (s_pf_color == 0u) : (s_pf_color == kPfPalette[c - 1]); + bool hov = ImGui::IsMouseHoveringRect(mn, ImVec2(mn.x + sw, mn.y + sw)); + if (isDefault) cdl->AddCircle(cc, sw * 0.40f, OnSurfaceMedium(), 0, 1.5f * dp); + else cdl->AddCircleFilled(cc, sw * 0.40f, kPfPalette[c - 1]); + if (sel) cdl->AddCircle(cc, sw * 0.50f, OnSurface(), 0, 2.0f * dp); + else if (hov) cdl->AddCircle(cc, sw * 0.50f, WithAlpha(OnSurface(), 120), 0, 1.5f * dp); + ImGui::PushID(2000 + c); + ImGui::InvisibleButton("##pfcol", ImVec2(sw, sw)); + if (ImGui::IsItemClicked()) s_pf_color = isDefault ? 0u : kPfPalette[c - 1]; + ImGui::PopID(); + } + + // Custom-color circle: shows the current color when it isn't a preset, else a "+"; + // click opens a color-picker popup. + bool isCustom = (s_pf_color != 0u); + for (int c = 0; c < nColors; c++) + if (s_pf_color == kPfPalette[c]) isCustom = false; + ImGui::SameLine(0, 5.0f * dp); + ImVec2 mn = ImGui::GetCursorScreenPos(); + ImVec2 cc(mn.x + sw * 0.5f, mn.y + sw * 0.5f); + bool hov = ImGui::IsMouseHoveringRect(mn, ImVec2(mn.x + sw, mn.y + sw)); + if (isCustom) { + cdl->AddCircleFilled(cc, sw * 0.40f, (ImU32)s_pf_color); + } else { + cdl->AddCircle(cc, sw * 0.40f, OnSurfaceMedium(), 0, 1.5f * dp); + float pr = sw * 0.18f; + cdl->AddLine(ImVec2(cc.x - pr, cc.y), ImVec2(cc.x + pr, cc.y), OnSurfaceMedium(), 1.5f * dp); + cdl->AddLine(ImVec2(cc.x, cc.y - pr), ImVec2(cc.x, cc.y + pr), OnSurfaceMedium(), 1.5f * dp); + } + if (isCustom) cdl->AddCircle(cc, sw * 0.50f, OnSurface(), 0, 2.0f * dp); + else if (hov) cdl->AddCircle(cc, sw * 0.50f, WithAlpha(OnSurface(), 120), 0, 1.5f * dp); + ImGui::InvisibleButton("##pfcustomcol", ImVec2(sw, sw)); + if (ImGui::IsItemClicked()) { + ImU32 base = s_pf_color ? (ImU32)s_pf_color : IM_COL32(0x4F, 0x9D, 0xFF, 0xFF); + s_pf_custom_rgb[0] = ((base >> IM_COL32_R_SHIFT) & 0xFF) / 255.0f; + s_pf_custom_rgb[1] = ((base >> IM_COL32_G_SHIFT) & 0xFF) / 255.0f; + s_pf_custom_rgb[2] = ((base >> IM_COL32_B_SHIFT) & 0xFF) / 255.0f; + ImGui::OpenPopup("##pfCustomColor"); + } + if (hov) material::Tooltip("%s", TR("portfolio_custom_color")); + if (ImGui::BeginPopup("##pfCustomColor")) { + ImGui::ColorPicker3("##pfpick", s_pf_custom_rgb, + ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoLabel); + s_pf_color = IM_COL32((int)(s_pf_custom_rgb[0] * 255.0f + 0.5f), + (int)(s_pf_custom_rgb[1] * 255.0f + 0.5f), + (int)(s_pf_custom_rgb[2] * 255.0f + 0.5f), 255); + ImGui::EndPopup(); + } + } + ImGui::Dummy(ImVec2(0, Layout::spacingSm())); + + // Icon picker — fills the remaining height of the left column. { float cell = 28.0f * dp, cellGap = 4.0f * dp; ImGui::TextUnformatted(TR("portfolio_icon")); - ImGui::BeginChild("##pfIconGrid", ImVec2(0, cell * 3.0f + cellGap * 2.0f + Layout::spacingSm() * 2.0f), true); + float iconGridH = std::max(cell * 2.0f + cellGap, ImGui::GetContentRegionAvail().y); + ImGui::BeginChild("##pfIconGrid", ImVec2(0, iconGridH), true); ImDrawList* gdl = ImGui::GetWindowDrawList(); float availW = ImGui::GetContentRegionAvail().x; int cols = std::max(1, (int)((availW + cellGap) / (cell + cellGap))); @@ -299,31 +363,6 @@ static void RenderPortfolioEditor(App* app) } ImGui::EndChild(); } - ImGui::Dummy(ImVec2(0, Layout::spacingSm())); - - // Color picker - { - float sw = 22.0f * dp; - ImGui::TextUnformatted(TR("portfolio_color")); - ImDrawList* cdl = ImGui::GetWindowDrawList(); - int nColors = (int)(sizeof(kPfPalette) / sizeof(kPfPalette[0])); - for (int c = 0; c <= nColors; c++) { // slot 0 = default / no color - if (c != 0) ImGui::SameLine(0, 5.0f * dp); - ImVec2 mn = ImGui::GetCursorScreenPos(); - ImVec2 cc(mn.x + sw * 0.5f, mn.y + sw * 0.5f); - bool isDefault = (c == 0); - bool sel = isDefault ? (s_pf_color == 0u) : (s_pf_color == kPfPalette[c - 1]); - bool hov = ImGui::IsMouseHoveringRect(mn, ImVec2(mn.x + sw, mn.y + sw)); - if (isDefault) cdl->AddCircle(cc, sw * 0.40f, OnSurfaceMedium(), 0, 1.5f * dp); - else cdl->AddCircleFilled(cc, sw * 0.40f, kPfPalette[c - 1]); - if (sel) cdl->AddCircle(cc, sw * 0.50f, OnSurface(), 0, 2.0f * dp); - else if (hov) cdl->AddCircle(cc, sw * 0.50f, WithAlpha(OnSurface(), 120), 0, 1.5f * dp); - ImGui::PushID(2000 + c); - ImGui::InvisibleButton("##pfcol", ImVec2(sw, sw)); - if (ImGui::IsItemClicked()) s_pf_color = isDefault ? 0u : kPfPalette[c - 1]; - ImGui::PopID(); - } - } } ImGui::EndChild(); diff --git a/src/util/i18n.cpp b/src/util/i18n.cpp index 912ca23..eefff22 100644 --- a/src/util/i18n.cpp +++ b/src/util/i18n.cpp @@ -1123,6 +1123,7 @@ void I18n::loadBuiltinEnglish() strings_["portfolio_icon"] = "Icon"; strings_["portfolio_color"] = "Color"; strings_["portfolio_no_icon"] = "None"; + strings_["portfolio_custom_color"] = "Custom color\xE2\x80\xA6"; strings_["portfolio_appearance"] = "APPEARANCE"; strings_["portfolio_addresses_hdr"] = "ADDRESSES"; strings_["portfolio_search"] = "Search addresses\xE2\x80\xA6";