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);
};
// ----------------------------------------------------------------------------