From 59db1f7f3678a58314f515d2729bcbb4fef03a92 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 1 Aug 2019 14:58:04 +0200 Subject: [PATCH] Code refactoring to add PrintableItem column to ObjectList --- resources/icons/eye_closed.svg | 13 ++++ resources/icons/eye_open.svg | 11 ++++ src/slic3r/GUI/GUI_ObjectList.cpp | 73 +++++++++++--------- src/slic3r/GUI/wxExtensions.cpp | 106 ++++++++++++++++++------------ src/slic3r/GUI/wxExtensions.hpp | 43 +++++++----- 5 files changed, 159 insertions(+), 87 deletions(-) create mode 100644 resources/icons/eye_closed.svg create mode 100644 resources/icons/eye_open.svg diff --git a/resources/icons/eye_closed.svg b/resources/icons/eye_closed.svg new file mode 100644 index 000000000..127d53ca3 --- /dev/null +++ b/resources/icons/eye_closed.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/resources/icons/eye_open.svg b/resources/icons/eye_open.svg new file mode 100644 index 000000000..a87cf3a83 --- /dev/null +++ b/resources/icons/eye_open.svg @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index bb824ab00..bbb7d7115 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -212,16 +212,20 @@ void ObjectList::create_objects_ctrl() EnableDropTarget(wxDF_UNICODETEXT); #endif // wxUSE_DRAG_AND_DROP && wxUSE_UNICODE - // column 0(Icon+Text) of the view control: + // column ItemName(Icon+Text) of the view control: // And Icon can be consisting of several bitmaps AppendColumn(new wxDataViewColumn(_(L("Name")), new BitmapTextRenderer(), - 0, 20*wxGetApp().em_unit()/*200*/, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE)); + colName, 20*wxGetApp().em_unit()/*200*/, wxALIGN_LEFT, wxDATAVIEW_COL_RESIZABLE)); - // column 1 of the view control: + // column PrintableProperty (Icon) of the view control: + AppendBitmapColumn(" ", colPrint, wxDATAVIEW_CELL_INERT, int(2 * wxGetApp().em_unit()), + wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); + + // column Extruder of the view control: AppendColumn(create_objects_list_extruder_column(4)); - // column 2 of the view control: - AppendBitmapColumn(" ", 2, wxDATAVIEW_CELL_INERT, int(2.5 * wxGetApp().em_unit())/*25*/, + // column ItemEditing of the view control: + AppendBitmapColumn("Editing", colEditing, wxDATAVIEW_CELL_INERT, int(2.5 * wxGetApp().em_unit())/*25*/, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); } @@ -321,7 +325,7 @@ void ObjectList::set_tooltip_for_item(const wxPoint& pt) return; } - if (col->GetTitle() == " " && GetSelectedItemsCount()<2) + if (col->GetTitle() == _(L("Editing")) && GetSelectedItemsCount()<2) GetMainWindow()->SetToolTip(_(L("Right button click the icon to change the object settings"))); else if (col->GetTitle() == _("Name")) { @@ -377,7 +381,7 @@ wxDataViewColumn* ObjectList::create_objects_list_extruder_column(int extruders_ choices.Add(wxString::Format("%d", i)); wxDataViewChoiceRenderer *c = new wxDataViewChoiceRenderer(choices, wxDATAVIEW_CELL_EDITABLE, wxALIGN_CENTER_HORIZONTAL); - wxDataViewColumn* column = new wxDataViewColumn(_(L("Extruder")), c, 1, + wxDataViewColumn* column = new wxDataViewColumn(_(L("Extruder")), c, colExtruder, 8*wxGetApp().em_unit()/*80*/, wxALIGN_CENTER_HORIZONTAL, wxDATAVIEW_COL_RESIZABLE); return column; } @@ -397,7 +401,7 @@ void ObjectList::update_extruder_values_for_items(const int max_extruder) else extruder = wxString::Format("%d", object->config.option("extruder")->value); - m_objects_model->SetValue(extruder, item, 1); + m_objects_model->SetValue(extruder, item, colExtruder); if (object->volumes.size() > 1) { for (auto id = 0; id < object->volumes.size(); id++) { @@ -409,7 +413,7 @@ void ObjectList::update_extruder_values_for_items(const int max_extruder) else extruder = wxString::Format("%d", object->volumes[id]->config.option("extruder")->value); - m_objects_model->SetValue(extruder, item, 1); + m_objects_model->SetValue(extruder, item, colExtruder); } } } @@ -421,7 +425,7 @@ void ObjectList::update_objects_list_extruder_column(int extruders_count) if (printer_technology() == ptSLA) extruders_count = 1; - wxDataViewChoiceRenderer* ch_render = dynamic_cast(GetColumn(1)->GetRenderer()); + wxDataViewChoiceRenderer* ch_render = dynamic_cast(GetColumn(colExtruder)->GetRenderer()); if (ch_render->GetChoices().GetCount() - 1 == extruders_count) return; @@ -430,21 +434,21 @@ void ObjectList::update_objects_list_extruder_column(int extruders_count) if (m_objects && extruders_count > 1) update_extruder_values_for_items(extruders_count); - // delete old 2nd column - DeleteColumn(GetColumn(1)); - // insert new created 3rd column - InsertColumn(1, create_objects_list_extruder_column(extruders_count)); + // delete old extruder column + DeleteColumn(GetColumn(colExtruder)); + // insert new created extruder column + InsertColumn(colExtruder, create_objects_list_extruder_column(extruders_count)); // set show/hide for this column set_extruder_column_hidden(extruders_count <= 1); //a workaround for a wrong last column width updating under OSX - GetColumn(2)->SetWidth(25); + GetColumn(colEditing)->SetWidth(25); m_prevent_update_extruder_in_config = false; } void ObjectList::set_extruder_column_hidden(const bool hide) const { - GetColumn(1)->SetHidden(hide); + GetColumn(colExtruder)->SetHidden(hide); } void ObjectList::update_extruder_in_config(const wxDataViewItem& item) @@ -471,7 +475,7 @@ void ObjectList::update_extruder_in_config(const wxDataViewItem& item) } wxVariant variant; - m_objects_model->GetValue(variant, item, 1); + m_objects_model->GetValue(variant, item, colExtruder); const wxString selection = variant.GetString(); if (!m_config || selection.empty()) @@ -748,7 +752,9 @@ void ObjectList::OnContextMenu(wxDataViewEvent&) #endif // __WXOSX__ const wxString title = col->GetTitle(); - if (title == " ") + if (title == " "); + // show_context_menu(); + else if (title == _("Editing")) show_context_menu(); else if (title == _("Name")) { @@ -2260,7 +2266,13 @@ void ObjectList::add_object_to_list(size_t obj_idx, bool call_selection_changed) // add instances to the object, if it has those if (model_object->instances.size()>1) - increase_object_instances(obj_idx, model_object->instances.size()); + { + std::vector print_idicator(model_object->instances.size()); + for (int i = 0; i < model_object->instances.size(); ++i) + print_idicator[i] = model_object->instances[i]->is_printable(); + + select_item(m_objects_model->AddInstanceChild(m_objects_model->GetItemById(obj_idx), print_idicator)); + } // add settings to the object, if it has those add_settings_item(item, &model_object->config); @@ -2342,7 +2354,7 @@ void ObjectList::delete_from_model_and_list(const std::vector& it (*m_objects)[item->obj_idx]->config.has("extruder")) { const wxString extruder = wxString::Format("%d", (*m_objects)[item->obj_idx]->config.option("extruder")->value); - m_objects_model->SetValue(extruder, m_objects_model->GetItemById(item->obj_idx), 1); + m_objects_model->SetValue(extruder, m_objects_model->GetItemById(item->obj_idx), colExtruder); } wxGetApp().plater()->canvas3D()->ensure_on_bed(item->obj_idx); } @@ -3415,7 +3427,7 @@ void ObjectList::rename_item() // The icon can't be edited so get its old value and reuse it. wxVariant valueOld; - m_objects_model->GetValue(valueOld, item, 0); + m_objects_model->GetValue(valueOld, item, colName); DataViewBitmapText bmpText; bmpText << valueOld; @@ -3425,7 +3437,7 @@ void ObjectList::rename_item() wxVariant value; value << bmpText; - m_objects_model->SetValue(value, item, 0); + m_objects_model->SetValue(value, item, colName); m_objects_model->ItemChanged(item); update_name_in_model(item); @@ -3466,9 +3478,10 @@ void ObjectList::msw_rescale() // update min size !!! A width of control shouldn't be a wxDefaultCoord SetMinSize(wxSize(1, 15 * em)); - GetColumn(0)->SetWidth(19 * em); - GetColumn(1)->SetWidth( 8 * em); - GetColumn(2)->SetWidth( 2 * em); + GetColumn(colName)->SetWidth(19 * em); + GetColumn(colPrint)->SetWidth( 2 * em); + GetColumn(colExtruder)->SetWidth( 8 * em); + GetColumn(colEditing)->SetWidth( 2 * em); // rescale all icons, used by ObjectList msw_rescale_icons(); @@ -3489,18 +3502,18 @@ void ObjectList::msw_rescale() void ObjectList::ItemValueChanged(wxDataViewEvent &event) { - if (event.GetColumn() == 0) + if (event.GetColumn() == colName) update_name_in_model(event.GetItem()); - else if (event.GetColumn() == 1) + else if (event.GetColumn() == colExtruder) update_extruder_in_config(event.GetItem()); } void ObjectList::OnEditingDone(wxDataViewEvent &event) { - if (event.GetColumn() != 0) + if (event.GetColumn() != colName) return; - const auto renderer = dynamic_cast(GetColumn(0)->GetRenderer()); + const auto renderer = dynamic_cast(GetColumn(colName)->GetRenderer()); if (renderer->WasCanceled()) wxTheApp->CallAfter([this]{ @@ -3582,7 +3595,7 @@ void ObjectList::set_extruder_for_selected_items(const int extruder) const /* 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); + m_objects_model->SetValue(extruder_str, type & itInstance ? m_objects_model->GetTopParent(item) : item, colExtruder); const int obj_idx = type & itObject ? m_objects_model->GetIdByItem(item) : m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item)); diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 3886a35aa..5bb85e86d 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -450,6 +450,16 @@ wxBitmap create_scaled_bitmap(wxWindow *win, const std::string& bmp_name_in, // ObjectDataViewModelNode // ---------------------------------------------------------------------------- +void ObjectDataViewModelNode::init_container() +{ +#ifdef __WXGTK__ + // it's necessary on GTK because of control have to know if this item will be container + // in another case you couldn't to add subitem for this item + // it will be produce "segmentation fault" + m_container = true; +#endif //__WXGTK__ +} + ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent, const ItemType type) : m_parent(parent), m_type(type), @@ -472,13 +482,8 @@ ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent m_name = _(L("Layers")); } -#ifdef __WXGTK__ - // it's necessary on GTK because of control have to know if this item will be container - // in another case you couldn't to add subitem for this item - // it will be produce "segmentation fault" if (type & (itInstanceRoot | itLayerRoot)) - m_container = true; -#endif //__WXGTK__ + init_container(); } ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent, @@ -504,14 +509,8 @@ ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent m_name = _(L("Range")) + label_range + "(" + _(L("mm")) + ")"; m_bmp = create_scaled_bitmap(nullptr, "edit_layers_some"); // FIXME: pass window ptr -#ifdef __WXGTK__ - // it's necessary on GTK because of control have to know if this item will be container - // in another case you couldn't to add subitem for this item - // it will be produce "segmentation fault" - m_container = true; -#endif //__WXGTK__ - set_action_icon(); + init_container(); } void ObjectDataViewModelNode::set_action_icon() @@ -521,6 +520,13 @@ void ObjectDataViewModelNode::set_action_icon() m_action_icon = create_scaled_bitmap(nullptr, m_action_icon_name); // FIXME: pass window ptr } +void ObjectDataViewModelNode::set_printable_icon(PrintIndicator printable) +{ + m_printable = printable; + m_printable_icon = m_printable == piUndef ? m_empty_bmp : + create_scaled_bitmap(nullptr, m_printable == piPrintable ? "eye_open.png" : "eye_closed.png"); +} + Slic3r::GUI::BitmapCache *m_bitmap_cache = nullptr; void ObjectDataViewModelNode::update_settings_digest_bitmaps() { @@ -574,17 +580,20 @@ bool ObjectDataViewModelNode::SetValue(const wxVariant& variant, unsigned col) { switch (col) { - case 0: { + case colPrint: + m_printable_icon << variant; + return true; + case colName: { DataViewBitmapText data; data << variant; m_bmp = data.GetBitmap(); m_name = data.GetText(); return true; } - case 1: { + case colExtruder: { const wxString & val = variant.GetString(); m_extruder = val == "0" ? _(L("default")) : val; return true; } - case 2: + case colEditing: m_action_icon << variant; return true; default: @@ -744,26 +753,49 @@ static bool append_root_node(ObjectDataViewModelNode *parent_node, return false; } -wxDataViewItem ObjectDataViewModel::AddInstanceChild(const wxDataViewItem &parent_item, size_t num) +wxDataViewItem ObjectDataViewModel::AddRoot(const wxDataViewItem &parent_item, ItemType root_type) { ObjectDataViewModelNode *parent_node = (ObjectDataViewModelNode*)parent_item.GetID(); if (!parent_node) return wxDataViewItem(0); // get InstanceRoot node - ObjectDataViewModelNode *inst_root_node { nullptr }; + ObjectDataViewModelNode *root_node { nullptr }; + const bool appended = append_root_node(parent_node, &root_node, root_type); + if (!root_node) return wxDataViewItem(0); - const bool appended = append_root_node(parent_node, &inst_root_node, itInstanceRoot); - const wxDataViewItem inst_root_item((void*)inst_root_node); - if (!inst_root_node) return wxDataViewItem(0); + const wxDataViewItem root_item((void*)root_node); if (appended) - ItemAdded(parent_item, inst_root_item);// notify control + ItemAdded(parent_item, root_item);// notify control + return root_item; +} + +wxDataViewItem ObjectDataViewModel::AddInstanceRoot(const wxDataViewItem &parent_item) +{ + return AddRoot(parent_item, itInstanceRoot); +} + +wxDataViewItem ObjectDataViewModel::AddInstanceChild(const wxDataViewItem &parent_item, size_t num) +{ + const std::vector print_indicator(num, true); + + return wxDataViewItem((void*)AddInstanceChild(parent_item, print_indicator)); +} + +wxDataViewItem ObjectDataViewModel::AddInstanceChild(const wxDataViewItem& parent_item, + const std::vector& print_indicator) +{ + const wxDataViewItem inst_root_item = AddInstanceRoot(parent_item); + if (!inst_root_item) return wxDataViewItem(0); + + ObjectDataViewModelNode* inst_root_node = (ObjectDataViewModelNode*)inst_root_item.GetID(); // Add instance nodes ObjectDataViewModelNode *instance_node = nullptr; size_t counter = 0; - while (counter < num) { + while (counter < print_indicator.size()) { instance_node = new ObjectDataViewModelNode(inst_root_node, itInstance); + instance_node->set_printable_icon(print_indicator[counter] ? piPrintable : piUnprintable); inst_root_node->Append(instance_node); // notify control const wxDataViewItem instance_item((void*)instance_node); @@ -776,20 +808,7 @@ wxDataViewItem ObjectDataViewModel::AddInstanceChild(const wxDataViewItem &paren wxDataViewItem ObjectDataViewModel::AddLayersRoot(const wxDataViewItem &parent_item) { - ObjectDataViewModelNode *parent_node = (ObjectDataViewModelNode*)parent_item.GetID(); - if (!parent_node) return wxDataViewItem(0); - - // get LayerRoot node - ObjectDataViewModelNode *layer_root_node{ nullptr }; - const bool appended = append_root_node(parent_node, &layer_root_node, itLayerRoot); - if (!layer_root_node) return wxDataViewItem(0); - - const wxDataViewItem layer_root_item((void*)layer_root_node); - - if (appended) - ItemAdded(parent_item, layer_root_item);// notify control - - return layer_root_item; + return AddRoot(parent_item, itLayerRoot); } wxDataViewItem ObjectDataViewModel::AddLayersChild(const wxDataViewItem &parent_item, @@ -1356,13 +1375,16 @@ void ObjectDataViewModel::GetValue(wxVariant &variant, const wxDataViewItem &ite ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); switch (col) { - case 0: + case colPrint: + variant << node->m_printable_icon; + break; + case colName: variant << DataViewBitmapText(node->m_name, node->m_bmp); break; - case 1: + case colExtruder: variant = node->m_extruder; break; - case 2: + case colEditing: variant << node->m_action_icon; break; default: @@ -1425,7 +1447,7 @@ bool ObjectDataViewModel::IsEnabled(const wxDataViewItem &item, unsigned int col ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID(); // disable extruder selection for the non "itObject|itVolume" item - return !(col == 1 && node->m_extruder.IsEmpty()); + return !(col == colExtruder && node->m_extruder.IsEmpty()); } wxDataViewItem ObjectDataViewModel::GetParent(const wxDataViewItem &item) const @@ -1773,7 +1795,7 @@ bool BitmapTextRenderer::GetValueFromEditorCtrl(wxWindow* ctrl, wxVariant& value // The icon can't be edited so get its old value and reuse it. wxVariant valueOld; - GetView()->GetModel()->GetValue(valueOld, m_item, 0); + GetView()->GetModel()->GetValue(valueOld, m_item, colName); DataViewBitmapText bmpText; bmpText << valueOld; diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 785634b30..679d9346d 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -175,6 +175,21 @@ enum ItemType { itLayer = 64, }; +enum ColumnNumber +{ + colName = 0, // item name + colPrint , // printable property + colExtruder , // extruder selection + colEditing , // item editing +}; + +enum PrintIndicator +{ + piUndef = 0, // no print indicator + piPrintable , // printable + piUnprintable , // unprintable +}; + class ObjectDataViewModelNode; WX_DEFINE_ARRAY_PTR(ObjectDataViewModelNode*, MyObjectTreeModelNodePtrArray); @@ -194,6 +209,8 @@ class ObjectDataViewModelNode bool m_container = false; wxString m_extruder = "default"; wxBitmap m_action_icon; + PrintIndicator m_printable {piUndef}; + wxBitmap m_printable_icon; std::string m_action_icon_name = ""; Slic3r::ModelVolumeType m_volume_type; @@ -206,14 +223,8 @@ public: m_type(itObject), m_extruder(extruder) { -#ifdef __WXGTK__ - // it's necessary on GTK because of control have to know if this item will be container - // in another case you couldn't to add subitem for this item - // it will be produce "segmentation fault" - m_container = true; -#endif //__WXGTK__ - set_action_icon(); + init_container(); } ObjectDataViewModelNode(ObjectDataViewModelNode* parent, @@ -227,15 +238,9 @@ public: m_idx (idx), m_extruder (extruder) { - m_bmp = bmp; -#ifdef __WXGTK__ - // it's necessary on GTK because of control have to know if this item will be container - // in another case you couldn't to add subitem for this item - // it will be produce "segmentation fault" - m_container = true; -#endif //__WXGTK__ - + m_bmp = bmp; set_action_icon(); + init_container(); } ObjectDataViewModelNode(ObjectDataViewModelNode* parent, @@ -256,6 +261,7 @@ public: } } + void init_container(); bool IsContainer() const { return m_container; @@ -344,6 +350,8 @@ public: // Set action icons for node void set_action_icon(); + // Set printable icon for node + void set_printable_icon(PrintIndicator printable); void update_settings_digest_bitmaps(); bool update_settings_digest(const std::vector& categories); @@ -383,6 +391,7 @@ public: const bool create_frst_child = true); wxDataViewItem AddSettingsChild(const wxDataViewItem &parent_item); wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, size_t num); + wxDataViewItem AddInstanceChild(const wxDataViewItem &parent_item, const std::vector& print_indicator); wxDataViewItem AddLayersRoot(const wxDataViewItem &parent_item); wxDataViewItem AddLayersChild( const wxDataViewItem &parent_item, const t_layer_height_range& layer_range, @@ -472,6 +481,10 @@ public: const bool is_marked = false); void DeleteWarningIcon(const wxDataViewItem& item, const bool unmark_object = false); t_layer_height_range GetLayerRangeByItem(const wxDataViewItem& item) const; + +private: + wxDataViewItem AddRoot(const wxDataViewItem& parent_item, const ItemType root_type); + wxDataViewItem AddInstanceRoot(const wxDataViewItem& parent_item); }; // ----------------------------------------------------------------------------