diff --git a/resources/icons/copy.svg b/resources/icons/copy.svg
new file mode 100644
index 0000000000..fcb24122de
--- /dev/null
+++ b/resources/icons/copy.svg
@@ -0,0 +1,15 @@
+
+
+
diff --git a/resources/icons/paste.svg b/resources/icons/paste.svg
new file mode 100644
index 0000000000..ba698e5b5e
--- /dev/null
+++ b/resources/icons/paste.svg
@@ -0,0 +1,19 @@
+
+
+
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index d1e5bbac6d..f911dd1718 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -3232,12 +3232,37 @@ bool GLCanvas3D::_init_toolbar()
if (!m_toolbar.add_separator())
return false;
+ item.name = "copy";
+#if ENABLE_SVG_ICONS
+ item.icon_filename = "copy.svg";
+#endif // ENABLE_SVG_ICONS
+ item.tooltip = GUI::L_str("Copy [Ctrl+C]");
+ item.sprite_id = 4;
+ item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_COPY)); };
+ item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_copy(); };
+ if (!m_toolbar.add_item(item))
+ return false;
+
+ item.name = "paste";
+#if ENABLE_SVG_ICONS
+ item.icon_filename = "paste.svg";
+#endif // ENABLE_SVG_ICONS
+ item.tooltip = GUI::L_str("Paste [Ctrl+V]");
+ item.sprite_id = 5;
+ item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_PASTE)); };
+ item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_paste(); };
+ if (!m_toolbar.add_item(item))
+ return false;
+
+ if (!m_toolbar.add_separator())
+ return false;
+
item.name = "more";
#if ENABLE_SVG_ICONS
item.icon_filename = "instance_add.svg";
#endif // ENABLE_SVG_ICONS
item.tooltip = GUI::L_str("Add instance [+]");
- item.sprite_id = 4;
+ item.sprite_id = 6;
item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_MORE)); };
item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; };
item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_increase_instances(); };
@@ -3249,7 +3274,7 @@ bool GLCanvas3D::_init_toolbar()
item.icon_filename = "instance_remove.svg";
#endif // ENABLE_SVG_ICONS
item.tooltip = GUI::L_str("Remove instance [-]");
- item.sprite_id = 5;
+ item.sprite_id = 7;
item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_FEWER)); };
item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; };
item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_decrease_instances(); };
@@ -3264,7 +3289,7 @@ bool GLCanvas3D::_init_toolbar()
item.icon_filename = "split_objects.svg";
#endif // ENABLE_SVG_ICONS
item.tooltip = GUI::L_str("Split to objects");
- item.sprite_id = 6;
+ item.sprite_id = 8;
item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_SPLIT_OBJECTS)); };
item.visibility_callback = GLToolbarItem::Default_Visibility_Callback;
item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_split_to_objects(); };
@@ -3276,7 +3301,7 @@ bool GLCanvas3D::_init_toolbar()
item.icon_filename = "split_parts.svg";
#endif // ENABLE_SVG_ICONS
item.tooltip = GUI::L_str("Split to parts");
- item.sprite_id = 7;
+ item.sprite_id = 9;
item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_SPLIT_VOLUMES)); };
item.visibility_callback = []()->bool { return wxGetApp().get_mode() != comSimple; };
item.enabled_state_callback = []()->bool { return wxGetApp().plater()->can_split_to_volumes(); };
@@ -3291,7 +3316,7 @@ bool GLCanvas3D::_init_toolbar()
item.icon_filename = "layers.svg";
#endif // ENABLE_SVG_ICONS
item.tooltip = GUI::L_str("Layers editing");
- item.sprite_id = 8;
+ item.sprite_id = 10;
item.is_toggable = true;
item.action_callback = [this]() { if (m_canvas != nullptr) wxPostEvent(m_canvas, SimpleEvent(EVT_GLTOOLBAR_LAYERSEDITING)); };
item.visibility_callback = [this]()->bool { return m_process->current_printer_technology() == ptFFF; };
diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp
index 144d02476e..842700aef8 100644
--- a/src/slic3r/GUI/GLToolbar.cpp
+++ b/src/slic3r/GUI/GLToolbar.cpp
@@ -21,6 +21,8 @@ wxDEFINE_EVENT(EVT_GLTOOLBAR_ADD, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_DELETE, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_DELETE_ALL, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_ARRANGE, SimpleEvent);
+wxDEFINE_EVENT(EVT_GLTOOLBAR_COPY, SimpleEvent);
+wxDEFINE_EVENT(EVT_GLTOOLBAR_PASTE, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_MORE, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_FEWER, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_SPLIT_OBJECTS, SimpleEvent);
diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp
index 0f8b17e04f..24314d60ff 100644
--- a/src/slic3r/GUI/GLToolbar.hpp
+++ b/src/slic3r/GUI/GLToolbar.hpp
@@ -20,6 +20,8 @@ wxDECLARE_EVENT(EVT_GLTOOLBAR_ADD, SimpleEvent);
wxDECLARE_EVENT(EVT_GLTOOLBAR_DELETE, SimpleEvent);
wxDECLARE_EVENT(EVT_GLTOOLBAR_DELETE_ALL, SimpleEvent);
wxDECLARE_EVENT(EVT_GLTOOLBAR_ARRANGE, SimpleEvent);
+wxDECLARE_EVENT(EVT_GLTOOLBAR_COPY, SimpleEvent);
+wxDECLARE_EVENT(EVT_GLTOOLBAR_PASTE, SimpleEvent);
wxDECLARE_EVENT(EVT_GLTOOLBAR_MORE, SimpleEvent);
wxDECLARE_EVENT(EVT_GLTOOLBAR_FEWER, SimpleEvent);
wxDECLARE_EVENT(EVT_GLTOOLBAR_SPLIT_OBJECTS, SimpleEvent);
diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp
index a6c0148999..d24d41a48c 100644
--- a/src/slic3r/GUI/MainFrame.cpp
+++ b/src/slic3r/GUI/MainFrame.cpp
@@ -256,16 +256,6 @@ bool MainFrame::can_delete_all() const
return (m_plater != nullptr) ? !m_plater->model().objects.empty() : false;
}
-bool MainFrame::can_copy() const
-{
- return (m_plater != nullptr) ? !m_plater->is_selection_empty() : false;
-}
-
-bool MainFrame::can_paste() const
-{
- return (m_plater != nullptr) ? !m_plater->is_selection_clipboard_empty() : false;
-}
-
void MainFrame::on_dpi_changed(const wxRect &suggested_rect)
{
// TODO
@@ -399,8 +389,8 @@ void MainFrame::init_menubar()
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_select()); }, item_select_all->GetId());
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_delete()); }, item_delete_sel->GetId());
Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_delete_all()); }, item_delete_all->GetId());
- Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_copy()); }, item_copy->GetId());
- Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_paste()); }, item_paste->GetId());
+ Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(m_plater->can_copy()); }, item_copy->GetId());
+ Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(m_plater->can_paste()); }, item_paste->GetId());
}
// Window menu
diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp
index 16116ec433..625e70b83b 100644
--- a/src/slic3r/GUI/MainFrame.hpp
+++ b/src/slic3r/GUI/MainFrame.hpp
@@ -68,8 +68,6 @@ class MainFrame : public DPIFrame
bool can_select() const;
bool can_delete() const;
bool can_delete_all() const;
- bool can_copy() const;
- bool can_paste() const;
protected:
virtual void on_dpi_changed(const wxRect &suggested_rect);
diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp
index daab7818ea..ebe7e2c758 100644
--- a/src/slic3r/GUI/Plater.cpp
+++ b/src/slic3r/GUI/Plater.cpp
@@ -1406,6 +1406,8 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE, [q](SimpleEvent&) { q->remove_selected(); });
view3D_canvas->Bind(EVT_GLTOOLBAR_DELETE_ALL, [this](SimpleEvent&) { reset(); });
view3D_canvas->Bind(EVT_GLTOOLBAR_ARRANGE, [this](SimpleEvent&) { arrange(); });
+ view3D_canvas->Bind(EVT_GLTOOLBAR_COPY, [q](SimpleEvent&) { q->copy_selection_to_clipboard(); });
+ view3D_canvas->Bind(EVT_GLTOOLBAR_PASTE, [q](SimpleEvent&) { q->paste_from_clipboard(); });
view3D_canvas->Bind(EVT_GLTOOLBAR_MORE, [q](SimpleEvent&) { q->increase_instances(); });
view3D_canvas->Bind(EVT_GLTOOLBAR_FEWER, [q](SimpleEvent&) { q->decrease_instances(); });
view3D_canvas->Bind(EVT_GLTOOLBAR_SPLIT_OBJECTS, &priv::on_action_split_objects, this);
@@ -3723,5 +3725,7 @@ bool Plater::can_split_to_objects() const { return p->can_split_to_objects(); }
bool Plater::can_split_to_volumes() const { return p->can_split_to_volumes(); }
bool Plater::can_arrange() const { return p->can_arrange(); }
bool Plater::can_layers_editing() const { return p->can_layers_editing(); }
+bool Plater::can_copy() const { return !is_selection_empty(); }
+bool Plater::can_paste() const { return !is_selection_clipboard_empty(); }
}} // namespace Slic3r::GUI
diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp
index 3d3ba8b3ec..a70656c58f 100644
--- a/src/slic3r/GUI/Plater.hpp
+++ b/src/slic3r/GUI/Plater.hpp
@@ -194,6 +194,8 @@ public:
bool can_split_to_volumes() const;
bool can_arrange() const;
bool can_layers_editing() const;
+ bool can_copy() const;
+ bool can_paste() const;
private:
struct priv;