diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 24818c4f43..a3d912c457 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -115,7 +115,7 @@ void ObjectList::set_tooltip_for_item(const wxPoint& pt) HitTest(pt, item, col); if (!item) return; - if (col->GetTitle() == " ") + if (col->GetTitle() == " " && GetSelectedItemsCount()<2) GetMainWindow()->SetToolTip(_(L("Right button click the icon to change the object settings"))); else if (col->GetTitle() == _("Name") && m_objects_model->GetIcon(item).GetRefData() == m_icon_manifold_warning.GetRefData()) { @@ -161,6 +161,15 @@ wxPoint ObjectList::get_mouse_position_in_control() { return wxPoint(pt.x - /*win->*/GetScreenPosition().x, pt.y - /*win->*/GetScreenPosition().y); } +int ObjectList::get_selected_obj_idx() const +{ + if (GetSelectedItemsCount() == 1) { + auto item = GetSelection(); + return m_objects_model->GetIdByItem(item); + } + return -1; +} + wxDataViewColumn* ObjectList::create_objects_list_extruder_column(int extruders_count) { wxArrayString choices; @@ -296,6 +305,8 @@ void ObjectList::key_event(wxKeyEvent& event) printf("WXK_BACK\n"); remove(); } + else if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_CONTROL)) + select_all(); else event.Skip(); } @@ -815,21 +826,22 @@ void ObjectList::load_lambda(const std::string& type_name) // Delete subobject -void ObjectList::del_subobject() +void ObjectList::del_subobject_item(wxDataViewItem& item) { - auto item = GetSelection(); // #ys_FIXME_to_multi_sel if (!item) return; - const auto volume_id = m_objects_model->GetVolumeIdByItem(item); - if (volume_id == -1) + int obj_idx, vol_idx; + m_objects_model->GetObjectAndVolumeIdsByItem(item, obj_idx, vol_idx); + + if (vol_idx == -1) return; - if (volume_id == -2) + if (vol_idx == -2) del_settings_from_config(); - else if (!del_subobject_from_object(volume_id)) + else if (!del_subobject_from_object(obj_idx, vol_idx)) return; - select_item(m_objects_model->Delete(item)); + m_objects_model->Delete(item); } void ObjectList::del_settings_from_config() @@ -847,14 +859,13 @@ void ObjectList::del_settings_from_config() m_config->set_key_value("extruder", new ConfigOptionInt(extruder)); } - -bool ObjectList::del_subobject_from_object(const int volume_id) +bool ObjectList::del_subobject_from_object(const int obj_idx, const int vol_idx) { - const auto volume = (*m_objects)[m_selected_object_id]->volumes[volume_id]; + const auto volume = (*m_objects)[obj_idx]->volumes[vol_idx]; // if user is deleting the last solid part, throw error int solid_cnt = 0; - for (auto vol : (*m_objects)[m_selected_object_id]->volumes) + for (auto vol : (*m_objects)[obj_idx]->volumes) if (vol->is_model_part()) ++solid_cnt; if (volume->is_model_part() && solid_cnt == 1) { @@ -862,10 +873,10 @@ bool ObjectList::del_subobject_from_object(const int volume_id) return false; } - (*m_objects)[m_selected_object_id]->delete_volume(volume_id); + (*m_objects)[obj_idx]->delete_volume(vol_idx); m_parts_changed = true; + parts_changed(obj_idx); - parts_changed(m_selected_object_id); return true; } @@ -1061,12 +1072,22 @@ void ObjectList::add_object_to_list(size_t obj_idx) void ObjectList::delete_object_from_list() { auto item = GetSelection(); - if (!item || m_objects_model->GetParent(item) != wxDataViewItem(0)) + if (!item) return; - // Select(m_objects_model->Delete(item)); - m_objects_model->Delete(item); + if (m_objects_model->GetParent(item) == wxDataViewItem(0)) + select_item(m_objects_model->Delete(item)); + else + select_item(m_objects_model->Delete(m_objects_model->GetParent(item))); +} - part_selection_changed(); +void ObjectList::delete_object_from_list(const size_t obj_idx) +{ + select_item(m_objects_model->Delete(m_objects_model->GetItemById(obj_idx))); +} + +void ObjectList::delete_volume_from_list(const size_t obj_idx, const size_t vol_idx) +{ + select_item(m_objects_model->Delete(m_objects_model->GetItemByVolumeId(obj_idx, vol_idx))); } void ObjectList::delete_all_objects_from_list() @@ -1118,15 +1139,19 @@ void ObjectList::select_current_volume(int idx, int vol_idx) void ObjectList::remove() { - auto item = GetSelection(); // #ys_FIXME_to_multi_sel - if (!item) + if (GetSelectedItemsCount() == 0) return; - if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { - wxGetApp().plater()->remove_selected(); // #ys_TESTME + wxDataViewItemArray sels; + GetSelections(sels); + + for (auto& item : sels) + { + if (m_objects_model->GetParent(item) == wxDataViewItem(0)) + wxGetApp().plater()->remove(m_objects_model->GetIdByItem(item)); + else + del_subobject_item(item); } - else - del_subobject(); } void ObjectList::init_objects() @@ -1183,7 +1208,7 @@ void ObjectList::update_selections_on_canvas() if (sel_cnt == 1) { wxDataViewItem item = GetSelection(); if (m_objects_model->IsSettingsItem(item)) - selection.clear(); + add_to_selection(m_objects_model->GetParent(item), selection, true); else add_to_selection(item, selection, true); @@ -1225,10 +1250,15 @@ void ObjectList::select_items(const wxDataViewItemArray& sels) m_prevent_list_events = false; } +void ObjectList::select_all() +{ + SelectAll(); + selection_changed(); +} + void ObjectList::fix_multiselection_conflicts() { - const int sel_cnt = GetSelectedItemsCount(); - if (sel_cnt <= 1) + if (GetSelectedItemsCount() <= 1) return; m_prevent_list_events = true; @@ -1239,7 +1269,7 @@ void ObjectList::fix_multiselection_conflicts() for (auto item : sels) { if (m_objects_model->IsSettingsItem(item)) Unselect(item); - if (m_objects_model->GetParent(item) != wxDataViewItem(0)) + else if (m_objects_model->GetParent(item) != wxDataViewItem(0)) Unselect(m_objects_model->GetParent(item)); } diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 6a9ef96ad0..21b4a729fb 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -85,16 +85,16 @@ public: void load_part(ModelObject* model_object, wxArrayString& part_names, const bool is_modifier); void load_lambda(ModelObject* model_object, wxArrayString& part_names, const bool is_modifier); void load_lambda(const std::string& type_name); - void del_subobject(); + void del_subobject_item(wxDataViewItem& item); void del_settings_from_config(); - bool del_subobject_from_object(const int volume_id); + bool del_subobject_from_object(const int obj_idx, const int vol_idx); void split(const bool split_part); bool get_volume_by_item(const bool split_part, const wxDataViewItem& item, ModelVolume*& volume); bool is_splittable_object(const bool split_part); wxPoint get_mouse_position_in_control(); wxBoxSizer* get_sizer(){return m_sizer;} - int get_sel_obj_id() const { return m_selected_object_id; } + int get_selected_obj_idx() const; bool is_parts_changed() const { return m_parts_changed; } bool is_part_settings_changed() const{ return m_part_settings_changed; } @@ -107,6 +107,8 @@ public: void add_object_to_list(size_t obj_idx); // Delete object from the list void delete_object_from_list(); + void delete_object_from_list(const size_t obj_idx); + void delete_volume_from_list(const size_t obj_idx, const size_t vol_idx); // Delete all objects from the list void delete_all_objects_from_list(); // Set count of object on c++ side @@ -129,6 +131,7 @@ public: void update_selections_on_canvas(); void select_item(const wxDataViewItem& item); void select_items(const wxDataViewItemArray& sels); + void select_all(); // correct current selections to avoid of the possible conflicts void fix_multiselection_conflicts(); }; diff --git a/src/slic3r/GUI/GUI_ObjectManipulation.cpp b/src/slic3r/GUI/GUI_ObjectManipulation.cpp index 5eb90054c0..9873914132 100644 --- a/src/slic3r/GUI/GUI_ObjectManipulation.cpp +++ b/src/slic3r/GUI/GUI_ObjectManipulation.cpp @@ -148,7 +148,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent): int ObjectManipulation::ol_selection() { - return wxGetApp().sidebar().get_ol_selection(); + return wxGetApp().obj_list()->get_selected_obj_idx(); } void ObjectManipulation::update_settings_list() diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 72ef476707..57d887cca2 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -614,11 +614,6 @@ void Sidebar::update_objects_list_extruder_column(int extruders_count) p->object_list->update_objects_list_extruder_column(extruders_count); } -int Sidebar::get_ol_selection() -{ - return p->object_list->get_sel_obj_id(); -} - void Sidebar::show_info_sizers(const bool show) { p->object_info->Show(show); @@ -1356,7 +1351,7 @@ void Plater::priv::remove(size_t obj_idx) model.delete_object(obj_idx); print.delete_object(obj_idx); // Delete object from Sidebar list - sidebar->obj_list()->delete_object_from_list(); + sidebar->obj_list()->delete_object_from_list(obj_idx); object_list_changed(); @@ -1931,7 +1926,7 @@ void Plater::changed_object_settings(int obj_idx) if (list->is_parts_changed()) { // recenter and re - align to Z = 0 - auto model_object = p->model.objects[list->get_sel_obj_id()]; + auto model_object = p->model.objects[obj_idx]; model_object->center_around_origin(); } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index b25b43b7d1..b174f5e211 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -69,7 +69,6 @@ public: ConfigOptionsGroup* og_freq_chng_params(); wxButton* get_wiping_dialog_button(); void update_objects_list_extruder_column(int extruders_count); - int get_ol_selection(); void show_info_sizers(const bool show); void show_buttons(const bool show); void enable_buttons(bool enable); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index c91d894bb0..23ad288b8a 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -591,7 +591,8 @@ wxDataViewItem PrusaObjectDataViewModel::GetItemByVolumeId(int obj_idx, int volu } auto parent = m_objects[obj_idx]; - if (parent->GetChildCount() == 0) { + if (parent->GetChildCount() == 0 || + (parent->GetChildCount() == 1 && parent->GetNthChild(0)->m_volume_id == -2)) { if (volume_idx == 0) return GetItemById(obj_idx); @@ -628,6 +629,23 @@ int PrusaObjectDataViewModel::GetVolumeIdByItem(const wxDataViewItem& item) return node->GetVolumeId(); } +void PrusaObjectDataViewModel::GetObjectAndVolumeIdsByItem(const wxDataViewItem& item, int& obj_idx, int& vol_idx) +{ + wxASSERT(item.IsOk()); + obj_idx = vol_idx = -1; + + PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); + if (!node) return; + vol_idx = node->GetVolumeId(); + + PrusaObjectDataViewModelNode *parent_node = node->GetParent(); + if (!parent_node) return; + + auto it = find(m_objects.begin(), m_objects.end(), parent_node); + if (it != m_objects.end()) + obj_idx = it - m_objects.begin(); +} + wxString PrusaObjectDataViewModel::GetName(const wxDataViewItem &item) const { PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index a6cbf1773b..33315880ff 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -422,7 +422,8 @@ public: wxDataViewItem GetItemByVolumeId(int obj_idx, int volume_idx); int GetIdByItem(wxDataViewItem& item); int GetVolumeIdByItem(const wxDataViewItem& item); - bool IsEmpty() { return m_objects.empty(); } + void GetObjectAndVolumeIdsByItem(const wxDataViewItem& item, int& obj_idx, int& vol_idx); + bool IsEmpty() { return m_objects.empty(); } // helper method for wxLog