diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 0e474670c..f52403321 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3995,6 +3995,7 @@ wxDEFINE_EVENT(EVT_GLCANVAS_VIEWPORT_CHANGED, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, Vec2dEvent); wxDEFINE_EVENT(EVT_GLCANVAS_REMOVE_OBJECT, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_ARRANGE, SimpleEvent); +wxDEFINE_EVENT(EVT_GLCANVAS_SELECT_ALL, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_QUESTION_MARK, SimpleEvent); wxDEFINE_EVENT(EVT_GLCANVAS_INCREASE_INSTANCES, Event); wxDEFINE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent); @@ -5100,71 +5101,60 @@ void GLCanvas3D::on_idle(wxIdleEvent& evt) void GLCanvas3D::on_char(wxKeyEvent& evt) { - if (evt.HasModifiers()) + // see include/wx/defs.h enum wxKeyCode + int keyCode = evt.GetKeyCode(); + if (evt.GetModifiers() == wxMOD_CONTROL) { + switch (keyCode) { + case WXK_CONTROL_A: post_event(SimpleEvent(EVT_GLCANVAS_SELECT_ALL)); break; +#ifdef __APPLE__ + case WXK_BACK: // the low cost Apple solutions are not equipped with a Delete key, use Backspace instead. +#endif /* __APPLE__ */ + case WXK_DELETE: post_event(SimpleEvent(EVT_GLTOOLBAR_DELETE_ALL)); break; + default: evt.Skip(); + } + } else if (evt.HasModifiers()) { evt.Skip(); - else - { - int keyCode = evt.GetKeyCode(); - switch (keyCode - 48) + } else { + switch (keyCode) { - // numerical input - case 0: { select_view("iso"); break; } - case 1: { select_view("top"); break; } - case 2: { select_view("bottom"); break; } - case 3: { select_view("front"); break; } - case 4: { select_view("rear"); break; } - case 5: { select_view("left"); break; } - case 6: { select_view("right"); break; } + // key ESC + case WXK_ESCAPE: { m_gizmos.reset_all_states(); m_dirty = true; break; } +#ifdef __APPLE__ + case WXK_BACK: // the low cost Apple solutions are not equipped with a Delete key, use Backspace instead. +#endif /* __APPLE__ */ + case WXK_DELETE: post_event(SimpleEvent(EVT_GLTOOLBAR_DELETE)); break; + case '0': { select_view("iso"); break; } + case '1': { select_view("top"); break; } + case '2': { select_view("bottom"); break; } + case '3': { select_view("front"); break; } + case '4': { select_view("rear"); break; } + case '5': { select_view("left"); break; } + case '6': { select_view("right"); break; } + case '+': { post_event(Event(EVT_GLCANVAS_INCREASE_INSTANCES, +1)); break; } + case '-': { post_event(Event(EVT_GLCANVAS_INCREASE_INSTANCES, -1)); break; } + case '?': { post_event(SimpleEvent(EVT_GLCANVAS_QUESTION_MARK)); break; } + case 'A': + case 'a': { post_event(SimpleEvent(EVT_GLCANVAS_ARRANGE)); break; } + case 'B': + case 'b': { zoom_to_bed(); break; } + case 'I': + case 'i': { set_camera_zoom(1.0f); break; } + case 'O': + case 'o': { set_camera_zoom(-1.0f); break; } + case 'Z': + case 'z': { m_selection.is_empty() ? zoom_to_volumes() : zoom_to_selection(); break; } default: + { + if (m_gizmos.handle_shortcut(keyCode, m_selection)) { - // text input - switch (keyCode) - { - // key ESC - case 27: { m_gizmos.reset_all_states(); m_dirty = true; break; } - // key + - case 43: { post_event(Event(EVT_GLCANVAS_INCREASE_INSTANCES, +1)); break; } - // key - - case 45: { post_event(Event(EVT_GLCANVAS_INCREASE_INSTANCES, -1)); break; } - // key ? - case 63: { post_event(SimpleEvent(EVT_GLCANVAS_QUESTION_MARK)); break; } - // key A/a - case 65: - case 97: { post_event(SimpleEvent(EVT_GLCANVAS_ARRANGE)); break; } - // key B/b - case 66: - case 98: { zoom_to_bed(); break; } - // key I/i - case 73: - case 105: { set_camera_zoom(1.0f); break; } - // key O/o - case 79: - case 111: { set_camera_zoom(-1.0f); break; } - // key Z/z - case 90: - case 122: - { - if (m_selection.is_empty()) - zoom_to_volumes(); - else - zoom_to_selection(); - - break; - } - default: - { - if (m_gizmos.handle_shortcut(keyCode, m_selection)) - { - _update_gizmos_data(); - m_dirty = true; - } - else - evt.Skip(); - - break; - } - } + _update_gizmos_data(); + m_dirty = true; } + else + evt.Skip(); + + break; + } } } } diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index ec980dd92..21ae80606 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -121,6 +121,7 @@ wxDECLARE_EVENT(EVT_GLCANVAS_VIEWPORT_CHANGED, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, Vec2dEvent); wxDECLARE_EVENT(EVT_GLCANVAS_REMOVE_OBJECT, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_ARRANGE, SimpleEvent); +wxDECLARE_EVENT(EVT_GLCANVAS_SELECT_ALL, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_QUESTION_MARK, SimpleEvent); wxDECLARE_EVENT(EVT_GLCANVAS_INCREASE_INSTANCES, Event); // data: +1 => increase, -1 => decrease wxDECLARE_EVENT(EVT_GLCANVAS_INSTANCE_MOVED, SimpleEvent); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 947dd59bd..4ff01c0d3 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -324,12 +324,14 @@ void MainFrame::init_menubar() if (m_plater != nullptr) { editMenu = new wxMenu(); - wxMenuItem* item_select_all = append_menu_item(editMenu, wxID_ANY, _(L("&Select all")) + "\tCtrl+A", _(L("Selects all objects")), + // \xA0 is a non-breaking space. It is entered here to spoil the automatic accelerators, + // as the simple numeric accelerators spoil all numeric data entry. + wxMenuItem* item_select_all = append_menu_item(editMenu, wxID_ANY, _(L("&Select all")) + "\t\xA0" + "Ctrl+\xA0" + "A", _(L("Selects all objects")), [this](wxCommandEvent&) { m_plater->select_all(); }, ""); editMenu->AppendSeparator(); - wxMenuItem* item_delete_sel = append_menu_item(editMenu, wxID_ANY, _(L("&Delete selected")) + "\tDel", _(L("Deletes the current selection")), + wxMenuItem* item_delete_sel = append_menu_item(editMenu, wxID_ANY, _(L("&Delete selected")) + "\t\xA0" + "Del", _(L("Deletes the current selection")), [this](wxCommandEvent&) { m_plater->remove_selected(); }, ""); - wxMenuItem* item_delete_all = append_menu_item(editMenu, wxID_ANY, _(L("Delete &all")) + "\tCtrl+Del", _(L("Deletes all objects")), + wxMenuItem* item_delete_all = append_menu_item(editMenu, wxID_ANY, _(L("Delete &all")) + "\t\xA0" + "Ctrl+\xA0" + "Del", _(L("Deletes all objects")), [this](wxCommandEvent&) { m_plater->reset(); }, ""); Bind(wxEVT_UPDATE_UI, [this](wxUpdateUIEvent& evt) { evt.Enable(can_select()); }, item_select_all->GetId()); @@ -388,7 +390,7 @@ void MainFrame::init_menubar() wxMenu* viewMenu = nullptr; if (m_plater) { viewMenu = new wxMenu(); - // \xA0 is a non-breaing space. It is entered here to spoil the automatic accelerators, + // \xA0 is a non-breaking space. It is entered here to spoil the automatic accelerators, // as the simple numeric accelerators spoil all numeric data entry. // The camera control accelerators are captured by GLCanvas3D::on_char(). wxMenuItem* item_iso = append_menu_item(viewMenu, wxID_ANY, _(L("&Iso")) + "\t\xA0" + "0", _(L("Iso View")), [this](wxCommandEvent&) { select_view("iso"); }); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index ef8e84ca8..59148c0a3 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1171,6 +1171,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) view3D_canvas->Bind(EVT_GLCANVAS_RIGHT_CLICK, &priv::on_right_click, this); view3D_canvas->Bind(EVT_GLCANVAS_REMOVE_OBJECT, [q](SimpleEvent&) { q->remove_selected(); }); view3D_canvas->Bind(EVT_GLCANVAS_ARRANGE, [this](SimpleEvent&) { arrange(); }); + view3D_canvas->Bind(EVT_GLCANVAS_SELECT_ALL, [this](SimpleEvent&) { this->q->select_all(); }); view3D_canvas->Bind(EVT_GLCANVAS_QUESTION_MARK, [this](SimpleEvent&) { wxGetApp().keyboard_shortcuts(); }); view3D_canvas->Bind(EVT_GLCANVAS_INCREASE_INSTANCES, [this](Event &evt) { if (evt.data == 1) this->q->increase_instances(); else if (this->can_decrease_instances()) this->q->decrease_instances(); }); @@ -1736,6 +1737,8 @@ void Plater::priv::arrange() // Guard the arrange process arranging.store(true); + wxBusyCursor wait; + // Disable the arrange button (to prevent reentrancies, we will call wxYied) view3D->enable_toolbar_item("arrange", can_arrange());