diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 98c9a9466..a3f381e5c 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -515,10 +515,10 @@ sub new { $self->{right_panel}->SetSizer($right_sizer); $right_sizer->SetMinSize([320, -1]); $right_sizer->Add($presets, 0, wxEXPAND | wxTOP, 10) if defined $presets; - $right_sizer->Add($frequently_changed_parameters_sizer, 1, wxEXPAND | wxTOP, 0) if defined $frequently_changed_parameters_sizer; + $right_sizer->Add($frequently_changed_parameters_sizer, 2, wxEXPAND | wxTOP, 0) if defined $frequently_changed_parameters_sizer; $right_sizer->Add($expert_mode_part_sizer, 0, wxEXPAND | wxTOP, 0) if defined $expert_mode_part_sizer; $right_sizer->Add($buttons_sizer, 0, wxEXPAND | wxBOTTOM, 5); - $right_sizer->Add($info_sizer, 0, wxEXPAND | wxLEFT, 20); + $right_sizer->Add($info_sizer, 1, wxEXPAND | wxLEFT, 20); $right_sizer->Add($self->{btn_export_gcode}, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, 20); # Callback for showing / hiding the print info box. $self->{"print_info_box_show"} = sub { @@ -847,6 +847,9 @@ sub load_model_objects { $self->{list}->SetItem($obj_idx, 1, $model_object->instances_count); $self->{list}->SetItem($obj_idx, 2, ($model_object->instances->[0]->scaling_factor * 100) . "%"); + + # Add object to list on c++ side + Slic3r::GUI::add_object_to_list($object->name, $model_object->instances_count, ($model_object->instances->[0]->scaling_factor * 100)); $self->reset_thumbnail($obj_idx); } @@ -894,6 +897,8 @@ sub remove { $self->{model}->delete_object($obj_idx); $self->{print}->delete_object($obj_idx); $self->{list}->DeleteItem($obj_idx); + # Delete object from list on c++ side + Slic3r::GUI::delete_object_from_list(); $self->object_list_changed; $self->select_object(undef); @@ -917,6 +922,8 @@ sub reset { $self->{model}->clear_objects; $self->{print}->clear_objects; $self->{list}->DeleteAllItems; + # Delete all objects from list on c++ side + Slic3r::GUI::delete_all_objects_from_list(); $self->object_list_changed; $self->select_object(undef); diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp index 77a1a54b8..7f26816f0 100644 --- a/xs/src/slic3r/GUI/GUI.cpp +++ b/xs/src/slic3r/GUI/GUI.cpp @@ -477,7 +477,7 @@ void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_l void add_menus(wxMenuBar *menu, int event_preferences_changed, int event_language_change) { - add_config_menu(menu, event_language_change, event_language_change); + add_config_menu(menu, event_preferences_changed, event_language_change); } // This is called when closing the application, when loading a config file or when starting the config wizard @@ -1038,36 +1038,52 @@ wxBoxSizer* content_settings(wxWindow *win) return sizer; } -void add_object(const std::string &name) +void add_object_to_list(const std::string &name, int instances_count, int scale) { wxString item = name; - m_objects_ctrl->Select(m_objects_model->Add(item)); + m_objects_ctrl->Select(m_objects_model->Add(item, instances_count, scale)); } -void del_object() +void delete_object_from_list() { auto item = m_objects_ctrl->GetSelection(); - if (!item) return; - m_objects_ctrl->Select(m_objects_model->Delete(item)); + if (!item || m_objects_model->GetParent(item) != wxDataViewItem(0)) + return; +// m_objects_ctrl->Select(m_objects_model->Delete(item)); + m_objects_model->Delete(item); if (m_objects_model->IsEmpty()) m_collpane_settings->show_it(false); } +void delete_all_objects_from_list() +{ + m_objects_model->DeleteAll(); + m_collpane_settings->show_it(false); +} + void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) { wxWindowUpdateLocker noUpdates(parent); + auto btn_grid_sizer = new wxGridSizer(1, 3, 2, 2); + sizer->Add(btn_grid_sizer, 0, wxALIGN_LEFT | wxLEFT, 20); + // Experiments with new UI auto add_btn = new wxButton(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); if (wxMSW) add_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); add_btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("add.png")), wxBITMAP_TYPE_PNG)); - sizer->Add(add_btn, 0, wxALIGN_LEFT | wxLEFT | wxTOP, 20); + btn_grid_sizer->Add(add_btn, 0, wxEXPAND, 0); auto del_btn = new wxButton(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); if (wxMSW) del_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); del_btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("brick_delete.png")), wxBITMAP_TYPE_PNG)); - sizer->Add(del_btn, 0, wxALIGN_LEFT | wxLEFT, 20); + btn_grid_sizer->Add(del_btn, 0, wxEXPAND, 0); + + auto del_all_btn = new wxButton(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); + if (wxMSW) del_all_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + del_all_btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("delete.png")), wxBITMAP_TYPE_PNG)); + btn_grid_sizer->Add(del_all_btn, 0, wxEXPAND, 0); // *** Objects List *** auto collpane = add_prusa_collapsible_pane(parent, sizer, "Objects List:", content_objects_list); @@ -1095,7 +1111,9 @@ void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer) m_objects_ctrl->Select(m_objects_model->Add(name)); }); - del_btn->Bind(wxEVT_BUTTON, [](wxEvent& ) { del_object(); }); + del_btn->Bind(wxEVT_BUTTON, [](wxEvent& ) { delete_object_from_list(); }); + + del_all_btn->Bind(wxEVT_BUTTON, [](wxEvent&) { delete_all_objects_from_list(); }); // More experiments with UI // auto listctrl = new wxDataViewListCtrl(main_page, wxID_ANY, wxDefaultPosition, wxSize(-1, 100)); @@ -1302,7 +1320,7 @@ void show_buttons(bool show) void show_scrolled_window_sizer(bool show) { - g_scrolled_window_sizer->Show(static_cast(0), false/*show*/); //don't used now + g_scrolled_window_sizer->Show(static_cast(0), /*false*/show); //don't used now g_scrolled_window_sizer->Show(1, show); g_scrolled_window_sizer->Show(2, show && g_show_print_info); g_manifold_warning_icon->Show(show && g_show_manifold_warning_icon); diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp index 79dc2c595..293183e7d 100644 --- a/xs/src/slic3r/GUI/GUI.hpp +++ b/xs/src/slic3r/GUI/GUI.hpp @@ -175,9 +175,12 @@ wxString L_str(const std::string &str); wxString from_u8(const std::string &str); // Add object to the list -void add_object(const std::string &name); +//void add_object(const std::string &name); +void add_object_to_list(const std::string &name, int instances_count=1, int scale=100); // Delete object from the list -void del_object(); +void delete_object_from_list(); +// Delete all objects from the list +void delete_all_objects_from_list(); void add_expert_mode_part(wxWindow* parent, wxBoxSizer* sizer); void add_frequently_changed_parameters(wxWindow* parent, wxBoxSizer* sizer, wxFlexGridSizer* preset_sizer); diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index ecb79caaf..268267cd2 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -363,6 +363,17 @@ wxDataViewItem MyObjectTreeModel::Add(wxString &name) return child; } +wxDataViewItem MyObjectTreeModel::Add(wxString &name, int instances_count, int scale) +{ + auto root = new MyObjectTreeModelNode(name, instances_count, scale); + m_objects.push_back(root); + // notify control + wxDataViewItem child((void*)root); + wxDataViewItem parent((void*)NULL); + ItemAdded(parent, child); + return child; +} + wxDataViewItem MyObjectTreeModel::AddChild(const wxDataViewItem &parent_item, wxString &name) { MyObjectTreeModelNode *root = (MyObjectTreeModelNode*)parent_item.GetID(); @@ -431,6 +442,27 @@ wxDataViewItem MyObjectTreeModel::Delete(const wxDataViewItem &item) return ret_item; } +void MyObjectTreeModel::DeleteAll() +{ + while (!m_objects.empty()) + { + auto object = m_objects.back(); +// object->RemoveAllChildren(); + Delete(wxDataViewItem(object)); + } +} + +wxDataViewItem MyObjectTreeModel::GetItemById(int obj_idx) +{ + if (obj_idx >= m_objects.size()) + { + printf("Error! Out of objects range.\n"); + return wxDataViewItem(0); + } + return wxDataViewItem(m_objects[obj_idx]); +} + + wxString MyObjectTreeModel::GetName(const wxDataViewItem &item) const { MyObjectTreeModelNode *node = (MyObjectTreeModelNode*)item.GetID(); @@ -475,7 +507,7 @@ void MyObjectTreeModel::GetValue(wxVariant &variant, const wxDataViewItem &item, variant = node->m_scale; break; default: - ;// wxLogError("MyMusicTreeModel::GetValue: wrong column %d", col); + ; } } diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index 329eecd59..189637de5 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -137,11 +137,11 @@ class MyObjectTreeModelNode MyObjectTreeModelNode* m_parent; MyObjectTreeModelNodePtrArray m_children; public: - MyObjectTreeModelNode( const wxString &name) { + MyObjectTreeModelNode(const wxString &name, int instances_count=1, int scale=100) { m_parent = NULL; m_name = name; - m_copy = "1"; - m_scale = "100%"; + m_copy = wxString::Format("%d", instances_count); + m_scale = wxString::Format("%d%%", scale); } MyObjectTreeModelNode( MyObjectTreeModelNode* parent, @@ -195,6 +195,20 @@ public: m_container = true; m_children.Add(child); } + void RemoveAllChildren() + { + if (GetChildCount() == 0) + return; + for (size_t id = GetChildCount() - 1; id >= 0; --id) + { + if (m_children.Item(id)->GetChildCount() > 0) + m_children[id]->RemoveAllChildren(); + auto node = m_children[id]; + m_children.RemoveAt(id); + delete node; + } + } + size_t GetChildCount() const { return m_children.GetCount(); @@ -217,8 +231,11 @@ public: } wxDataViewItem Add(wxString &name); + wxDataViewItem Add(wxString &name, int instances_count, int scale); wxDataViewItem AddChild(const wxDataViewItem &parent_item, wxString &name); wxDataViewItem Delete(const wxDataViewItem &item); + void DeleteAll(); + wxDataViewItem GetItemById(int obj_idx); bool IsEmpty() { return m_objects.empty(); } // helper method for wxLog diff --git a/xs/xsp/GUI.xsp b/xs/xsp/GUI.xsp index 905954172..b38970c09 100644 --- a/xs/xsp/GUI.xsp +++ b/xs/xsp/GUI.xsp @@ -122,11 +122,14 @@ void set_show_manifold_warning_icon(bool show) void update_mode() %code%{ Slic3r::GUI::update_mode(); %}; -void add_object(const char *name) - %code%{ Slic3r::GUI::add_object(name); %}; +void add_object_to_list(const char *name, int instances_count, int scale) + %code%{ Slic3r::GUI::add_object_to_list(name, instances_count, scale); %}; -void del_object() - %code%{ Slic3r::GUI::del_object(); %}; +void delete_object_from_list() + %code%{ Slic3r::GUI::delete_object_from_list(); %}; + +void delete_all_objects_from_list() + %code%{ Slic3r::GUI::delete_all_objects_from_list(); %}; std::string fold_utf8_to_ascii(const char *src) %code%{ RETVAL = Slic3r::fold_utf8_to_ascii(src); %};