From 16d8e86b84e0efdc8ead1c0b188650bb888f3456 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Wed, 30 Apr 2025 14:47:19 +0800 Subject: [PATCH] ENH: group filament preset by vendor & list uncompatible filaments Change-Id: Ice05956fca59fe130d927b505ac0f61dc8e8cb5e Jira: STUDIO-11615 (cherry picked from commit 564e59bf4fd99ce718f224ec61f1423fd876fc52) --- src/slic3r/GUI/PresetComboBoxes.cpp | 77 +++++++++++++++++++++++++---- src/slic3r/GUI/Widgets/DropDown.cpp | 14 +++++- src/slic3r/GUI/Widgets/DropDown.hpp | 1 + 3 files changed, 81 insertions(+), 11 deletions(-) diff --git a/src/slic3r/GUI/PresetComboBoxes.cpp b/src/slic3r/GUI/PresetComboBoxes.cpp index ebb1cd0362..41688b83e0 100644 --- a/src/slic3r/GUI/PresetComboBoxes.cpp +++ b/src/slic3r/GUI/PresetComboBoxes.cpp @@ -1112,8 +1112,11 @@ void PlaterPresetComboBox::update() //BBS: add project embedded presets logic std::map project_embedded_presets; std::map system_presets; + std::map uncompatible_presets; std::unordered_set system_printer_models; std::map preset_descriptions; + std::map preset_filament_vendors; + std::map preset_filament_types; //BBS: move system to the end wxString selected_system_preset; wxString selected_user_preset; @@ -1133,7 +1136,7 @@ void PlaterPresetComboBox::update() m_type == Preset::TYPE_PRINTER && m_preset_bundle->physical_printers.has_selection() ? false : i == m_collection->get_selected_idx(); - if (!is_selected && (!preset.is_visible ||!preset.is_compatible)) + if (!is_selected && !preset.is_visible) { continue; } @@ -1156,6 +1159,16 @@ void PlaterPresetComboBox::update() bitmap_key += single_bar ? filament_rgb : filament_rgb + extruder_rgb; #endif + if (preset.is_system) { + if (!preset.is_compatible && preset_filament_vendors.count(name) > 0) + continue; + else if (preset.is_compatible && preset_filament_vendors.count(name) > 0) + uncompatible_presets.erase(name); + preset_filament_vendors[name] = preset.config.option("filament_vendor")->values.at(0); + if (preset_filament_vendors[name] == "Bambu Lab") + preset_filament_vendors[name] = "Bambu"; + preset_filament_types[name] = preset.config.option("filament_type")->values.at(0); + } } wxBitmap* bmp = get_bmp(preset); @@ -1163,7 +1176,12 @@ void PlaterPresetComboBox::update() preset_descriptions.emplace(name, from_u8(preset.description)); - if (preset.is_default || preset.is_system) { + if (!preset.is_compatible) { + if (boost::ends_with(name, " template")) + continue; + uncompatible_presets.emplace(name, bmp); + } + else if (preset.is_default || preset.is_system) { //BBS: move system to the end if (m_type == Preset::TYPE_PRINTER) { auto printer_model = preset.config.opt_string("printer_model"); @@ -1210,21 +1228,61 @@ void PlaterPresetComboBox::update() //if (m_type == Preset::TYPE_PRINTER) // add_connected_printers("", true); bool selected_in_ams = false; - if (m_type == Preset::TYPE_FILAMENT && m_preset_bundle->is_bbl_vendor()) { + if (m_type == Preset::TYPE_FILAMENT) { set_replace_text("Bambu", "BambuStudioBlack"); - selected_in_ams = add_ams_filaments(into_u8(selected_user_preset), true); + selected_in_ams = add_ams_filaments(into_u8(selected_user_preset.empty() ? selected_system_preset : selected_user_preset), true); } - auto add_presets = [this, &preset_descriptions, &selected_in_ams] + std::vector filament_orders = {"Bambu PLA Basic", "Bambu PLA Matte", "Bambu PETG HF", "Bambu ABS", "Bambu PLA Silk", "Bambu PLA-CF", + "Bambu PLA Galaxy", "Bambu PLA Metal", "Bambu PLA Marble", "Bambu PETG-CF", "Bambu PETG Translucent", "Bambu ABS-GF"}; + std::vector first_vendors = {"Bambu", "Generic"}; + std::vector first_types = {"PLA", "PETG", "ABS", "TPU"}; + auto add_presets = [this, &preset_descriptions, &filament_orders, &preset_filament_vendors, &first_vendors, &preset_filament_types, &first_types, &selected_in_ams] (std::map const &presets, wxString const &selected, std::string const &group) { if (!presets.empty()) { set_label_marker(Append(separator(group), wxNullBitmap)); + if (m_type == Preset::TYPE_FILAMENT) { + std::vector::value_type const*> list(presets.size(), nullptr); + std::transform(presets.begin(), presets.end(), list.begin(), [](auto & pair) { return &pair; }); + if (group == "System presets") + std::sort(list.begin(), list.end(), [&filament_orders, &preset_filament_vendors, &first_vendors, &preset_filament_types, &first_types](auto *l, auto *r) { + { // Compare order + auto iter1 = std::find(filament_orders.begin(), filament_orders.end(), l->first); + auto iter2 = std::find(filament_orders.begin(), filament_orders.end(), r->first); + if (iter1 != iter2) + return iter1 < iter2; + } + { // Compare vendor + auto iter1 = std::find(first_vendors.begin(), first_vendors.end(), preset_filament_vendors[l->first]); + auto iter2 = std::find(first_vendors.begin(), first_vendors.end(), preset_filament_vendors[r->first]); + if (iter1 != iter2) + return iter1 < iter2; + } + { // Compare type + auto iter1 = std::find(first_types.begin(), first_types.end(), preset_filament_types[l->first]); + auto iter2 = std::find(first_types.begin(), first_types.end(), preset_filament_types[r->first]); + if (iter1 != iter2) + return iter1 < iter2; + } + return l->first < r->first; + }); + for (auto it : list) { + auto vendor = preset_filament_vendors[it->first]; + if (!vendor.empty() && group == "Unsupported presets") + vendor.push_back(' '); + SetItemTooltip(Append(it->first, *it->second, vendor), preset_descriptions[it->first]); + bool is_selected = it->first == selected; + validate_selection(is_selected); + if (is_selected && selected_in_ams) { + SetFlag(GetCount() - 1, (int) FilamentAMSType::FROM_AMS); + } + } + } else { for (std::map::const_iterator it = presets.begin(); it != presets.end(); ++it) { SetItemTooltip(Append(it->first, *it->second), preset_descriptions[it->first]); - bool is_selected = it->first == selected; - validate_selection(is_selected); - if (is_selected && selected_in_ams) { - SetFlag(GetCount() - 1, (int) FilamentAMSType::FROM_AMS); + if (group == "System presets") + set_label_marker(GetCount() - 1, LABEL_ITEM_PRINTER_MODELS); + validate_selection(it->first == selected); } } } @@ -1235,6 +1293,7 @@ void PlaterPresetComboBox::update() add_presets(nonsys_presets, selected_user_preset, L("User presets")); // BBS: move system to the end add_presets(system_presets, selected_system_preset, L("System presets")); + add_presets(uncompatible_presets, {}, L("Unsupported presets")); //BBS: remove unused pysical printer logic /*if (m_type == Preset::TYPE_PRINTER) diff --git a/src/slic3r/GUI/Widgets/DropDown.cpp b/src/slic3r/GUI/Widgets/DropDown.cpp index 07b3604c96..9f33944dde 100644 --- a/src/slic3r/GUI/Widgets/DropDown.cpp +++ b/src/slic3r/GUI/Widgets/DropDown.cpp @@ -59,6 +59,7 @@ void DropDown::Create(wxWindow *parent, long style) state_handler.update_binds(); if ((style & DD_NO_CHECK_ICON) == 0) check_bitmap = ScalableBitmap(this, "checked", 16); + arrow_bitmap = ScalableBitmap(this, "hms_arrow", 16); text_off = style & DD_NO_TEXT; // BBS set default font @@ -323,7 +324,7 @@ void DropDown::render(wxDC &dc) } auto text = group.IsEmpty() ? (item.group.IsEmpty() ? item.text : item.group) - : item.text.substr(group.size()).Trim(false); + : (item.text.StartsWith(group) ? item.text.substr(group.size()).Trim(false) : item.text); if (!text_off && !text.IsEmpty()) { wxSize tSize = dc.GetMultiLineTextExtent(text); if (pt.x + tSize.x > rcContent.GetRight()) { @@ -335,6 +336,12 @@ void DropDown::render(wxDC &dc) pt.y += (rcContent.height - textSize.y) / 2; dc.SetFont(GetFont()); dc.DrawText(text, pt); + if (group.IsEmpty() && !item.group.IsEmpty()) { + auto szBmp = arrow_bitmap.GetBmpSize(); + pt.x = rcContent.GetRight() - szBmp.x - 5; + pt.y = rcContent.y += (rcContent.height - szBmp.y) / 2; + dc.DrawBitmap(arrow_bitmap.bmp(), pt); + } } rcContent.y += rowSize.y; } @@ -407,6 +414,7 @@ void DropDown::messureSize() iconSize = wxSize(); count = 0; wxClientDC dc(GetParent() ? GetParent() : this); + dc.SetFont(GetFont()); std::set groups; for (size_t i = 0; i < items.size(); ++i) { auto &item = items[i]; @@ -427,7 +435,7 @@ void DropDown::messureSize() if (!text_off) { auto text = group.IsEmpty() ? (item.group.IsEmpty() ? item.text : item.group) - : item.text.substr(group.size()).Trim(false); + : (item.text.StartsWith(group) ? item.text.substr(group.size()).Trim(false) : item.text); size1 = dc.GetMultiLineTextExtent(text); } if (item.icon.IsOk()) { @@ -442,6 +450,8 @@ void DropDown::messureSize() } if (!align_icon) iconSize.x = 0; wxSize szContent = textSize; + if (szContent.x < FromDIP(120)) + szContent.x = FromDIP(120); szContent.x += 10; if (check_bitmap.bmp().IsOk()) { auto szBmp = check_bitmap.GetBmpSize(); diff --git a/src/slic3r/GUI/Widgets/DropDown.hpp b/src/slic3r/GUI/Widgets/DropDown.hpp index 6920c3c939..0622ca4131 100644 --- a/src/slic3r/GUI/Widgets/DropDown.hpp +++ b/src/slic3r/GUI/Widgets/DropDown.hpp @@ -54,6 +54,7 @@ private: StateColor selector_border_color; StateColor selector_background_color; ScalableBitmap check_bitmap; + ScalableBitmap arrow_bitmap; bool pressedDown = false; boost::posix_time::ptime dismissTime;