diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 799d6d6321..8aa6352f5a 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -5161,7 +5161,8 @@ void GLCanvas3D::bind_event_handlers() m_canvas->Bind(wxEVT_SIZE, &GLCanvas3D::on_size, this); m_canvas->Bind(wxEVT_IDLE, &GLCanvas3D::on_idle, this); m_canvas->Bind(wxEVT_CHAR, &GLCanvas3D::on_char, this); - m_canvas->Bind(wxEVT_KEY_UP, &GLCanvas3D::on_key_up, this); + m_canvas->Bind(wxEVT_KEY_DOWN, &GLCanvas3D::on_key, this); + m_canvas->Bind(wxEVT_KEY_UP, &GLCanvas3D::on_key, this); m_canvas->Bind(wxEVT_MOUSEWHEEL, &GLCanvas3D::on_mouse_wheel, this); m_canvas->Bind(wxEVT_TIMER, &GLCanvas3D::on_timer, this); m_canvas->Bind(wxEVT_LEFT_DOWN, &GLCanvas3D::on_mouse, this); @@ -5187,7 +5188,8 @@ void GLCanvas3D::unbind_event_handlers() m_canvas->Unbind(wxEVT_SIZE, &GLCanvas3D::on_size, this); m_canvas->Unbind(wxEVT_IDLE, &GLCanvas3D::on_idle, this); m_canvas->Unbind(wxEVT_CHAR, &GLCanvas3D::on_char, this); - m_canvas->Unbind(wxEVT_KEY_UP, &GLCanvas3D::on_key_up, this); + m_canvas->Unbind(wxEVT_KEY_DOWN, &GLCanvas3D::on_key, this); + m_canvas->Unbind(wxEVT_KEY_UP, &GLCanvas3D::on_key, this); m_canvas->Unbind(wxEVT_MOUSEWHEEL, &GLCanvas3D::on_mouse_wheel, this); m_canvas->Unbind(wxEVT_TIMER, &GLCanvas3D::on_timer, this); m_canvas->Unbind(wxEVT_LEFT_DOWN, &GLCanvas3D::on_mouse, this); @@ -5224,6 +5226,17 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) // see include/wx/defs.h enum wxKeyCode int keyCode = evt.GetKeyCode(); int ctrlMask = wxMOD_CONTROL; + +#if ENABLE_IMGUI + auto imgui = wxGetApp().imgui(); + if (imgui->update_key_data(evt)) { + render(); + if (imgui->want_any_input()) { + return; + } + } +#endif // ENABLE_IMGUI + //#ifdef __APPLE__ // ctrlMask |= wxMOD_RAW_CONTROL; //#endif /* __APPLE__ */ @@ -5299,14 +5312,23 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) } } -void GLCanvas3D::on_key_up(wxKeyEvent& evt) +void GLCanvas3D::on_key(wxKeyEvent& evt) { - // see include/wx/defs.h enum wxKeyCode - int keyCode = evt.GetKeyCode(); +#if ENABLE_IMGUI + auto imgui = wxGetApp().imgui(); + if (imgui->update_key_data(evt)) { + render(); + } else +#endif // ENABLE_IMGUI + if (evt.GetEventType() == wxEVT_KEY_UP) { + const int keyCode = evt.GetKeyCode(); + + // shift has been just released - SLA gizmo might want to close rectangular selection. + if (m_gizmos.get_current_type() == Gizmos::SlaSupports && keyCode == WXK_SHIFT && m_gizmos.mouse_event(SLAGizmoEventType::ShiftUp)) + m_dirty = true; + } - // shift has been just released - SLA gizmo might want to close rectangular selection. - if (m_gizmos.get_current_type() == Gizmos::SlaSupports && keyCode == WXK_SHIFT && m_gizmos.mouse_event(SLAGizmoEventType::ShiftUp)) - m_dirty = true; + evt.Skip(); // Needed to have EVT_CHAR generated as well } void GLCanvas3D::on_mouse_wheel(wxMouseEvent& evt) diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 3317c6378e..3d44aa13f9 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -1075,7 +1075,7 @@ public: void on_size(wxSizeEvent& evt); void on_idle(wxIdleEvent& evt); void on_char(wxKeyEvent& evt); - void on_key_up(wxKeyEvent& evt); + void on_key(wxKeyEvent& evt); void on_mouse_wheel(wxMouseEvent& evt); void on_timer(wxTimerEvent& evt); void on_mouse(wxMouseEvent& evt); diff --git a/src/slic3r/GUI/GLCanvas3DManager.cpp b/src/slic3r/GUI/GLCanvas3DManager.cpp index 8f2e5b219c..71299f777d 100644 --- a/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -233,7 +233,7 @@ wxGLCanvas* GLCanvas3DManager::create_wxglcanvas(wxWindow *parent) attribList[4] = 0; } - return new wxGLCanvas(parent, wxID_ANY, attribList); + return new wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS); } GLCanvas3DManager::CanvasesMap::iterator GLCanvas3DManager::_get_canvas(wxGLCanvas* canvas) diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 63fa09ae2c..38d90fbfab 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -44,6 +45,7 @@ bool ImGuiWrapper::init() ImGui::CreateContext(); init_default_font(m_style_scaling); + init_input(); ImGui::GetIO().IniFilename = nullptr; @@ -109,6 +111,28 @@ bool ImGuiWrapper::update_mouse_data(wxMouseEvent& evt) return res; } +bool ImGuiWrapper::update_key_data(wxKeyEvent &evt) +{ + ImGuiIO& io = ImGui::GetIO(); + + if (evt.GetEventType() == wxEVT_CHAR) { + // Char event + io.AddInputCharacter(evt.GetUnicodeKey()); + } else { + // Key up/down event + int key = evt.GetKeyCode(); + wxCHECK_MSG(key >= 0 && key < IM_ARRAYSIZE(io.KeysDown), false, "Received invalid key code"); + + io.KeysDown[key] = evt.GetEventType() == wxEVT_KEY_DOWN; + io.KeyShift = evt.ShiftDown(); + io.KeyCtrl = evt.ControlDown(); + io.KeyAlt = evt.AltDown(); + io.KeySuper = evt.MetaDown(); + } + + return true; +} + void ImGuiWrapper::new_frame() { if (m_font_texture == 0) @@ -307,6 +331,39 @@ void ImGuiWrapper::create_fonts_texture() glBindTexture(GL_TEXTURE_2D, last_texture); } +void ImGuiWrapper::init_input() +{ + ImGuiIO& io = ImGui::GetIO(); + + // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array. + io.KeyMap[ImGuiKey_Tab] = WXK_TAB; + io.KeyMap[ImGuiKey_LeftArrow] = WXK_LEFT; + io.KeyMap[ImGuiKey_RightArrow] = WXK_RIGHT; + io.KeyMap[ImGuiKey_UpArrow] = WXK_UP; + io.KeyMap[ImGuiKey_DownArrow] = WXK_DOWN; + io.KeyMap[ImGuiKey_PageUp] = WXK_PAGEUP; + io.KeyMap[ImGuiKey_PageDown] = WXK_PAGEDOWN; + io.KeyMap[ImGuiKey_Home] = WXK_HOME; + io.KeyMap[ImGuiKey_End] = WXK_END; + io.KeyMap[ImGuiKey_Insert] = WXK_INSERT; + io.KeyMap[ImGuiKey_Delete] = WXK_DELETE; + io.KeyMap[ImGuiKey_Backspace] = WXK_BACK; + io.KeyMap[ImGuiKey_Space] = WXK_SPACE; + io.KeyMap[ImGuiKey_Enter] = WXK_RETURN; + io.KeyMap[ImGuiKey_Escape] = WXK_ESCAPE; + io.KeyMap[ImGuiKey_A] = 'A'; + io.KeyMap[ImGuiKey_C] = 'C'; + io.KeyMap[ImGuiKey_V] = 'V'; + io.KeyMap[ImGuiKey_X] = 'X'; + io.KeyMap[ImGuiKey_Y] = 'Y'; + io.KeyMap[ImGuiKey_Z] = 'Z'; + + // Setup clipboard interaction callbacks + io.SetClipboardTextFn = clipboard_set; + io.GetClipboardTextFn = clipboard_get; + io.ClipboardUserData = this; +} + void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) { // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) @@ -420,6 +477,37 @@ void ImGuiWrapper::destroy_fonts_texture() } } +const char* ImGuiWrapper::clipboard_get(void* user_data) +{ + ImGuiWrapper *self = reinterpret_cast(user_data); + + const char* res = ""; + + if (wxTheClipboard->Open()) { + if (wxTheClipboard->IsSupported(wxDF_TEXT)) { + wxTextDataObject data; + wxTheClipboard->GetData(data); + + if (data.GetTextLength() > 0) { + self->clipboard_text = into_u8(data.GetText()); + res = self->clipboard_text.c_str(); + } + } + + wxTheClipboard->Close(); + } + + return res; +} + +void ImGuiWrapper::clipboard_set(void* /* user_data */, const char* text) +{ + if (wxTheClipboard->Open()) { + wxTheClipboard->SetData(new wxTextDataObject(wxString::FromUTF8(text))); // object owned by the clipboard + wxTheClipboard->Close(); + } +} + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp index a4f5a89762..b0b5cc858f 100644 --- a/src/slic3r/GUI/ImGuiWrapper.hpp +++ b/src/slic3r/GUI/ImGuiWrapper.hpp @@ -10,6 +10,7 @@ class wxString; class wxMouseEvent; +class wxKeyEvent; namespace Slic3r { @@ -37,6 +38,7 @@ public: void set_display_size(float w, float h); void set_style_scaling(float scaling); bool update_mouse_data(wxMouseEvent &evt); + bool update_key_data(wxKeyEvent &evt); void new_frame(); void render(); @@ -65,12 +67,18 @@ public: bool want_any_input() const; private: + std::string clipboard_text; + void init_default_font(float scaling); void create_device_objects(); void create_fonts_texture(); + void init_input(); void render_draw_data(ImDrawData *draw_data); void destroy_device_objects(); void destroy_fonts_texture(); + + static const char* clipboard_get(void* user_data); + static void clipboard_set(void* user_data, const char* text); };