diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 04f860dc8..90adfbf62 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2804,8 +2804,7 @@ void GLCanvas3D::load_preview(const std::vector& str_tool_colors, c void GLCanvas3D::bind_event_handlers() { - if (m_canvas != nullptr) - { + if (m_canvas != nullptr) { 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); @@ -2827,13 +2826,14 @@ void GLCanvas3D::bind_event_handlers() m_canvas->Bind(wxEVT_RIGHT_DCLICK, &GLCanvas3D::on_mouse, this); m_canvas->Bind(wxEVT_PAINT, &GLCanvas3D::on_paint, this); m_canvas->Bind(wxEVT_SET_FOCUS, &GLCanvas3D::on_set_focus, this); + + m_event_handlers_bound = true; } } void GLCanvas3D::unbind_event_handlers() { - if (m_canvas != nullptr) - { + if (m_canvas != nullptr && m_event_handlers_bound) { 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); @@ -2855,6 +2855,8 @@ void GLCanvas3D::unbind_event_handlers() m_canvas->Unbind(wxEVT_RIGHT_DCLICK, &GLCanvas3D::on_mouse, this); m_canvas->Unbind(wxEVT_PAINT, &GLCanvas3D::on_paint, this); m_canvas->Unbind(wxEVT_SET_FOCUS, &GLCanvas3D::on_set_focus, this); + + m_event_handlers_bound = false; } } @@ -2880,8 +2882,7 @@ void GLCanvas3D::on_idle(wxIdleEvent& evt) _refresh_if_shown_on_screen(); - if (m_extra_frame_requested || mouse3d_controller_applied) - { + if (m_extra_frame_requested || mouse3d_controller_applied) { m_dirty = true; m_extra_frame_requested = false; evt.RequestMore(); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index a76d9f4a0..d0a130e89 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -474,6 +474,7 @@ private: // when true renders an extra frame by not resetting m_dirty to false // see request_extra_frame() bool m_extra_frame_requested; + bool m_event_handlers_bound{ false }; mutable GLVolumeCollection m_volumes; #if ENABLE_GCODE_VIEWER diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 441fef768..56068c20e 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -1180,9 +1180,9 @@ void fatal_error(wxWindow* parent) // Called after the Preferences dialog is closed and the program settings are saved. // Update the UI based on the current preferences. -void GUI_App::update_ui_from_settings() +void GUI_App::update_ui_from_settings(bool apply_free_camera_correction) { - mainframe->update_ui_from_settings(); + mainframe->update_ui_from_settings(apply_free_camera_correction); } void GUI_App::persist_window_geometry(wxTopLevelWindow *window, bool default_maximized) diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index fa2872a53..e76953a03 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -230,7 +230,7 @@ public: static bool catch_error(std::function cb, const std::string& err); void persist_window_geometry(wxTopLevelWindow *window, bool default_maximized = false); - void update_ui_from_settings(); + void update_ui_from_settings(bool apply_free_camera_correction = true); bool switch_language(); bool load_language(wxString language, bool initial); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 3e2913bf8..119eb2ed5 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -59,7 +59,6 @@ bool View3D::init(wxWindow* parent, Model* model, DynamicPrintConfig* config, Ba m_canvas = new GLCanvas3D(m_canvas_widget); m_canvas->set_context(wxGetApp().init_glcontext(*m_canvas_widget)); - m_canvas->bind_event_handlers(); m_canvas->allow_multisample(OpenGLManager::can_multisample()); // XXX: If have OpenGL @@ -250,7 +249,6 @@ bool Preview::init(wxWindow* parent, Model* model) m_canvas = new GLCanvas3D(m_canvas_widget); m_canvas->set_context(wxGetApp().init_glcontext(*m_canvas_widget)); - m_canvas->bind_event_handlers(); m_canvas->allow_multisample(OpenGLManager::can_multisample()); m_canvas->set_config(m_config); m_canvas->set_model(model); diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index ba1fd56c7..2e334c559 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -1933,7 +1933,7 @@ void MainFrame::add_to_recent_projects(const wxString& filename) // // Called after the Preferences dialog is closed and the program settings are saved. // Update the UI based on the current preferences. -void MainFrame::update_ui_from_settings() +void MainFrame::update_ui_from_settings(bool apply_free_camera_correction) { // const bool bp_on = wxGetApp().app_config->get("background_processing") == "1"; // m_menu_item_reslice_now->Enable(!bp_on); @@ -1942,7 +1942,7 @@ void MainFrame::update_ui_from_settings() // m_plater->sidebar().Layout(); if (m_plater) - m_plater->update_ui_from_settings(); + m_plater->update_ui_from_settings(apply_free_camera_correction); for (auto tab: wxGetApp().tabs_list) tab->update_ui_from_settings(); } diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index 8172b0d33..5275ca527 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -167,7 +167,7 @@ public: #endif // ENABLE_GCODE_VIEWER void update_menubar(); - void update_ui_from_settings(); + void update_ui_from_settings(bool apply_free_camera_correction = true); bool is_loaded() const { return m_loaded; } bool is_last_input_file() const { return !m_qs_last_input_file.IsEmpty(); } bool is_dlg_layout() const { return m_layout == ESettingsLayout::Dlg; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 7f89dc9e9..b3cd1ef00 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1620,7 +1620,7 @@ struct Plater::priv #endif // ENABLE_GCODE_VIEWER void reset_all_gizmos(); - void update_ui_from_settings(); + void update_ui_from_settings(bool apply_free_camera_correction = true); void update_main_toolbar_tooltips(); std::shared_ptr statusbar(); std::string get_config(const std::string &key) const; @@ -2122,7 +2122,7 @@ void Plater::priv::select_view_3D(const std::string& name) set_current_panel(preview); #if ENABLE_GCODE_VIEWER - wxGetApp().update_ui_from_settings(); + wxGetApp().update_ui_from_settings(false); #endif // ENABLE_GCODE_VIEWER } @@ -2155,10 +2155,10 @@ void Plater::priv::reset_all_gizmos() // Called after the Preferences dialog is closed and the program settings are saved. // Update the UI based on the current preferences. -void Plater::priv::update_ui_from_settings() +void Plater::priv::update_ui_from_settings(bool apply_free_camera_correction) { camera.set_type(wxGetApp().app_config->get("use_perspective_camera")); - if (wxGetApp().app_config->get("use_free_camera") != "1") + if (apply_free_camera_correction && wxGetApp().app_config->get("use_free_camera") != "1") camera.recover_from_free_camera(); view3D->get_canvas3d()->update_ui_from_settings(); @@ -3296,16 +3296,14 @@ void Plater::priv::set_current_panel(wxPanel* panel) if (current_panel == panel) return; + wxPanel* old_panel = current_panel; current_panel = panel; // to reduce flickering when changing view, first set as visible the new current panel - for (wxPanel* p : panels) - { - if (p == current_panel) - { + for (wxPanel* p : panels) { + if (p == current_panel) { #ifdef __WXMAC__ // On Mac we need also to force a render to avoid flickering when changing view - if (force_render) - { + if (force_render) { if (p == view3D) dynamic_cast(p)->get_canvas3d()->render(); else if (p == preview) @@ -3316,21 +3314,22 @@ void Plater::priv::set_current_panel(wxPanel* panel) } } // then set to invisible the other - for (wxPanel* p : panels) - { + for (wxPanel* p : panels) { if (p != current_panel) p->Hide(); } panel_sizer->Layout(); - if (current_panel == view3D) - { - if (view3D->is_reload_delayed()) - { + if (current_panel == view3D) { + if (old_panel == preview) + preview->get_canvas3d()->unbind_event_handlers(); + + view3D->get_canvas3d()->bind_event_handlers(); + + if (view3D->is_reload_delayed()) { // Delayed loading of the 3D scene. - if (this->printer_technology == ptSLA) - { + if (this->printer_technology == ptSLA) { // Update the SLAPrint from the current Model, so that the reload_scene() // pulls the correct data. this->update_restart_background_process(true, false); @@ -3344,8 +3343,12 @@ void Plater::priv::set_current_panel(wxPanel* panel) if(notification_manager != nullptr) notification_manager->set_in_preview(false); } - else if (current_panel == preview) - { + else if (current_panel == preview) { + if (old_panel == view3D) + view3D->get_canvas3d()->unbind_event_handlers(); + + preview->get_canvas3d()->bind_event_handlers(); + // see: Plater::priv::object_list_changed() // FIXME: it may be better to have a single function making this check and let it be called wherever needed bool export_in_progress = this->background_process.is_export_scheduled(); @@ -4746,7 +4749,7 @@ void Plater::update() { p->update(); } void Plater::stop_jobs() { p->m_ui_jobs.stop_all(); } -void Plater::update_ui_from_settings() { p->update_ui_from_settings(); } +void Plater::update_ui_from_settings(bool apply_free_camera_correction) { p->update_ui_from_settings(apply_free_camera_correction); } void Plater::select_view(const std::string& direction) { p->select_view(direction); } diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index b68b211a9..e7b7c8442 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -169,7 +169,7 @@ public: // Called after the Preferences dialog is closed and the program settings are saved. // Update the UI based on the current preferences. - void update_ui_from_settings(); + void update_ui_from_settings(bool apply_free_camera_correction = true); void select_all(); void deselect_all();