diff --git a/resources/icons/PrusaSlicer-gcodeviewer_128px.png b/resources/icons/PrusaSlicer-gcodeviewer_128px.png new file mode 100644 index 000000000..d8e3e438b Binary files /dev/null and b/resources/icons/PrusaSlicer-gcodeviewer_128px.png differ diff --git a/resources/icons/PrusaSlicerGCodeViewer_128px.png b/resources/icons/PrusaSlicerGCodeViewer_128px.png deleted file mode 100644 index 0bf85abbd..000000000 Binary files a/resources/icons/PrusaSlicerGCodeViewer_128px.png and /dev/null differ diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index 2962f0cdf..ea56124e6 100644 --- a/src/PrusaSlicer.cpp +++ b/src/PrusaSlicer.cpp @@ -534,7 +534,11 @@ int CLI::run(int argc, char **argv) if (start_gui) { #ifdef SLIC3R_GUI // #ifdef USE_WX +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + GUI::GUI_App* gui = new GUI::GUI_App(start_as_gcodeviewer ? GUI::GUI_App::EAppMode::GCodeViewer : GUI::GUI_App::EAppMode::Editor); +#else GUI::GUI_App *gui = new GUI::GUI_App(); +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION bool gui_single_instance_setting = gui->app_config->get("single_instance") == "1"; if (Slic3r::instance_check(argc, argv, gui_single_instance_setting)) { diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index 8b41bd271..db3bd78dd 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -179,6 +179,11 @@ std::string AppConfig::load() void AppConfig::save() { +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (!m_save_enabled) + return; +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + // The config is first written to a file with a PID suffix and then moved // to avoid race conditions with multiple instances of Slic3r const auto path = config_path(); diff --git a/src/libslic3r/AppConfig.hpp b/src/libslic3r/AppConfig.hpp index ffd1b9fdf..3f4ce2008 100644 --- a/src/libslic3r/AppConfig.hpp +++ b/src/libslic3r/AppConfig.hpp @@ -18,6 +18,9 @@ public: AppConfig() : m_dirty(false), m_orig_version(Semver::invalid()), +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + m_save_enabled(true), +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION m_legacy_datadir(false) { this->reset(); @@ -157,6 +160,10 @@ public: bool get_mouse_device_swap_yz(const std::string& name, bool& swap) const { return get_3dmouse_device_numeric_value(name, "swap_yz", swap); } +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + void enable_save(bool enable) { m_save_enabled = enable; } +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + static const std::string SECTION_FILAMENTS; static const std::string SECTION_MATERIALS; @@ -183,6 +190,10 @@ private: bool m_dirty; // Original version found in the ini file before it was overwritten Semver m_orig_version; +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + // Whether or not calls to save() should take effect + bool m_save_enabled; +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION // Whether the existing version is before system profiles & configuration updating bool m_legacy_datadir; }; diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index a0484b259..2dbad472f 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -59,5 +59,6 @@ #define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_DATA_CHECKING (0 && ENABLE_GCODE_VIEWER) #define ENABLE_GCODE_VIEWER_TASKBAR_ICON (0 && ENABLE_GCODE_VIEWER) +#define ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION (1 && ENABLE_GCODE_VIEWER) #endif // _prusaslicer_technologies_h_ diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index bc424466b..2b9bf8ca4 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -339,7 +339,11 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& reset(); load_toolpaths(gcode_result); +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (wxGetApp().is_editor()) +#else if (wxGetApp().mainframe->get_mode() != MainFrame::EMode::GCodeViewer) +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION load_shells(print, initialized); else { Pointfs bed_shape; @@ -875,7 +879,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result) for (size_t i = 0; i < m_vertices_count; ++i) { const GCodeProcessor::MoveVertex& move = gcode_result.moves[i]; +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (wxGetApp().is_gcode_viewer()) +#else if (wxGetApp().mainframe->get_mode() == MainFrame::EMode::GCodeViewer) +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION // for the gcode viewer we need all moves to correctly size the printbed m_paths_bounding_box.merge(move.position.cast()); else { diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index e7f0f094d..2f9f9464c 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2732,7 +2732,11 @@ static void load_gcode_retractions(const GCodePreviewData::Retraction& retractio void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result) { m_gcode_viewer.load(gcode_result, *this->fff_print(), m_initialized); +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (wxGetApp().is_editor()) +#else if (wxGetApp().mainframe->get_mode() != MainFrame::EMode::GCodeViewer) +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION _show_warning_texture_if_needed(WarningTexture::ToolpathOutside); } @@ -4302,7 +4306,11 @@ void GLCanvas3D::update_ui_from_settings() #endif // ENABLE_RETINA_GL #if ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (wxGetApp().is_editor()) +#else if (wxGetApp().mainframe != nullptr && wxGetApp().mainframe->get_mode() != MainFrame::EMode::GCodeViewer) +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION wxGetApp().plater()->get_collapse_toolbar().set_enabled(wxGetApp().app_config->get("show_collapse_button") == "1"); #else bool enable_collapse = wxGetApp().app_config->get("show_collapse_button") == "1"; @@ -5405,7 +5413,11 @@ void GLCanvas3D::_render_background() const { #if ENABLE_GCODE_VIEWER bool use_error_color = false; +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (wxGetApp().is_editor()) { +#else if (wxGetApp().mainframe->get_mode() != MainFrame::EMode::GCodeViewer) { +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION use_error_color = m_dynamic_background_enabled; if (!m_volumes.empty()) use_error_color &= _is_any_volume_outside(); @@ -7134,7 +7146,11 @@ void GLCanvas3D::_show_warning_texture_if_needed(WarningTexture::Warning warning if (!m_volumes.empty()) show = _is_any_volume_outside(); else { +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (wxGetApp().is_editor()) { +#else if (wxGetApp().mainframe->get_mode() != MainFrame::EMode::GCodeViewer) { +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION BoundingBoxf3 test_volume = (m_config != nullptr) ? print_volume(*m_config) : BoundingBoxf3(); const BoundingBoxf3& paths_volume = m_gcode_viewer.get_paths_bounding_box(); if (test_volume.radius() > 0.0 && paths_volume.radius() > 0.0) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 08219ed86..65aa026b5 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -1,3 +1,4 @@ +#include "libslic3r/Technologies.hpp" #include "GUI_App.hpp" #include "GUI_ObjectList.hpp" #include "GUI_ObjectManipulation.hpp" @@ -309,8 +310,15 @@ static void generic_exception_handle() IMPLEMENT_APP(GUI_App) +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION +GUI_App::GUI_App(EAppMode mode) +#else GUI_App::GUI_App() +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION : wxApp() +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + , m_app_mode(mode) +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION , m_em_unit(10) , m_imgui(new ImGuiWrapper()) , m_wizard(nullptr) @@ -366,6 +374,12 @@ void GUI_App::init_app_config() if (!app_config) app_config = new AppConfig(); +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (is_gcode_viewer()) + // disable config save to avoid to mess it up for the editor + app_config->enable_save(false); +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + // load settings app_conf_exists = app_config->exists(); if (app_conf_exists) { @@ -402,18 +416,18 @@ bool GUI_App::on_init_inner() wxCHECK_MSG(wxDirExists(resources_dir), false, wxString::Format("Resources path does not exist or is not a directory: %s", resources_dir)); - // Enable this to get the default Win32 COMCTRL32 behavior of static boxes. + // Enable this to get the default Win32 COMCTRL32 behavior of static boxes. // wxSystemOptions::SetOption("msw.staticbox.optimized-paint", 0); // Enable this to disable Windows Vista themes for all wxNotebooks. The themes seem to lead to terrible // performance when working on high resolution multi-display setups. // wxSystemOptions::SetOption("msw.notebook.themed-background", 0); // Slic3r::debugf "wxWidgets version %s, Wx version %s\n", wxVERSION_STRING, wxVERSION; - + std::string msg = Http::tls_global_init(); std::string ssl_cert_store = app_config->get("tls_accepted_cert_store_location"); bool ssl_accept = app_config->get("tls_cert_store_accepted") == "yes" && ssl_cert_store == Http::tls_system_cert_store(); - + if (!msg.empty() && !ssl_accept) { wxRichMessageDialog dlg(nullptr, @@ -423,38 +437,44 @@ bool GUI_App::on_init_inner() if (dlg.ShowModal() != wxID_YES) return false; app_config->set("tls_cert_store_accepted", - dlg.IsCheckBoxChecked() ? "yes" : "no"); + dlg.IsCheckBoxChecked() ? "yes" : "no"); app_config->set("tls_accepted_cert_store_location", - dlg.IsCheckBoxChecked() ? Http::tls_system_cert_store() : ""); + dlg.IsCheckBoxChecked() ? Http::tls_system_cert_store() : ""); } - + app_config->set("version", SLIC3R_VERSION); app_config->save(); wxBitmap bitmap = create_scaled_bitmap("prusa_slicer_logo", nullptr, 400); SplashScreen* scrn = new SplashScreen(bitmap, wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_TIMEOUT, 4000, nullptr); scrn->SetText(_L("Loading configuration...")); - + preset_bundle = new PresetBundle(); - + // just checking for existence of Slic3r::data_dir is not enough : it may be an empty directory // supplied as argument to --datadir; in that case we should still run the wizard preset_bundle->setup_directories(); +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (is_editor()) { +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION #ifdef __WXMSW__ - associate_3mf_files(); + associate_3mf_files(); #endif // __WXMSW__ - preset_updater = new PresetUpdater(); - Bind(EVT_SLIC3R_VERSION_ONLINE, [this](const wxCommandEvent &evt) { - app_config->set("version_online", into_u8(evt.GetString())); - app_config->save(); - if(this->plater_ != nullptr) { - if (*Semver::parse(SLIC3R_VERSION) < * Semver::parse(into_u8(evt.GetString()))) { - this->plater_->get_notification_manager()->push_notification(NotificationType::NewAppAviable, *(this->plater_->get_current_canvas3D())); - } - } - }); + preset_updater = new PresetUpdater(); + Bind(EVT_SLIC3R_VERSION_ONLINE, [this](const wxCommandEvent& evt) { + app_config->set("version_online", into_u8(evt.GetString())); + app_config->save(); + if (this->plater_ != nullptr) { + if (*Semver::parse(SLIC3R_VERSION) < *Semver::parse(into_u8(evt.GetString()))) { + this->plater_->get_notification_manager()->push_notification(NotificationType::NewAppAviable, *(this->plater_->get_current_canvas3D())); + } + } + }); +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + } +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION // initialize label colors and fonts init_label_colours(); @@ -484,7 +504,11 @@ bool GUI_App::on_init_inner() // application frame if (wxImage::FindHandler(wxBITMAP_TYPE_PNG) == nullptr) wxImage::AddHandler(new wxPNGHandler()); - scrn->SetText(_L("Creating settings tabs...")); + +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (is_editor()) +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + scrn->SetText(_L("Creating settings tabs...")); mainframe = new MainFrame(); // hide settings tabs after first Layout @@ -519,13 +543,20 @@ bool GUI_App::on_init_inner() static bool once = true; if (once) { once = false; - check_updates(false); +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (preset_updater != nullptr) { +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + check_updates(false); + + CallAfter([this] { + config_wizard_startup(); + preset_updater->slic3r_update_notify(); + preset_updater->sync(preset_bundle); + }); +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + } +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION - CallAfter([this] { - config_wizard_startup(); - preset_updater->slic3r_update_notify(); - preset_updater->sync(preset_bundle); - }); #ifdef _WIN32 //sets window property to mainframe so other instances can indentify it OtherInstanceMessageHandler::init_windows_properties(mainframe, m_instance_hash_int); @@ -533,8 +564,16 @@ bool GUI_App::on_init_inner() } }); +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (is_gcode_viewer()) { + mainframe->update_layout(); + if (plater_ != nullptr) + // ensure the selected technology is ptFFF + plater_->set_printer_technology(ptFFF); + } +#else load_current_presets(); - +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION mainframe->Show(true); /* Temporary workaround for the correct behavior of the Scrolled sidebar panel: diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 34114c03c..d63825de3 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -94,8 +94,22 @@ static wxString dots("…", wxConvUTF8); class GUI_App : public wxApp { +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION +public: + enum class EAppMode : unsigned char + { + Editor, + GCodeViewer + }; + +private: +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + bool m_initialized { false }; bool app_conf_exists{ false }; +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + EAppMode m_app_mode{ EAppMode::Editor }; +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION wxColour m_color_label_modified; wxColour m_color_label_sys; @@ -125,13 +139,24 @@ class GUI_App : public wxApp std::unique_ptr m_single_instance_checker; std::string m_instance_hash_string; size_t m_instance_hash_int; + public: bool OnInit() override; bool initialized() const { return m_initialized; } +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + explicit GUI_App(EAppMode mode = EAppMode::Editor); +#else GUI_App(); +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION ~GUI_App() override; +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + EAppMode get_app_mode() const { return m_app_mode; } + bool is_editor() const { return m_app_mode == EAppMode::Editor; } + bool is_gcode_viewer() const { return m_app_mode == EAppMode::GCodeViewer; } +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + static std::string get_gl_info(bool format_as_html, bool extensions); wxGLContext* init_glcontext(wxGLCanvas& canvas); bool init_opengl(); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 5dcd26a87..530b3358e 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -1234,7 +1234,11 @@ void Preview::load_print_as_fff(bool keep_z_range) } #if ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (wxGetApp().is_editor() && !has_layers) +#else if (wxGetApp().mainframe->get_mode() != MainFrame::EMode::GCodeViewer && !has_layers) +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION #else if (! has_layers) #endif // ENABLE_GCODE_VIEWER diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index d9ce44bd6..629766306 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -194,6 +194,9 @@ Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, #if ENABLE_GCODE_VIEWER void update_bottom_toolbar(); void update_moves_slider(); +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + void hide_layers_slider(); +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION #endif // ENABLE_GCODE_VIEWER private: @@ -203,7 +206,9 @@ private: void unbind_event_handlers(); #if ENABLE_GCODE_VIEWER +#if !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION void hide_layers_slider(); +#endif // !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION #else void show_hide_ui_elements(const std::string& what); diff --git a/src/slic3r/GUI/KBShortcutsDialog.cpp b/src/slic3r/GUI/KBShortcutsDialog.cpp index 1eceea22e..632bc48ed 100644 --- a/src/slic3r/GUI/KBShortcutsDialog.cpp +++ b/src/slic3r/GUI/KBShortcutsDialog.cpp @@ -95,9 +95,15 @@ void KBShortcutsDialog::fill_shortcuts() const std::string& alt = GUI::shortkey_alt_prefix(); #if ENABLE_GCODE_VIEWER +#if !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION bool is_gcode_viewer = wxGetApp().mainframe->get_mode() == MainFrame::EMode::GCodeViewer; +#endif // !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (wxGetApp().is_editor()) { +#else if (!is_gcode_viewer) { +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION #endif // ENABLE_GCODE_VIEWER Shortcuts commands_shortcuts = { // File diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index f6fd939e2..853d9a6d7 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -92,7 +92,6 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S } #endif // ENABLE_GCODE_VIEWER_TASKBAR_ICON -// SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); // Load the icon either from the exe, or from the ico file. #if _WIN32 { @@ -102,7 +101,24 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S SetIcon(wxIcon(szExeFileName, wxBITMAP_TYPE_ICO)); } #else - SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + switch (wxGetApp().get_mode()) + { + default: + case GUI_App::EMode::Editor: + { +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + break; + } + case GUI_App::EMode::GCodeViewer: + { + SetIcon(wxIcon(Slic3r::var("PrusaSlicer-gcodeviewer_128px.png"), wxBITMAP_TYPE_PNG)); + break; + } + } +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION #endif // _WIN32 // initialize status bar @@ -116,8 +132,15 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S // initialize tabpanel and menubar init_tabpanel(); #if ENABLE_GCODE_VIEWER - init_editor_menubar(); - init_gcodeviewer_menubar(); +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (wxGetApp().is_gcode_viewer()) + init_menubar_as_gcodeviewer(); + else + init_menubar_as_editor(); +#else + init_menubar_as_editor(); + init_menubar_as_gcodeviewer(); +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION #if _WIN32 // This is needed on Windows to fake the CTRL+# of the window menu when using the numpad @@ -148,7 +171,10 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S sizer->Add(m_main_sizer, 1, wxEXPAND); SetSizer(sizer); // initialize layout from config - update_layout(); +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (wxGetApp().is_editor()) +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + update_layout(); sizer->SetSizeHints(this); Fit(); @@ -300,10 +326,17 @@ void MainFrame::update_layout() }; #if ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + ESettingsLayout layout = wxGetApp().is_gcode_viewer() ? ESettingsLayout::GCodeViewer : + (wxGetApp().app_config->get("old_settings_layout_mode") == "1" ? ESettingsLayout::Old : + wxGetApp().app_config->get("new_settings_layout_mode") == "1" ? ESettingsLayout::New : + wxGetApp().app_config->get("dlg_settings_layout_mode") == "1" ? ESettingsLayout::Dlg : ESettingsLayout::Old); +#else ESettingsLayout layout = (m_mode == EMode::GCodeViewer) ? ESettingsLayout::GCodeViewer : (wxGetApp().app_config->get("old_settings_layout_mode") == "1" ? ESettingsLayout::Old : wxGetApp().app_config->get("new_settings_layout_mode") == "1" ? ESettingsLayout::New : wxGetApp().app_config->get("dlg_settings_layout_mode") == "1" ? ESettingsLayout::Dlg : ESettingsLayout::Old); +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION #else ESettingsLayout layout = wxGetApp().app_config->get("old_settings_layout_mode") == "1" ? ESettingsLayout::Old : wxGetApp().app_config->get("new_settings_layout_mode") == "1" ? ESettingsLayout::New : @@ -375,6 +408,12 @@ void MainFrame::update_layout() case ESettingsLayout::GCodeViewer: { m_main_sizer->Add(m_plater, 1, wxEXPAND); +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + m_plater->set_bed_shape({ { 0.0, 0.0 }, { 200.0, 0.0 }, { 200.0, 200.0 }, { 0.0, 200.0 } }, "", "", true); + m_plater->enable_view_toolbar(false); + m_plater->get_collapse_toolbar().set_enabled(false); + m_plater->collapse_sidebar(true); +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION m_plater->Show(); break; } @@ -482,6 +521,7 @@ void MainFrame::shutdown() if (m_plater != nullptr) { #if ENABLE_GCODE_VIEWER +#if !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION // restore sidebar if it was hidden when switching to gcode viewer mode if (m_restore_from_gcode_viewer.collapsed_sidebar) m_plater->collapse_sidebar(false); @@ -489,6 +529,7 @@ void MainFrame::shutdown() // restore sla printer if it was deselected when switching to gcode viewer mode if (m_restore_from_gcode_viewer.sla_technology) m_plater->set_printer_technology(ptSLA); +#endif // !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION #endif // ENABLE_GCODE_VIEWER // Stop the background thread (Windows and Linux). // Disconnect from a 3DConnextion driver (OSX). @@ -590,7 +631,10 @@ void MainFrame::init_tabpanel() // or when the preset's "modified" status changes. Bind(EVT_TAB_PRESETS_CHANGED, &MainFrame::on_presets_changed, this); // #ys_FIXME_to_delete - create_preset_tabs(); +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (wxGetApp().is_editor()) +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + create_preset_tabs(); if (m_plater) { // load initial config @@ -891,7 +935,7 @@ static void add_common_view_menu_items(wxMenu* view_menu, MainFrame* mainFrame, "", nullptr, [can_change_view]() { return can_change_view(); }, mainFrame); } -void MainFrame::init_editor_menubar() +void MainFrame::init_menubar_as_editor() #else void MainFrame::init_menubar() #endif // ENABLE_GCODE_VIEWER @@ -1055,6 +1099,7 @@ void MainFrame::init_menubar() [this](wxCommandEvent&) { repair_stl(); }, "wrench", nullptr, [this]() { return true; }, this); #if ENABLE_GCODE_VIEWER +#if !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION fileMenu->AppendSeparator(); append_menu_item(fileMenu, wxID_ANY, _L("&G-code preview"), _L("Switch to G-code preview mode"), [this](wxCommandEvent&) { @@ -1063,6 +1108,7 @@ void MainFrame::init_menubar() wxString(SLIC3R_APP_NAME) + " - " + _L("Switch to G-code preview mode"), wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION | wxCENTRE).ShowModal() == wxID_YES) set_mode(EMode::GCodeViewer); }, "", nullptr); +#endif // !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION #endif // ENABLE_GCODE_VIEWER fileMenu->AppendSeparator(); append_menu_item(fileMenu, wxID_EXIT, _L("&Quit"), wxString::Format(_L("Quit %s"), SLIC3R_APP_NAME), @@ -1286,6 +1332,17 @@ void MainFrame::init_menubar() // assign menubar to frame after appending items, otherwise special items // will not be handled correctly #if ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + m_menubar = new wxMenuBar(); + m_menubar->Append(fileMenu, _L("&File")); + if (editMenu) m_menubar->Append(editMenu, _L("&Edit")); + m_menubar->Append(windowMenu, _L("&Window")); + if (viewMenu) m_menubar->Append(viewMenu, _L("&View")); + // Add additional menus from C++ + wxGetApp().add_config_menu(m_menubar); + m_menubar->Append(helpMenu, _L("&Help")); + SetMenuBar(m_menubar); +#else m_editor_menubar = new wxMenuBar(); m_editor_menubar->Append(fileMenu, _L("&File")); if (editMenu) m_editor_menubar->Append(editMenu, _L("&Edit")); @@ -1295,6 +1352,7 @@ void MainFrame::init_menubar() wxGetApp().add_config_menu(m_editor_menubar); m_editor_menubar->Append(helpMenu, _L("&Help")); SetMenuBar(m_editor_menubar); +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION #else auto menubar = new wxMenuBar(); menubar->Append(fileMenu, _(L("&File"))); @@ -1323,15 +1381,11 @@ void MainFrame::init_menubar() #endif if (plater()->printer_technology() == ptSLA) -#if ENABLE_GCODE_VIEWER - update_editor_menubar(); -#else update_menubar(); -#endif // ENABLE_GCODE_VIEWER } #if ENABLE_GCODE_VIEWER -void MainFrame::init_gcodeviewer_menubar() +void MainFrame::init_menubar_as_gcodeviewer() { wxMenu* fileMenu = new wxMenu; { @@ -1342,9 +1396,11 @@ void MainFrame::init_gcodeviewer_menubar() append_menu_item(fileMenu, wxID_ANY, _L("Export &toolpaths as OBJ") + dots, _L("Export toolpaths as OBJ"), [this](wxCommandEvent&) { if (m_plater != nullptr) m_plater->export_toolpaths_to_obj(); }, "export_plater", nullptr, [this]() {return can_export_toolpaths(); }, this); +#if !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION fileMenu->AppendSeparator(); append_menu_item(fileMenu, wxID_ANY, _L("Exit &G-code preview"), _L("Switch to editor mode"), [this](wxCommandEvent&) { set_mode(EMode::Editor); }); +#endif // !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION fileMenu->AppendSeparator(); append_menu_item(fileMenu, wxID_EXIT, _L("&Quit"), wxString::Format(_L("Quit %s"), SLIC3R_APP_NAME), [this](wxCommandEvent&) { Close(false); }); @@ -1360,13 +1416,22 @@ void MainFrame::init_gcodeviewer_menubar() // helpmenu auto helpMenu = generate_help_menu(); +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + m_menubar = new wxMenuBar(); + m_menubar->Append(fileMenu, _L("&File")); + if (viewMenu != nullptr) m_menubar->Append(viewMenu, _L("&View")); + m_menubar->Append(helpMenu, _L("&Help")); + SetMenuBar(m_menubar); +#else m_gcodeviewer_menubar = new wxMenuBar(); m_gcodeviewer_menubar->Append(fileMenu, _L("&File")); - if ((viewMenu != nullptr)) + if (viewMenu != nullptr) m_gcodeviewer_menubar->Append(viewMenu, _L("&View")); m_gcodeviewer_menubar->Append(helpMenu, _L("&Help")); +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION } +#if !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION void MainFrame::set_mode(EMode mode) { if (m_mode == mode) @@ -1432,7 +1497,7 @@ void MainFrame::set_mode(EMode mode) TCHAR szExeFileName[MAX_PATH]; GetModuleFileName(nullptr, szExeFileName, MAX_PATH); SetIcon(wxIcon(szExeFileName, wxBITMAP_TYPE_ICO)); - } + } #else SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); #endif // _WIN32 @@ -1488,11 +1553,11 @@ void MainFrame::set_mode(EMode mode) m_plater->Thaw(); - SetIcon(wxIcon(Slic3r::var("PrusaSlicerGCodeViewer_128px.png"), wxBITMAP_TYPE_PNG)); + SetIcon(wxIcon(Slic3r::var("PrusaSlicer-gcodeviewer_128px.png"), wxBITMAP_TYPE_PNG)); #if ENABLE_GCODE_VIEWER_TASKBAR_ICON if (m_taskbar_icon != nullptr) { m_taskbar_icon->RemoveIcon(); - m_taskbar_icon->SetIcon(wxIcon(Slic3r::var("PrusaSlicerGCodeViewer_128px.png"), wxBITMAP_TYPE_PNG), "PrusaSlicer-GCode viewer"); + m_taskbar_icon->SetIcon(wxIcon(Slic3r::var("PrusaSlicer-gcodeviewer_128px.png"), wxBITMAP_TYPE_PNG), "PrusaSlicer-GCode viewer"); } #endif // ENABLE_GCODE_VIEWER_TASKBAR_ICON @@ -1500,20 +1565,22 @@ void MainFrame::set_mode(EMode mode) } } } +#endif // !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION #endif // ENABLE_GCODE_VIEWER -#if ENABLE_GCODE_VIEWER -void MainFrame::update_editor_menubar() -#else void MainFrame::update_menubar() -#endif // ENABLE_GCODE_VIEWER { +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (wxGetApp().is_gcode_viewer()) + return; +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + const bool is_fff = plater()->printer_technology() == ptFFF; - m_changeable_menu_items[miExport] ->SetItemLabel((is_fff ? _(L("Export &G-code")) : _(L("E&xport")) ) + dots + "\tCtrl+G"); - m_changeable_menu_items[miSend] ->SetItemLabel((is_fff ? _(L("S&end G-code")) : _(L("S&end to print"))) + dots + "\tCtrl+Shift+G"); + m_changeable_menu_items[miExport] ->SetItemLabel((is_fff ? _L("Export &G-code") : _L("E&xport")) + dots + "\tCtrl+G"); + m_changeable_menu_items[miSend] ->SetItemLabel((is_fff ? _L("S&end G-code") : _L("S&end to print")) + dots + "\tCtrl+Shift+G"); - m_changeable_menu_items[miMaterialTab] ->SetItemLabel((is_fff ? _(L("&Filament Settings Tab")) : _(L("Mate&rial Settings Tab"))) + "\tCtrl+3"); + m_changeable_menu_items[miMaterialTab] ->SetItemLabel((is_fff ? _L("&Filament Settings Tab") : _L("Mate&rial Settings Tab")) + "\tCtrl+3"); m_changeable_menu_items[miMaterialTab] ->SetBitmap(create_scaled_bitmap(is_fff ? "spool" : "resin")); m_changeable_menu_items[miPrinterTab] ->SetBitmap(create_scaled_bitmap(is_fff ? "printer" : "sla_printer")); @@ -1996,6 +2063,11 @@ SettingsDialog::SettingsDialog(MainFrame* mainframe) wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMINIMIZE_BOX | wxMAXIMIZE_BOX, "settings_dialog"), m_main_frame(mainframe) { +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (wxGetApp().is_gcode_viewer()) + return; +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + #if ENABLE_WX_3_1_3_DPI_CHANGED_EVENT && defined(__WXMSW__) // ys_FIXME! temporary workaround for correct font scaling // Because of from wxWidgets 3.1.3 auto rescaling is implemented for the Fonts, @@ -2006,8 +2078,6 @@ SettingsDialog::SettingsDialog(MainFrame* mainframe) #endif // ENABLE_WX_3_1_3_DPI_CHANGED_EVENT this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); - -// SetIcon(wxIcon(Slic3r::var("PrusaSlicer_128px.png"), wxBITMAP_TYPE_PNG)); // Load the icon either from the exe, or from the ico file. #if _WIN32 { @@ -2070,6 +2140,11 @@ SettingsDialog::SettingsDialog(MainFrame* mainframe) void SettingsDialog::on_dpi_changed(const wxRect& suggested_rect) { +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (wxGetApp().is_gcode_viewer()) + return; +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + const int& em = em_unit(); const wxSize& size = wxSize(85 * em, 50 * em); diff --git a/src/slic3r/GUI/MainFrame.hpp b/src/slic3r/GUI/MainFrame.hpp index 7777a053d..867e11e86 100644 --- a/src/slic3r/GUI/MainFrame.hpp +++ b/src/slic3r/GUI/MainFrame.hpp @@ -57,7 +57,7 @@ class SettingsDialog : public DPIDialog MainFrame* m_main_frame { nullptr }; public: SettingsDialog(MainFrame* mainframe); - ~SettingsDialog() {} + ~SettingsDialog() = default; void set_tabpanel(wxNotebook* tabpanel) { m_tabpanel = tabpanel; } protected: @@ -72,6 +72,9 @@ class MainFrame : public DPIFrame wxString m_qs_last_output_file = wxEmptyString; wxString m_last_config = wxEmptyString; #if ENABLE_GCODE_VIEWER +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + wxMenuBar* m_menubar{ nullptr }; +#else wxMenuBar* m_editor_menubar{ nullptr }; wxMenuBar* m_gcodeviewer_menubar{ nullptr }; @@ -83,6 +86,7 @@ class MainFrame : public DPIFrame }; RestoreFromGCodeViewer m_restore_from_gcode_viewer; +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION #endif // ENABLE_GCODE_VIEWER #if 0 @@ -146,6 +150,7 @@ class MainFrame : public DPIFrame ESettingsLayout m_layout{ ESettingsLayout::Unknown }; #if ENABLE_GCODE_VIEWER +#if !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION public: enum class EMode : unsigned char { @@ -155,6 +160,7 @@ public: private: EMode m_mode{ EMode::Editor }; +#endif // !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION #endif // ENABLE_GCODE_VIEWER protected: @@ -182,16 +188,17 @@ public: void create_preset_tabs(); void add_created_tab(Tab* panel); #if ENABLE_GCODE_VIEWER - void init_editor_menubar(); - void update_editor_menubar(); - void init_gcodeviewer_menubar(); + void init_menubar_as_editor(); + void init_menubar_as_gcodeviewer(); +#if !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION EMode get_mode() const { return m_mode; } void set_mode(EMode mode); +#endif // !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION #else void init_menubar(); - void update_menubar(); #endif // ENABLE_GCODE_VIEWER + void update_menubar(); void update_ui_from_settings(); bool is_loaded() const { return m_loaded; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 45a1f6ea8..09640ebaf 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -1369,41 +1369,52 @@ bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &fi this->MSWUpdateDragImageOnLeave(); #endif // WIN32 - // gcode section - for (const auto& filename : filenames) { - fs::path path(into_path(filename)); - if (std::regex_match(path.string(), pattern_gcode_drop)) - paths.push_back(std::move(path)); - } - - if (paths.size() > 1) { - wxMessageDialog((wxWindow*)plater, _L("You can open only one .gcode file at a time."), - wxString(SLIC3R_APP_NAME) + " - " + _L("Drag and drop G-code file"), wxCLOSE | wxICON_WARNING | wxCENTRE).ShowModal(); - return false; - } - else if (paths.size() == 1) { - if (wxGetApp().mainframe->get_mode() == MainFrame::EMode::GCodeViewer) { - plater->load_gcode(from_path(paths.front())); - return true; +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (wxGetApp().is_gcode_viewer()) { +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + // gcode section + for (const auto& filename : filenames) { + fs::path path(into_path(filename)); + if (std::regex_match(path.string(), pattern_gcode_drop)) + paths.push_back(std::move(path)); } - else { - if (wxMessageDialog((wxWindow*)plater, _L("Do you want to switch to G-code preview ?"), - wxString(SLIC3R_APP_NAME) + " - " + _L("Drag and drop G-code file"), wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES) { - if (plater->model().objects.empty() || - wxMessageDialog((wxWindow*)plater, _L("Switching to G-code preview mode will remove all objects, continue?"), - wxString(SLIC3R_APP_NAME) + " - " + _L("Switch to G-code preview mode"), wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES) { - wxGetApp().mainframe->set_mode(MainFrame::EMode::GCodeViewer); - plater->load_gcode(from_path(paths.front())); - return true; - } - } + if (paths.size() > 1) { + wxMessageDialog((wxWindow*)plater, _L("You can open only one .gcode file at a time."), + wxString(SLIC3R_APP_NAME) + " - " + _L("Drag and drop G-code file"), wxCLOSE | wxICON_WARNING | wxCENTRE).ShowModal(); return false; } + else if (paths.size() == 1) { +#if !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (wxGetApp().mainframe->get_mode() == MainFrame::EMode::GCodeViewer) { +#endif // !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + plater->load_gcode(from_path(paths.front())); + return true; +#if !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + } + else { + if (wxMessageDialog((wxWindow*)plater, _L("Do you want to switch to G-code preview ?"), + wxString(SLIC3R_APP_NAME) + " - " + _L("Drag and drop G-code file"), wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES) { + + if (plater->model().objects.empty() || + wxMessageDialog((wxWindow*)plater, _L("Switching to G-code preview mode will remove all objects, continue?"), + wxString(SLIC3R_APP_NAME) + " - " + _L("Switch to G-code preview mode"), wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES) { + wxGetApp().mainframe->set_mode(MainFrame::EMode::GCodeViewer); + plater->load_gcode(from_path(paths.front())); + return true; + } + } + return false; + } +#endif // !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + } +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + return false; } +#endif //ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION #endif // ENABLE_GCODE_VIEWER - // model section + // editor section for (const auto &filename : filenames) { fs::path path(into_path(filename)); if (std::regex_match(path.string(), pattern_drop)) @@ -1413,6 +1424,7 @@ bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &fi } #if ENABLE_GCODE_VIEWER +#if !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION if (wxGetApp().mainframe->get_mode() == MainFrame::EMode::GCodeViewer) { if (wxMessageDialog((wxWindow*)plater, _L("Do you want to exit G-code preview ?"), wxString(SLIC3R_APP_NAME) + " - " + _L("Drag and drop model file"), wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT | wxCENTRE).ShowModal() == wxID_YES) @@ -1420,6 +1432,7 @@ bool PlaterDropTarget::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &fi else return false; } +#endif // !ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION #endif // ENABLE_GCODE_VIEWER wxString snapshot_label; @@ -1970,7 +1983,13 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) q->SetDropTarget(new PlaterDropTarget(q)); // if my understanding is right, wxWindow takes the owenership q->Layout(); +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + set_current_panel(wxGetApp().is_editor() ? (wxPanel*)view3D : (wxPanel*)preview); + if (wxGetApp().is_gcode_viewer()) + preview->hide_layers_slider(); +#else set_current_panel(view3D); +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION // updates camera type from .ini file camera.set_type(get_config("use_perspective_camera")); @@ -1990,33 +2009,38 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) #endif /* _WIN32 */ notification_manager = new NotificationManager(this->q); - this->q->Bind(EVT_EJECT_DRIVE_NOTIFICAION_CLICKED, [this](EjectDriveNotificationClickedEvent&) { this->q->eject_drive(); }); - this->q->Bind(EVT_EXPORT_GCODE_NOTIFICAION_CLICKED, [this](ExportGcodeNotificationClickedEvent&) { this->q->export_gcode(true); }); - this->q->Bind(EVT_PRESET_UPDATE_AVIABLE_CLICKED, [this](PresetUpdateAviableClickedEvent&) { wxGetApp().get_preset_updater()->on_update_notification_confirm(); }); - - this->q->Bind(EVT_REMOVABLE_DRIVE_EJECTED, [this, q](RemovableDriveEjectEvent &evt) { - if (evt.data.second) { - this->show_action_buttons(this->ready_to_slice); - notification_manager->push_notification(format(_L("Unmounting successful. The device %s(%s) can now be safely removed from the computer."),evt.data.first.name, evt.data.first.path), - NotificationManager::NotificationLevel::RegularNotification, *q->get_current_canvas3D()); - } else { - notification_manager->push_notification(format(_L("Ejecting of device %s(%s) has failed."), evt.data.first.name, evt.data.first.path), - NotificationManager::NotificationLevel::ErrorNotification, *q->get_current_canvas3D()); - } - }); - this->q->Bind(EVT_REMOVABLE_DRIVES_CHANGED, [this, q](RemovableDrivesChangedEvent &) { - this->show_action_buttons(this->ready_to_slice); - if (!this->sidebar->get_eject_shown()) { - notification_manager->close_notification_of_type(NotificationType::ExportToRemovableFinished); - } - }); - // Start the background thread and register this window as a target for update events. - wxGetApp().removable_drive_manager()->init(this->q); +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + if (wxGetApp().is_editor()) { +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + this->q->Bind(EVT_EJECT_DRIVE_NOTIFICAION_CLICKED, [this](EjectDriveNotificationClickedEvent&) { this->q->eject_drive(); }); + this->q->Bind(EVT_EXPORT_GCODE_NOTIFICAION_CLICKED, [this](ExportGcodeNotificationClickedEvent&) { this->q->export_gcode(true); }); + this->q->Bind(EVT_PRESET_UPDATE_AVIABLE_CLICKED, [this](PresetUpdateAviableClickedEvent&) { wxGetApp().get_preset_updater()->on_update_notification_confirm(); }); + this->q->Bind(EVT_REMOVABLE_DRIVE_EJECTED, [this, q](RemovableDriveEjectEvent &evt) { + if (evt.data.second) { + this->show_action_buttons(this->ready_to_slice); + notification_manager->push_notification(format(_L("Unmounting successful. The device %s(%s) can now be safely removed from the computer."),evt.data.first.name, evt.data.first.path), + NotificationManager::NotificationLevel::RegularNotification, *q->get_current_canvas3D()); + } else { + notification_manager->push_notification(format(_L("Ejecting of device %s(%s) has failed."), evt.data.first.name, evt.data.first.path), + NotificationManager::NotificationLevel::ErrorNotification, *q->get_current_canvas3D()); + } + }); + this->q->Bind(EVT_REMOVABLE_DRIVES_CHANGED, [this, q](RemovableDrivesChangedEvent &) { + this->show_action_buttons(this->ready_to_slice); + if (!this->sidebar->get_eject_shown()) { + notification_manager->close_notification_of_type(NotificationType::ExportToRemovableFinished); + } + }); + // Start the background thread and register this window as a target for update events. + wxGetApp().removable_drive_manager()->init(this->q); #ifdef _WIN32 - // Trigger enumeration of removable media on Win32 notification. - this->q->Bind(EVT_VOLUME_ATTACHED, [this](VolumeAttachedEvent &evt) { wxGetApp().removable_drive_manager()->volumes_changed(); }); - this->q->Bind(EVT_VOLUME_DETACHED, [this](VolumeDetachedEvent &evt) { wxGetApp().removable_drive_manager()->volumes_changed(); }); + // Trigger enumeration of removable media on Win32 notification. + this->q->Bind(EVT_VOLUME_ATTACHED, [this](VolumeAttachedEvent &evt) { wxGetApp().removable_drive_manager()->volumes_changed(); }); + this->q->Bind(EVT_VOLUME_DETACHED, [this](VolumeDetachedEvent &evt) { wxGetApp().removable_drive_manager()->volumes_changed(); }); #endif /* _WIN32 */ +#if ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION + } +#endif // ENABLE_GCODE_VIEWER_AS_STANDALONE_APPLICATION // Initialize the Undo / Redo stack with a first snapshot. this->take_snapshot(_L("New Project")); @@ -5384,7 +5408,7 @@ void Plater::on_config_change(const DynamicPrintConfig &config) this->set_printer_technology(config.opt_enum(opt_key)); // print technology is changed, so we should to update a search list p->sidebar->update_searcher(); - } + } else if ((opt_key == "bed_shape") || (opt_key == "bed_custom_texture") || (opt_key == "bed_custom_model")) { bed_shape_changed = true; update_scheduled = true; @@ -5628,11 +5652,7 @@ void Plater::set_printer_technology(PrinterTechnology printer_technology) p->label_btn_send = printer_technology == ptFFF ? L("Send G-code") : L("Send to printer"); if (wxGetApp().mainframe != nullptr) -#if ENABLE_GCODE_VIEWER - wxGetApp().mainframe->update_editor_menubar(); -#else wxGetApp().mainframe->update_menubar(); -#endif // ENABLE_GCODE_VIEWER p->update_main_toolbar_tooltips();