From 973399104f9877afd8d5796d7cfa241a05957706 Mon Sep 17 00:00:00 2001 From: "chunmao.guo" Date: Thu, 8 May 2025 18:18:42 +0800 Subject: [PATCH] FIX: clapse filament list min height & adjust filament groups Change-Id: Ie4c41b2977addcac4359f161daa46f34dd35054e Jira: STUDIO-12082, STUDIO-12084, STUDIO-12077 --- src/slic3r/GUI/Plater.cpp | 18 ++++++++--- src/slic3r/GUI/PresetComboBoxes.cpp | 47 +++++++++++++++++------------ src/slic3r/GUI/PresetComboBoxes.hpp | 8 ++--- src/slic3r/GUI/Widgets/DropDown.cpp | 36 +++++++++++++++++----- src/slic3r/GUI/Widgets/DropDown.hpp | 3 +- 5 files changed, 75 insertions(+), 37 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 9300820a1..45d6788ef 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1744,10 +1744,16 @@ Sidebar::Sidebar(Plater *parent) if (e.GetPosition().x > (p->m_flushing_volume_btn->IsShown() ? p->m_flushing_volume_btn->GetPosition().x : p->m_bpButton_add_filament->GetPosition().x)) return; - if (p->m_panel_filament_content->GetMaxHeight() == 0) - p->m_panel_filament_content->SetMaxSize({-1, -1}); - else + if (p->m_panel_filament_content->GetMaxHeight() == 0) { + p->m_panel_filament_content->SetMaxSize({-1, FromDIP(174)}); + auto min_size = p->m_panel_filament_content->GetSizer()->GetMinSize(); + if (min_size.y > p->m_panel_filament_content->GetMaxHeight()) + min_size.y = p->m_panel_filament_content->GetMaxHeight(); + p->m_panel_filament_content->SetMinSize({-1, min_size.y}); + } else { + p->m_panel_filament_content->SetMinSize({-1, 0}); p->m_panel_filament_content->SetMaxSize({-1, 0}); + } m_scrolled_sizer->Layout(); }); @@ -3170,7 +3176,11 @@ void Sidebar::sync_ams_list(bool is_from_big_sync_btn) for (auto& c : p->combos_filament) c->update(); // Expand filament list - p->m_panel_filament_content->SetMaxSize({-1, -1}); + p->m_panel_filament_content->SetMaxSize({-1, FromDIP(174)}); + auto min_size = p->m_panel_filament_content->GetSizer()->GetMinSize(); + if (min_size.y > p->m_panel_filament_content->GetMaxHeight()) + min_size.y = p->m_panel_filament_content->GetMaxHeight(); + p->m_panel_filament_content->SetMinSize({-1, min_size.y}); // BBS:Synchronized consumables information // auto calculation of flushing volumes for (int i = 0; i < p->combos_filament.size(); ++i) { diff --git a/src/slic3r/GUI/PresetComboBoxes.cpp b/src/slic3r/GUI/PresetComboBoxes.cpp index 43bccdcb5..b488bb27e 100644 --- a/src/slic3r/GUI/PresetComboBoxes.cpp +++ b/src/slic3r/GUI/PresetComboBoxes.cpp @@ -346,7 +346,7 @@ void PresetComboBox::update(std::string select_preset_name) wxString selected = ""; if (!presets.front().is_visible) - set_label_marker(Append(separator(L("System presets")), wxNullBitmap)); + set_label_marker(Append(L("System presets"), wxNullBitmap, DD_ITEM_STYLE_SPLIT_ITEM)); for (size_t i = presets.front().is_visible ? 0 : m_collection->num_default_presets(); i < presets.size(); ++i) { @@ -376,11 +376,11 @@ void PresetComboBox::update(std::string select_preset_name) selected = get_preset_name(preset); } if (i + 1 == m_collection->num_default_presets()) - set_label_marker(Append(separator(L("System presets")), wxNullBitmap)); + set_label_marker(Append(L("System presets"), wxNullBitmap, DD_ITEM_STYLE_SPLIT_ITEM)); } if (!nonsys_presets.empty()) { - set_label_marker(Append(separator(L("User presets")), wxNullBitmap)); + set_label_marker(Append(L("User presets"), wxNullBitmap, DD_ITEM_STYLE_SPLIT_ITEM)); for (std::map>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) { int item_id = Append(it->first, *it->second.first); bool is_enabled = it->second.second; @@ -391,7 +391,7 @@ void PresetComboBox::update(std::string select_preset_name) } if (!incomp_presets.empty()) { - set_label_marker(Append(separator(L("Incompatible presets")), wxNullBitmap)); + set_label_marker(Append(L("Incompatible presets"), wxNullBitmap, DD_ITEM_STYLE_SPLIT_ITEM)); for (std::map::iterator it = incomp_presets.begin(); it != incomp_presets.end(); ++it) { set_label_marker(Append(it->first, *it->second), LABEL_ITEM_DISABLED); } @@ -427,7 +427,7 @@ void PresetComboBox::add_connected_printers(std::string selected, bool alias_nam if (machine_list.empty()) return; - set_label_marker(Append(separator(L("My Printer")), wxNullBitmap)); + set_label_marker(Append(L("My Printer"), wxNullBitmap, DD_ITEM_STYLE_SPLIT_ITEM)); m_first_printer_idx = GetCount(); // sort list @@ -475,8 +475,8 @@ bool PresetComboBox::add_ams_filaments(std::string selected, bool alias_name) bool selected_in_ams = false; bool is_bbl_vendor_preset = m_preset_bundle->printers.get_edited_preset().is_bbl_vendor_preset(m_preset_bundle); if (is_bbl_vendor_preset && !m_preset_bundle->filament_ams_list.empty()) { - bool dual_extruder = (m_preset_bundle->filament_ams_list.begin()->first & 0x10000) == 0; - set_label_marker(Append(separator(dual_extruder ? L("Left filaments") : L("AMS filaments")), wxNullBitmap)); + bool dual_extruder = (m_preset_bundle->filament_ams_list.begin()->first & 0x10000) == 0; + set_label_marker(Append(dual_extruder ? L("Left filaments") : L("AMS filaments"), wxNullBitmap, DD_ITEM_STYLE_SPLIT_ITEM)); m_first_ams_filament = GetCount(); auto &filaments = m_collection->get_presets(); @@ -491,7 +491,7 @@ bool PresetComboBox::add_ams_filaments(std::string selected, bool alias_name) for (auto &entry : m_preset_bundle->filament_ams_list) { if (dual_extruder && (entry.first & 0x10000)) { dual_extruder = false; - set_label_marker(Append(separator(L("Right filaments")), wxNullBitmap)); + set_label_marker(Append(L("Right filaments"), wxNullBitmap, DD_ITEM_STYLE_SPLIT_ITEM)); } auto & tray = entry.second; std::string filament_id = tray.opt_string("filament_id", 0u); @@ -1232,16 +1232,21 @@ void PlaterPresetComboBox::update() 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_vendors = {"", "Bambu", "Generic"}; // Empty vendor for non-system presets 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)); + set_label_marker(Append(group, wxNullBitmap, DD_ITEM_STYLE_SPLIT_ITEM)); 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") + bool groupByGroup = group != "System presets"; + //if (groupByGroup) { + // if (GetCount() == 1) Clear(); + // else SetString(GetCount() - 1, ""); + //} + if (group == "System presets" || group == "Unsupported 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); @@ -1263,11 +1268,13 @@ void PlaterPresetComboBox::update() } return l->first < r->first; }); + bool unsupported = group == "Unsupported presets"; 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]); + auto groupName = groupByGroup ? group : preset_filament_vendors[it->first]; + int index = Append(it->first, *it->second, groupName, nullptr, unsupported ? DD_ITEM_STYLE_DISABLED : 0); + if (unsupported) + set_label_marker(index, LABEL_ITEM_DISABLED); + SetItemTooltip(index, preset_descriptions[it->first]); bool is_selected = it->first == selected; validate_selection(is_selected); if (is_selected && selected_in_ams) { @@ -1506,7 +1513,7 @@ void TabPresetComboBox::update() //BBS: add project embedded preset logic if (!project_embedded_presets.empty()) { - set_label_marker(Append(separator(L("Project-inside presets")), wxNullBitmap)); + set_label_marker(Append(L("Project-inside presets"), wxNullBitmap, DD_ITEM_STYLE_SPLIT_ITEM)); for (std::map>::iterator it = project_embedded_presets.begin(); it != project_embedded_presets.end(); ++it) { int item_id = Append(it->first, *it->second.first); SetItemTooltip(item_id, preset_descriptions[it->first]); @@ -1518,7 +1525,7 @@ void TabPresetComboBox::update() } if (!nonsys_presets.empty()) { - set_label_marker(Append(separator(L("User presets")), wxNullBitmap)); + set_label_marker(Append(L("User presets"), wxNullBitmap, DD_ITEM_STYLE_SPLIT_ITEM)); for (std::map>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) { int item_id = Append(it->first, *it->second.first); SetItemTooltip(item_id, preset_descriptions[it->first]); @@ -1531,7 +1538,7 @@ void TabPresetComboBox::update() //BBS: move system to the end if (!system_presets.empty()) { - set_label_marker(Append(separator(L("System presets")), wxNullBitmap)); + set_label_marker(Append(L("System presets"), wxNullBitmap, DD_ITEM_STYLE_SPLIT_ITEM)); for (std::map>::iterator it = system_presets.begin(); it != system_presets.end(); ++it) { int item_id = Append(it->first, *it->second.first); SetItemTooltip(item_id, preset_descriptions[it->first]); @@ -1765,7 +1772,7 @@ void GUI::CalibrateFilamentComboBox::update() if (!m_nonsys_presets.empty()) { - set_label_marker(Append(separator(L("User presets")), wxNullBitmap)); + set_label_marker(Append(L("User presets"), wxNullBitmap, DD_ITEM_STYLE_SPLIT_ITEM)); for (auto it = m_nonsys_presets.begin(); it != m_nonsys_presets.end(); ++it) { Append(it->first, *(it->second.second)); validate_selection(it->first == selected_preset); @@ -1773,7 +1780,7 @@ void GUI::CalibrateFilamentComboBox::update() } if (!m_system_presets.empty()) { - set_label_marker(Append(separator(L("System presets")), wxNullBitmap)); + set_label_marker(Append(L("System presets"), wxNullBitmap, DD_ITEM_STYLE_SPLIT_ITEM)); for (auto it = m_system_presets.begin(); it != m_system_presets.end(); ++it) { Append(it->first, *(it->second.second)); validate_selection(it->first == selected_preset); diff --git a/src/slic3r/GUI/PresetComboBoxes.hpp b/src/slic3r/GUI/PresetComboBoxes.hpp index fb92adf03..ad2a42f55 100644 --- a/src/slic3r/GUI/PresetComboBoxes.hpp +++ b/src/slic3r/GUI/PresetComboBoxes.hpp @@ -157,11 +157,11 @@ protected: int update_ams_color(); #ifdef __linux__ - static const char* separator_head() { return "------- "; } - static const char* separator_tail() { return " -------"; } + static const char* separator_head() { return "-- "; } + static const char* separator_tail() { return " --"; } #else // __linux__ - static const char* separator_head() { return "------ "; } - static const char* separator_tail() { return " ------"; } + static const char* separator_head() { return "--"; } + static const char* separator_tail() { return " --"; } #endif // __linux__ static wxString separator(const std::string& label); diff --git a/src/slic3r/GUI/Widgets/DropDown.cpp b/src/slic3r/GUI/Widgets/DropDown.cpp index 4ea7f8d1c..bcaf06419 100644 --- a/src/slic3r/GUI/Widgets/DropDown.cpp +++ b/src/slic3r/GUI/Widgets/DropDown.cpp @@ -36,7 +36,8 @@ DropDown::DropDown(std::vector &items) : items(items) , state_handler(this) , border_color(0xDBDBDB) - , text_color(0x363636) + , text_color(std::make_pair(0x909090, (int) StateColor::Disabled), + std::make_pair(0x363636, (int) StateColor::Normal)) , selector_border_color(std::make_pair(0x00AE42, (int) StateColor::Hovered), std::make_pair(*wxWHITE, (int) StateColor::Normal)) , selector_background_color(std::make_pair(0xEDFAF2, (int) StateColor::Checked), @@ -269,10 +270,11 @@ void DropDown::render(wxDC &dc) dc.DrawRoundedRectangle(0, 0, size.x, size.y, radius); int selected_item = selectedItem(); + int hover_index = hoverIndex(); // draw hover rectangle wxRect rcContent = {{0, offset.y}, rowSize}; - if (hover_item >= 0 && (states & StateColor::Hovered) && !(items[hover_item].style & DD_ITEM_STYLE_SPLIT_ITEM)) { + if (hover_item >= 0 && (states & StateColor::Hovered) && (hover_index < 0 || !(items[hover_index].style & DD_ITEM_STYLE_SPLIT_ITEM))) { rcContent.y += rowSize.y * hover_item; if (rcContent.GetBottom() > 0 && rcContent.y < size.y) { if (selected_item == hover_item) @@ -331,17 +333,29 @@ void DropDown::render(wxDC &dc) std::set groups; // draw texts & icons - dc.SetTextForeground(text_color.colorForStates(states)); int index = 0; for (int i = 0; i < items.size(); ++i) { auto &item = items[i]; + int states2 = states; + if ((item.style & DD_ITEM_STYLE_DISABLED) != 0) + states2 &= ~StateColor::Enabled; // Skip by group if (group.IsEmpty()) { if (!item.group.IsEmpty()) { - if (groups.find(item.group) == groups.end()) - groups.insert(item.group); - else + if (groups.find(item.group) != groups.end()) continue; + groups.insert(item.group); + if (!item.group.IsEmpty()) { + bool disabled = true; + for (int j = i + 1; j < items.size(); ++j) { + if (items[i].group != item.group && (items[j].style & DD_ITEM_STYLE_DISABLED) == 0) { + disabled = false; + break; + } + } + if (!disabled) + states2 |= StateColor::Enabled; + } } } else { if (item.group != group) @@ -393,6 +407,7 @@ void DropDown::render(wxDC &dc) } pt.y += (rcContent.height - textSize.y) / 2; dc.SetFont(GetFont()); + dc.SetTextForeground(text_color.colorForStates(states2)); dc.DrawText(text, pt); if (group.IsEmpty() && !item.group.IsEmpty()) { auto szBmp = arrow_bitmap.GetBmpSize(); @@ -495,6 +510,8 @@ void DropDown::messureSize() ? (item.group.IsEmpty() ? item.text : item.group) : (item.text.StartsWith(group) ? item.text.substr(group.size()).Trim(false) : item.text); size1 = dc.GetMultiLineTextExtent(text); + if (group.IsEmpty() && !item.group.IsEmpty()) + size1.x += 5 + arrow_bitmap.GetBmpWidth(); } if (item.icon.IsOk()) { wxSize size2 = GetBmpSize(item.icon); @@ -623,10 +640,13 @@ void DropDown::mouseReleased(wxMouseEvent& event) pressedDown = false; if (HasCapture()) ReleaseMouse(); - if (hover_item >= 0) { // not moved + if (hover_item >= 0 && subDropDown == nullptr) { // not moved sendDropDownEvent(); + if (mainDropDown) + mainDropDown->hover_item = -1; // To Dismiss mainDropDown DismissAndNotify(); - } + } else if (subDropDown) + subDropDown->Popup(subDropDown); } } diff --git a/src/slic3r/GUI/Widgets/DropDown.hpp b/src/slic3r/GUI/Widgets/DropDown.hpp index ca2481d3b..43289cb71 100644 --- a/src/slic3r/GUI/Widgets/DropDown.hpp +++ b/src/slic3r/GUI/Widgets/DropDown.hpp @@ -11,7 +11,8 @@ #define DD_NO_TEXT 0x0002 #define DD_STYLE_MASK 0x0003 -#define DD_ITEM_STYLE_SPLIT_ITEM 0x0001 // ----text----, text with horizontal line arounds +#define DD_ITEM_STYLE_SPLIT_ITEM 0x0001 // ----text----, text with horizontal line arounds +#define DD_ITEM_STYLE_DISABLED 0x0002 // ----text----, text with horizontal line arounds wxDECLARE_EVENT(EVT_DISMISS, wxCommandEvent);