From 13388f1caa1ccdf2a7d3b87121920a979dfa1227 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 13 Aug 2018 14:15:43 +0200 Subject: [PATCH] Drag & Drop for sub-objects (parts of the object) --- xs/src/slic3r/GUI/GUI_ObjectParts.cpp | 42 +++++++++++++-------------- xs/src/slic3r/GUI/wxExtensions.cpp | 26 +++++++++++++++++ xs/src/slic3r/GUI/wxExtensions.hpp | 5 ++++ 3 files changed, 51 insertions(+), 22 deletions(-) diff --git a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp index 90fc615658..a5174fff38 100644 --- a/xs/src/slic3r/GUI/GUI_ObjectParts.cpp +++ b/xs/src/slic3r/GUI/GUI_ObjectParts.cpp @@ -306,6 +306,7 @@ wxBoxSizer* content_objects_list(wxWindow *win) m_objects_ctrl->GetMainWindow()->Bind(wxEVT_MOTION, [](wxMouseEvent& event) { set_tooltip_for_item(event.GetPosition()); + event.Skip(); }); #else m_objects_ctrl->Bind(wxEVT_DATAVIEW_ITEM_VALUE_CHANGED, [](wxDataViewEvent& event) @@ -1536,17 +1537,15 @@ void on_begin_drag(wxDataViewEvent &event) wxDataViewItem item(event.GetItem()); // only allow drags for item, not containers - if (m_objects_model->GetParent(item) == wxDataViewItem(0)) - { + if (m_objects_model->GetParent(item) == wxDataViewItem(0)) { event.Veto(); return; } - PrusaObjectDataViewModelNode *node = (PrusaObjectDataViewModelNode*)item.GetID(); wxTextDataObject *obj = new wxTextDataObject; - obj->SetText(node->m_name); + obj->SetText(wxString::Format("%d", m_objects_model->GetVolumeIdByItem(item))); event.SetDataObject(obj); - event.SetDragFlags(wxDrag_AllowMove); // allows both copy and move; + event.SetDragFlags(/*wxDrag_AllowMove*/wxDrag_DefaultMove); // allows both copy and move; } void on_drop_possible(wxDataViewEvent &event) @@ -1554,10 +1553,8 @@ void on_drop_possible(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)) - event.Veto(); - - if (event.GetDataFormat() != wxDF_UNICODETEXT) + if (item.IsOk() && m_objects_model->GetParent(item) == wxDataViewItem(0) || + event.GetDataFormat() != wxDF_UNICODETEXT) event.Veto(); } @@ -1566,25 +1563,26 @@ void on_drop(wxDataViewEvent &event) wxDataViewItem item(event.GetItem()); // only allow drops for item, not containers - if (item.IsOk() && m_objects_model->GetParent(item) == wxDataViewItem(0)) - { + if (item.IsOk() && m_objects_model->GetParent(item) == wxDataViewItem(0) || + event.GetDataFormat() != wxDF_UNICODETEXT) { event.Veto(); return; - } - - if (event.GetDataFormat() != wxDF_UNICODETEXT) - { - event.Veto(); - return; - } + } wxTextDataObject obj; obj.SetData(wxDF_UNICODETEXT, event.GetDataSize(), event.GetDataBuffer()); - if (item.IsOk()) - wxMessageBox(wxString::Format("Text dropped on item %s: %s", m_objects_model->GetName(item), obj.GetText())); - else - wxMessageBox(wxString::Format("Text dropped on background: %s", obj.GetText())); + int from_volume_id = std::stoi(obj.GetText().ToStdString()); + int to_volume_id = m_objects_model->GetVolumeIdByItem(item); + + m_objects_ctrl->Select(m_objects_model->ReorganizeChildren(from_volume_id, to_volume_id, + m_objects_model->GetParent(item))); + + auto& volumes = (*m_objects)[m_selected_object_id]->volumes; + auto delta = to_volume_id < from_volume_id ? -1 : 1; + int cnt = 0; + for (int id = from_volume_id; cnt < abs(from_volume_id - to_volume_id); id+=delta, cnt++) + std::swap(volumes[id], volumes[id +delta]); } } //namespace GUI diff --git a/xs/src/slic3r/GUI/wxExtensions.cpp b/xs/src/slic3r/GUI/wxExtensions.cpp index 71f49a9703..6c330a3d62 100644 --- a/xs/src/slic3r/GUI/wxExtensions.cpp +++ b/xs/src/slic3r/GUI/wxExtensions.cpp @@ -664,6 +664,32 @@ wxDataViewItem PrusaObjectDataViewModel::MoveChildDown(const wxDataViewItem &ite return ret_item; } +wxDataViewItem PrusaObjectDataViewModel::ReorganizeChildren(int current_volume_id, int new_volume_id, const wxDataViewItem &parent) +{ + auto ret_item = wxDataViewItem(0); + if (current_volume_id == new_volume_id) + return ret_item; + wxASSERT(parent.IsOk()); + PrusaObjectDataViewModelNode *node_parent = (PrusaObjectDataViewModelNode*)parent.GetID(); + if (!node_parent) // happens if item.IsOk()==false + return ret_item; + + PrusaObjectDataViewModelNode *deleted_node = node_parent->GetNthChild(current_volume_id); + node_parent->GetChildren().Remove(deleted_node); + ItemDeleted(parent, wxDataViewItem(deleted_node)); + node_parent->Insert(deleted_node, new_volume_id); + ItemAdded(parent, wxDataViewItem(deleted_node)); + + //update volume_id value for child-nodes + auto children = node_parent->GetChildren(); + int id_frst = current_volume_id < new_volume_id ? current_volume_id : new_volume_id; + int id_last = current_volume_id > new_volume_id ? current_volume_id : new_volume_id; + for (int id = id_frst; id <= id_last; ++id) + children[id]->SetVolumeId(id); + + return wxDataViewItem(node_parent->GetNthChild(new_volume_id)); +} + // bool MyObjectTreeModel::IsEnabled(const wxDataViewItem &item, unsigned int col) const // { // diff --git a/xs/src/slic3r/GUI/wxExtensions.hpp b/xs/src/slic3r/GUI/wxExtensions.hpp index daff37a60d..b536232b81 100644 --- a/xs/src/slic3r/GUI/wxExtensions.hpp +++ b/xs/src/slic3r/GUI/wxExtensions.hpp @@ -381,6 +381,11 @@ public: wxDataViewItem MoveChildUp(const wxDataViewItem &item); wxDataViewItem MoveChildDown(const wxDataViewItem &item); + // For parent move child from cur_volume_id place to new_volume_id + // Remaining items will moved up/down accordingly + wxDataViewItem ReorganizeChildren(int cur_volume_id, + int new_volume_id, + const wxDataViewItem &parent); // virtual bool IsEnabled(const wxDataViewItem &item, // unsigned int col) const override;