From 44d3243df1fc46681b2b1d9ee0db5cd790c031ac Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 28 Mar 2019 16:28:34 +0100 Subject: [PATCH] Added context menu Item "Change Extruder" on 3D-Scene --- src/slic3r/GUI/GUI_ObjectList.cpp | 79 ++++++++++++++++++++++++------- src/slic3r/GUI/GUI_ObjectList.hpp | 6 ++- src/slic3r/GUI/Plater.cpp | 50 ++++++++++--------- src/slic3r/GUI/wxExtensions.cpp | 18 +++++++ src/slic3r/GUI/wxExtensions.hpp | 6 ++- 5 files changed, 117 insertions(+), 42 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 642a9fb55..093d77814 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -228,6 +228,21 @@ int ObjectList::get_selected_obj_idx() const return -1; } +DynamicPrintConfig& ObjectList::get_item_config(const wxDataViewItem& item) const +{ + assert(item); + const ItemType type = m_objects_model->GetItemType(item); + + const int obj_idx = type & itObject ? m_objects_model->GetIdByItem(item) : + m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item)); + + const int vol_idx = type & itVolume ? m_objects_model->GetVolumeIdByItem(item) : -1; + + assert(obj_idx >= 0 || ((type & itVolume) && vol_idx >=0)); + return type & itObject|itInstance ? (*m_objects)[obj_idx]->config : + (*m_objects)[obj_idx]->volumes[vol_idx]->config; +} + wxDataViewColumn* ObjectList::create_objects_list_extruder_column(int extruders_count) { wxArrayString choices; @@ -910,8 +925,10 @@ wxMenuItem* ObjectList::append_menu_item_split(wxMenu* menu) wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_) { PrusaMenu* menu = dynamic_cast(menu_); + + const wxString menu_name = _(L("Add settings")); // Delete old items from settings popupmenu - auto settings_id = menu->FindItem(_("Add settings")); + auto settings_id = menu->FindItem(menu_name); if (settings_id != wxNOT_FOUND) menu->Destroy(settings_id); @@ -966,14 +983,10 @@ wxMenuItem* ObjectList::append_menu_item_settings(wxMenu* menu_) menu->m_separator_scnd = menu->AppendSeparator(); // Add full settings list - auto menu_item = new wxMenuItem(menu, wxID_ANY, _(L("Add settings"))); + auto menu_item = new wxMenuItem(menu, wxID_ANY, menu_name); menu_item->SetBitmap(m_bmp_cog); -// const auto sel_vol = get_selected_model_volume(); -// if (sel_vol && sel_vol->type() >= ModelVolumeType::SUPPORT_ENFORCER) -// menu_item->Enable(false); -// else - menu_item->SetSubMenu(create_settings_popupmenu(menu)); + menu_item->SetSubMenu(create_settings_popupmenu(menu)); return menu->Append(menu_item); } @@ -1018,6 +1031,37 @@ void ObjectList::append_menu_item_export_stl(wxMenu* menu) const menu->AppendSeparator(); } +void ObjectList::append_menu_item_change_extruder(wxMenu* menu) const +{ + const wxString name = _(L("Change extruder")); + // Delete old menu item + const int item_id = menu->FindItem(name); + if (item_id != wxNOT_FOUND) + menu->Destroy(item_id); + + const int extruders_cnt = extruders_count(); + const wxDataViewItem item = GetSelection(); + if (item && extruders_cnt > 1) + { + DynamicPrintConfig& config = get_item_config(item); + + const int initial_extruder = !config.has("extruder") ? 0 : + config.option("extruder")->value; + + wxMenu* extruder_selection_menu = new wxMenu(); + + for (int i = 0; i <= extruders_cnt; i++) + { + const wxString& item_name = i == 0 ? _(L("Default")) : wxString::Format("%d", i); + + append_menu_radio_item(extruder_selection_menu, wxID_ANY, item_name, "", + [this, i](wxCommandEvent&) { set_extruder_for_selected_items(i); }, menu)->Check(i == initial_extruder); + } + + menu->AppendSubMenu(extruder_selection_menu, name, _(L("Select new extruder for the object/part"))); + } +} + void ObjectList::create_object_popupmenu(wxMenu *menu) { #ifdef __WXOSX__ @@ -2425,15 +2469,7 @@ void ObjectList::set_extruder_for_selected_items(const int extruder) const for (const wxDataViewItem& item : sels) { - const ItemType type = m_objects_model->GetItemType(item); - - const int obj_idx = type & itObject ? m_objects_model->GetIdByItem(item) : - m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item)); - - const int vol_idx = type & itVolume ? m_objects_model->GetVolumeIdByItem(item) : -1; - - DynamicPrintConfig& config = type & itObject ? (*m_objects)[obj_idx]->config : - (*m_objects)[obj_idx]->volumes[vol_idx]->config; + DynamicPrintConfig& config = get_item_config(item); if (config.has("extruder")) { if (extruder == 0) @@ -2446,7 +2482,16 @@ void ObjectList::set_extruder_for_selected_items(const int extruder) const const wxString extruder_str = extruder == 0 ? wxString ("default") : wxString::Format("%d", config.option("extruder")->value); - m_objects_model->SetValue(extruder_str, item, 1); + + auto const type = m_objects_model->GetItemType(item); + + /* We can change extruder for Object/Volume only. + * So, if Instance is selected, get its Object item and change it + */ + m_objects_model->SetValue(extruder_str, type & itInstance ? m_objects_model->GetTopParent(item) : item, 1); + + const int obj_idx = type & itObject ? m_objects_model->GetIdByItem(item) : + m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item)); wxGetApp().plater()->canvas3D()->ensure_on_bed(obj_idx); } diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index e0df8dd40..4ddc6ea71 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -187,6 +187,7 @@ public: void append_menu_items_osx(wxMenu* menu); void append_menu_item_fix_through_netfabb(wxMenu* menu); void append_menu_item_export_stl(wxMenu* menu) const ; + void append_menu_item_change_extruder(wxMenu* menu) const; void create_object_popupmenu(wxMenu *menu); void create_sla_object_popupmenu(wxMenu*menu); void create_part_popupmenu(wxMenu*menu); @@ -213,12 +214,13 @@ public: wxPoint get_mouse_position_in_control(); wxBoxSizer* get_sizer() {return m_sizer;} int get_selected_obj_idx() const; + DynamicPrintConfig& get_item_config(const wxDataViewItem& item) const; bool is_parts_changed() const { return m_parts_changed; } bool is_part_settings_changed() const { return m_part_settings_changed; } void part_settings_changed(); - void parts_changed(int obj_idx); - void part_selection_changed(); + void parts_changed(int obj_idx); + void part_selection_changed(); // Add object to the list void add_object_to_list(size_t obj_idx); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 6db5a5d5b..c92c22c50 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2624,29 +2624,35 @@ void Plater::priv::on_right_click(Vec2dEvent& evt) sidebar->obj_list()->append_menu_item_settings(menu); - /* Remove/Prepend "increase/decrease instances" menu items according to the view mode. - * Suppress to show those items for a Simple mode - */ - const MenuIdentifier id = printer_technology == ptSLA ? miObjectSLA : miObjectFFF; - if (wxGetApp().get_mode() == comSimple) { - if (menu->FindItem(_(L("Increase copies"))) != wxNOT_FOUND) - { - /* Detach an items from the menu, but don't delete them - * so that they can be added back later - * (after switching to the Advanced/Expert mode) - */ - menu->Remove(items_increase[id]); - menu->Remove(items_decrease[id]); - menu->Remove(items_set_number_of_copies[id]); + if (printer_technology != ptSLA) + sidebar->obj_list()->append_menu_item_change_extruder(menu); + + if (menu != &part_menu) + { + /* Remove/Prepend "increase/decrease instances" menu items according to the view mode. + * Suppress to show those items for a Simple mode + */ + const MenuIdentifier id = printer_technology == ptSLA ? miObjectSLA : miObjectFFF; + if (wxGetApp().get_mode() == comSimple) { + if (menu->FindItem(_(L("Increase copies"))) != wxNOT_FOUND) + { + /* Detach an items from the menu, but don't delete them + * so that they can be added back later + * (after switching to the Advanced/Expert mode) + */ + menu->Remove(items_increase[id]); + menu->Remove(items_decrease[id]); + menu->Remove(items_set_number_of_copies[id]); + } } - } - else { - if (menu->FindItem(_(L("Increase copies"))) == wxNOT_FOUND) - { - // Prepend items to the menu, if those aren't not there - menu->Prepend(items_set_number_of_copies[id]); - menu->Prepend(items_decrease[id]); - menu->Prepend(items_increase[id]); + else { + if (menu->FindItem(_(L("Increase copies"))) == wxNOT_FOUND) + { + // Prepend items to the menu, if those aren't not there + menu->Prepend(items_set_number_of_copies[id]); + menu->Prepend(items_decrease[id]); + menu->Prepend(items_increase[id]); + } } } diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index dee18ad43..55544f28e 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -61,6 +61,24 @@ wxMenuItem* append_submenu(wxMenu* menu, wxMenu* sub_menu, int id, const wxStrin return item; } +wxMenuItem* append_menu_radio_item(wxMenu* menu, int id, const wxString& string, const wxString& description, + std::function cb, wxEvtHandler* event_handler) +{ + if (id == wxID_ANY) + id = wxNewId(); + + wxMenuItem* item = menu->AppendRadioItem(id, string, description); + +#ifdef __WXMSW__ + if (event_handler != nullptr && event_handler != menu) + event_handler->Bind(wxEVT_MENU, cb, id); + else +#endif // __WXMSW__ + menu->Bind(wxEVT_MENU, cb, id); + + return item; +} + const unsigned int wxCheckListBoxComboPopup::DefaultWidth = 200; const unsigned int wxCheckListBoxComboPopup::DefaultHeight = 200; const unsigned int wxCheckListBoxComboPopup::DefaultItemHeight = 18; diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index a15bee256..27da67deb 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -25,7 +25,11 @@ wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxString& description, std::function cb, const std::string& icon = "", wxEvtHandler* event_handler = nullptr); -wxMenuItem* append_submenu(wxMenu* menu, wxMenu* sub_menu, int id, const wxString& string, const wxString& description, const std::string& icon = ""); +wxMenuItem* append_submenu(wxMenu* menu, wxMenu* sub_menu, int id, const wxString& string, const wxString& description, + const std::string& icon = ""); + +wxMenuItem* append_menu_radio_item(wxMenu* menu, int id, const wxString& string, const wxString& description, + std::function cb, wxEvtHandler* event_handler); wxBitmap create_scaled_bitmap(const std::string& bmp_name);