diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 22ebc093f6..7ed6e5a28a 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -75,6 +75,8 @@ ObjectList::ObjectList(wxWindow* parent) : Bind(wxEVT_DATAVIEW_ITEM_DROP_POSSIBLE, &ObjectList::OnDropPossible, this); Bind(wxEVT_DATAVIEW_ITEM_DROP, &ObjectList::OnDrop, this); + Bind(wxEVT_DATAVIEW_ITEM_EDITING_DONE, &ObjectList::OnEditingDone, this); + Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, &ObjectList::ItemValueChanged, this); Bind(wxCUSTOMEVT_LAST_VOLUME_IS_DELETED, [this](wxCommandEvent& e) { last_volume_is_deleted(e.GetInt()); }); @@ -290,6 +292,21 @@ void ObjectList::update_extruder_in_config(const wxDataViewItem& item) wxGetApp().plater()->update(); } +void ObjectList::update_name_in_model(const wxDataViewItem& item) +{ + const int obj_idx = m_objects_model->GetObjectIdByItem(item); + if (obj_idx < 0) return; + + if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { + (*m_objects)[obj_idx]->name = m_objects_model->GetName(item).ToStdString(); + return; + } + + const int volume_id = m_objects_model->GetVolumeIdByItem(item); + if (volume_id < 0) return; + (*m_objects)[obj_idx]->volumes[volume_id]->name = m_objects_model->GetName(item).ToStdString(); +} + void ObjectList::init_icons() { m_bmp_modifiermesh = wxBitmap(from_u8(var("lambda.png")), wxBITMAP_TYPE_PNG);//(Slic3r::var("plugin.png")), wxBITMAP_TYPE_PNG); @@ -337,9 +354,7 @@ void ObjectList::selection_changed() void ObjectList::OnChar(wxKeyEvent& event) { -// printf("KeyDown event\n"); if (event.GetKeyCode() == WXK_BACK){ - printf("WXK_BACK\n"); remove(); } else if (wxGetKeyState(wxKeyCode('A')) && wxGetKeyState(WXK_SHIFT)) @@ -370,15 +385,14 @@ void ObjectList::OnContextMenu(wxDataViewEvent&) if (title == " ") show_context_menu(); - - else if (title == _("Name") && pt.x >15 && - m_objects_model->GetBitmap(item).GetRefData() == m_bmp_manifold_warning.GetRefData()) - { - if (is_windows10()) { - const auto obj_idx = m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item)); - wxGetApp().plater()->fix_through_netfabb(obj_idx); - } + else if (title == _("Name") && pt.x >15 && + m_objects_model->GetBitmap(item).GetRefData() == m_bmp_manifold_warning.GetRefData()) + { + if (is_windows10()) { + const auto obj_idx = m_objects_model->GetIdByItem(m_objects_model->GetTopParent(item)); + wxGetApp().plater()->fix_through_netfabb(obj_idx); } + } #ifndef __WXMSW__ GetMainWindow()->SetToolTip(""); // hide tooltip #endif //__WXMSW__ @@ -455,10 +469,10 @@ void ObjectList::OnDropPossible(wxDataViewEvent &event) wxDataViewItem item(event.GetItem()); // only allow drags for item or background, not containers - if (item.IsOk() && - (m_objects_model->GetParent(item) == wxDataViewItem(0) || + if (!item.IsOk() || + m_objects_model->GetParent(item) == wxDataViewItem(0) || m_objects_model->GetItemType(item) != itVolume || - m_dragged_data.obj_idx() != m_objects_model->GetObjectIdByItem(item))) + m_dragged_data.obj_idx() != m_objects_model->GetObjectIdByItem(item)) event.Veto(); } @@ -466,9 +480,9 @@ void ObjectList::OnDrop(wxDataViewEvent &event) { wxDataViewItem item(event.GetItem()); - if (item.IsOk() && ( m_objects_model->GetParent(item) == wxDataViewItem(0) || - m_objects_model->GetItemType(item) != itVolume) || - m_dragged_data.obj_idx() != m_objects_model->GetObjectIdByItem(item)) { + if (!item.IsOk() || m_objects_model->GetParent(item) == wxDataViewItem(0) || + m_objects_model->GetItemType(item) != itVolume || + m_dragged_data.obj_idx() != m_objects_model->GetObjectIdByItem(item)) { event.Veto(); m_dragged_data.clear(); return; @@ -1667,7 +1681,22 @@ void ObjectList::update_settings_items() void ObjectList::ItemValueChanged(wxDataViewEvent &event) { - update_extruder_in_config(event.GetItem()); + if (event.GetColumn() == 0) + update_name_in_model(event.GetItem()); + else if (event.GetColumn() == 1) + update_extruder_in_config(event.GetItem()); +} + +void ObjectList::OnEditingDone(wxDataViewEvent &event) +{ + if (event.GetColumn() != 0) + return; + + const auto renderer = dynamic_cast(GetColumn(0)->GetRenderer()); + + if (renderer->WasCanceled()) + show_error(this, _(L("The supplied name is not valid;")) + "\n" + + _(L("the following characters are not allowed:")) + " <>:/\\|?*\""); } } //namespace GUI diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index 33e3894fe4..3664e6fdaa 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -128,6 +128,8 @@ public: void set_extruder_column_hidden(const bool hide) const; // update extruder in current config void update_extruder_in_config(const wxDataViewItem& item); + // update changed name in the object model + void update_name_in_model(const wxDataViewItem& item); void update_extruder_values_for_items(const int max_extruder); void init_icons(); @@ -227,6 +229,7 @@ private: void OnDrop(wxDataViewEvent &event); void ItemValueChanged(wxDataViewEvent &event); + void OnEditingDone(wxDataViewEvent &event); }; diff --git a/src/slic3r/GUI/wxExtensions.cpp b/src/slic3r/GUI/wxExtensions.cpp index 57828ea9aa..2e5a37040b 100644 --- a/src/slic3r/GUI/wxExtensions.cpp +++ b/src/slic3r/GUI/wxExtensions.cpp @@ -1281,6 +1281,52 @@ wxSize PrusaBitmapTextRenderer::GetSize() const } +wxWindow* PrusaBitmapTextRenderer::CreateEditorCtrl(wxWindow* parent, wxRect labelRect, const wxVariant& value) +{ + wxDataViewCtrl* const dv_ctrl = GetOwner()->GetOwner(); + PrusaObjectDataViewModel* const model = dynamic_cast(dv_ctrl->GetModel()); + + if ( !(model->GetItemType(dv_ctrl->GetSelection()) & (itVolume | itObject)) ) + return nullptr; + + PrusaDataViewBitmapText data; + data << value; + m_bmp_from_editing_item = data.GetBitmap(); + m_was_unusable_symbol = false; + + wxPoint position = labelRect.GetPosition(); + if (m_bmp_from_editing_item.IsOk()) { + const int bmp_width = m_bmp_from_editing_item.GetWidth(); + position.x += bmp_width; + labelRect.SetWidth(labelRect.GetWidth() - bmp_width); + } + + wxTextCtrl* text_editor = new wxTextCtrl(parent, wxID_ANY, data.GetText(), + position, labelRect.GetSize(), wxTE_PROCESS_ENTER); + text_editor->SetInsertionPointEnd(); + + return text_editor; +} + +bool PrusaBitmapTextRenderer::GetValueFromEditorCtrl(wxWindow* ctrl, wxVariant& value) +{ + wxTextCtrl* text_editor = wxDynamicCast(ctrl, wxTextCtrl); + if (!text_editor || text_editor->GetValue().IsEmpty()) + return false; + + std::string chosen_name = Slic3r::normalize_utf8_nfc(text_editor->GetValue().ToUTF8()); + const char* unusable_symbols = "<>:/\\|?*\""; + for (size_t i = 0; i < std::strlen(unusable_symbols); i++) { + if (chosen_name.find_first_of(unusable_symbols[i]) != std::string::npos) { + m_was_unusable_symbol = true; + return false; + } + } + + value << PrusaDataViewBitmapText(text_editor->GetValue(), m_bmp_from_editing_item); + return true; +} + // ---------------------------------------------------------------------------- // PrusaDoubleSlider // ---------------------------------------------------------------------------- diff --git a/src/slic3r/GUI/wxExtensions.hpp b/src/slic3r/GUI/wxExtensions.hpp index 866317e254..3fbf9a0839 100644 --- a/src/slic3r/GUI/wxExtensions.hpp +++ b/src/slic3r/GUI/wxExtensions.hpp @@ -522,7 +522,7 @@ public: class PrusaBitmapTextRenderer : public wxDataViewCustomRenderer { public: - PrusaBitmapTextRenderer( wxDataViewCellMode mode = wxDATAVIEW_CELL_INERT, + PrusaBitmapTextRenderer( wxDataViewCellMode mode = wxDATAVIEW_CELL_EDITABLE, int align = wxDVR_DEFAULT_ALIGNMENT): wxDataViewCustomRenderer(wxT("PrusaDataViewBitmapText"), mode, align) {} @@ -532,10 +532,18 @@ public: virtual bool Render(wxRect cell, wxDC *dc, int state); virtual wxSize GetSize() const; - virtual bool HasEditorCtrl() const { return false; } + bool HasEditorCtrl() const override { return true; } + wxWindow* CreateEditorCtrl(wxWindow* parent, + wxRect labelRect, + const wxVariant& value) override; + bool GetValueFromEditorCtrl( wxWindow* ctrl, + wxVariant& value) override; + bool WasCanceled() const { return m_was_unusable_symbol; } private: PrusaDataViewBitmapText m_value; + wxBitmap m_bmp_from_editing_item; + bool m_was_unusable_symbol; };