From ab556a398b579b65802cfa7fdd39d543ab49fbec Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 8 Sep 2020 11:40:06 +0200 Subject: [PATCH] GCode viewer using the proper layout when started as a standalone application --- .../icons/PrusaSlicer-gcodeviewer_128px.png | Bin 0 -> 5069 bytes .../icons/PrusaSlicerGCodeViewer_128px.png | Bin 15949 -> 0 bytes src/PrusaSlicer.cpp | 4 + src/libslic3r/AppConfig.cpp | 5 + src/libslic3r/AppConfig.hpp | 11 ++ src/libslic3r/Technologies.hpp | 1 + src/slic3r/GUI/GCodeViewer.cpp | 8 ++ src/slic3r/GUI/GLCanvas3D.cpp | 16 +++ src/slic3r/GUI/GUI_App.cpp | 93 ++++++++---- src/slic3r/GUI/GUI_App.hpp | 25 ++++ src/slic3r/GUI/GUI_Preview.cpp | 4 + src/slic3r/GUI/GUI_Preview.hpp | 5 + src/slic3r/GUI/KBShortcutsDialog.cpp | 6 + src/slic3r/GUI/MainFrame.cpp | 125 ++++++++++++---- src/slic3r/GUI/MainFrame.hpp | 17 ++- src/slic3r/GUI/Plater.cpp | 136 ++++++++++-------- 16 files changed, 341 insertions(+), 115 deletions(-) create mode 100644 resources/icons/PrusaSlicer-gcodeviewer_128px.png delete mode 100644 resources/icons/PrusaSlicerGCodeViewer_128px.png diff --git a/resources/icons/PrusaSlicer-gcodeviewer_128px.png b/resources/icons/PrusaSlicer-gcodeviewer_128px.png new file mode 100644 index 0000000000000000000000000000000000000000..d8e3e438be6c5fc64f7ebc8744a842bdcbfd6aa5 GIT binary patch literal 5069 zcmV;;6Ef_HP))84dsd02y>e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{024JyL_t(|+U=ctbW~NA#((G5 zBk%VT!R93(Dv~vXmu(9^K%o^C6qz1+v>g#2-D88cqsVfUv009`YZ?W+5qli9ZAW?< z6=}f?&>*y+%_D%k#25leAdx`Gvr<*5d+(V)>ViooNZqQsx2lr**5aQ~r|zlqeRrRI z_SxrbK{tYwQUF;%KVUF06c_>w0Qvw0#{Z`RZa|!A3bX+}pc$wGYJdu$3@8N-164q? z5JGmBF%t<+xC^)#7z&&n@YZ{Jj53j zd(m}`{nZDNQg#>uP1hKZ*N^d((s+>>vZDnQ2Dr%cgM#o!L6t24XN~T{qjUfXsVbJ$3 zCO0!T7C-YSFhvM)Fm423y!mTmMZU-9Vf(%ve7wDw4|c7>uUfy)(m$^sv#+1U*uv2a zA2d7`BA6TvOCX{^et%$nEX;mWYcs1qUCk@SOR1_q789!@gkVhnkvww8Tz*h^6;6lK z>OBNPPkkA^8Qyn{TVb*Wztq^_Dd}zw$-uJg12lOc;C(kN*9m6kRsLPRDR^B&!1v z0r_db`*tt&4wN6@U*A~3j;fNlb=QA()dSpp+uiiLsIOg1#OdM22}GFWD+D)m9=2;x zRZZo;*S^ay-+vCj+D5!1i%g!nc^*@5o=R3$mer5@4KO#Hw6kypFdKLcn<9Ltn@+Rv zt>;)#@e#^3P_8#;1_m3qLa3lTa!hBKaYhA7czeQ zc!aQIE9N!er=cd5m=VA&1QQl4U+A`YTbT3GT-JTHF{1BDZE=%cpNh-lL}=j;w(ipL z<+kC;^P#!4h=f>hB!`qXH}mGrW7@Q7R`>-faJvvx0Y%aa@Qmck> zkil8x7C=fl%5eNF&)%)AujTqDZ=}&@{zzS_$4yREW<;jmyftW};i4APj-!z9`hBl4 z`PxZVcF$)xge75H0OQcc^VpQS{l-Ucg++em=`?aHvTP+kXbs%t9m_&UbI+9m)_t)a zO}F$+NGkBW!C}}_z|8~?ZCH+N2e$Lu4a>qJKeHx1c-|%ka5uTgJ7zv4@;@c-ap>qF ztGhSR;LyAPjI(+Rup!##ZS%3{y_bLXTnZKT0v z=mIc~Xg^`czy-7bzh3#0`Jl>i`{(@cp4cI$CeyS(@ZshU?daVT2B#rgfJp>T>ROI3 zj~-%g^?q}2TVpD&7ANrrXRCwM7PqN3%Qn7_KVW$VQ<1^x`2}EX_0GYjQ$ueR|K8jZ zN*83*rV+2mIAw0Z)Y{g{p3*O@?v?=Nbalw2D+^Fa@MaFn(dcPp<*q-Q8{o!N9BuJ? z&cxa3#N{_@d6AnjCqpC-@F&SuUJ|JhWV zKbNdV)l{py<}$cFw*ZXWxbC!Tur}=Z#9ZLTw#~JtJ12_~1Q%9JK^EWiucE4l?j-Bnye?GxW7;Qmm zg*nG3)#Hw@b^kfY2T-fa=)L6)hNWeY-fJkFC-K7<@Zr^bc6E7zlrsO!R&o1R>S}Dd zfis{5_~f9u9KRHk>+4vO-?H?63R^1qqf?N6<6WeVzayTyU0`tiQRgY(7Q1?Ivf&h; z9sZl?AWNc!CEjeG;T zis$WLpw(8ylK`$YI6rFvF2=@-n;IJ%O?}?&b0Tz+c;uh41D;wu?=D38TjNClgAC5k z3ScZY-pRZFsJS$6r|L*p^3Q&*Yy;j+e~K3YxD3wE3SgX_PcN-Dw*pY&!2Cx-zOj(S zU;HBKvC?=E!8icL$oDU@>#3@yvg3%k+s_<+CBexzrUKPR>#D_|#YKUUA}OU%fNX+g zR%}5)3((LSx(^_9fuqfl@Z_Iu`(-h02R@Gn0Sp1M6`(J{8auYY*XF0$*J4fp0i|1z ze+J$)uOI`ySPLK*=&KN{u4UT@o6Uq3QUuSwb`$aewBtJo9NZRb0Vu#=1)HySscSTM znS~OA@UNBRpK%C%8{P!#w}8)wp^BaJKS03bwoLXH@@@8r>IqjVl99n3c;d^ zN!Un!a7iHXm#mNVPadEUtf-kJ-%j$+Si_wwklyB4{_H*q@mqthTayo)`wm;oT z@O-W4$!~tu(g%3t#8F~a-FfTVj6AlF6_+k2#g$^K0aAdro=kqr()$sO6)}GUbX`Z6 zwo9;0A$XTea?bCW@F@hZ7)_GjGtsO7bxHDjEb0`XCP{veMU4X3IvUdCojy_|$+r*{ z3Q%U}6I0#hBG0-*Pm*sP%A5p?57~yitXz{8Kn9}}(mL|bSS44K)`GeOEinX8>I4oG z%(}BBFVN+5A%rlBHij^mibQkj=S>Wa+{b>OfQI0iHT z`Swf!Y2>73hnyNN9l^W%ze@noF#Elt90?lei2Jv{0XU`rO?LVLE~k^r`&?$Kjpo)9 zZqC=^o`1@KCdH^MvD>bvDnjAPA!E!5AWcg;e9^~lA;j5xy832?v2}MS1*PRxP-j)(8I!-uCeoA zNs|1?v9WzQxz6FW<#zR=AiIF^mt1YC&42#y>!`<*NU5S`n(P-@=02gX22{q0sGG@ z03n19EWxINY?t&M!aYB@%T${kI(!^RGHL=6SYmK{UJC%Q4jXp}XWsB56k#qO)hz;wG68Z7lm zym7|A8Xw)zfoBaaF>3(;KJFYiux!Ap%edu>4;Z1CPtN6zHRtFeOlso~vQzg&ffJ(B7eJB9}|nCX#xZn7VWq9CGsM%f3< zH#j6*3xE)!1XyMn`JH0>mpkC!!aO3sO@}*LC7%cE&&&4$EB!FDRZ<ya?ImNGWdtR?@N3SXA6)|IT%^zVj$j{dT7DN_fUASsMX~ z3NX`VRo(gb)p(HZUzaDdlK_nM0P` zFe-f>yzAe_w|>#t3ly6q{LTk&tKBE;H~-crxPRJxrm~~YgJxiY5W-YFp0MnWlybIV zYAiZXDhV9kL+gqc(5kkB5J=#CKm4*Su|=RL3csDTm|Mq3wN9rFJSc>C-E6~f1)uzr7gm$G=84*8qZDD*U@&QksApL01kK!@^n5GHl@G(f;b+0CT(A?XyGx zh6vJt_ko+N9yqS^2e8NR>1gI2YjuT{xg{^&c1(L!cQ22bAlI5&;^ zAs6OdXvHH+fXPCLu+#Y?UVBI>`vdE-v-XgtqE>%R+y1}d-L;C{#}DvFpUPS-J~rWc zXI;o+w>`q-?@uB>+p=pHN`V`N5S5X9NmLe}Qp%x*B^YS?Xlp9ksVdat<$P7PhmZGe z^VeT>tddVJ?7;F#u4BR4&V z40k$(eG3_IK|hLy6p@*cNkMJ_z4CgIoo;)vl~Ul=XuSEB2%w!$@PS>9VVHeH)iqQt zKwBVy?BqE(6a|;lg(4Ijio=Sn+Hf7dJ0hL)Ef+w$)xjU^SR(ci6a#lh;_aW)f3c#s zMn|U`0g7bqZUi9^V+^NTLB3@cpq(X9fLXvIdU$oRFwhMA0(c{w2wz+Xpq&s#18)Mu zle~t6{lL9uH+JG?3g}`=*a?g$xPhc5`8_98V~obzLB4Gkpq(WUz!ZWTNrRGncR)EX z7g!T&GDpH#fOeKZ8mUTSfS2h3j>|lP&^?(@N$MFz`Apt(oG8B{|i9@3W0lp8Nfve zMtn7}!iazDvoe^|Ed|g?4B3XGI1`uv6vSy)>j-8{F9$YszK|&?far)J4;W{}6RtDj z39*_c0>=7%6Tw`FEkcO;L>kY8cC@6FF5qHdEO0e25*PyHTCl9t36@zYBY5e;R)SZq zA31aJaw4KzdD=##F$?Gi3?`VEG6Wa^^f9K6EFcwdxBLB);At-(!A+Ptf(11z48ltZ j7T2l*n(YqOSc(4w{3s$Y5itx{00000NkvXXu0mjfDT8&X literal 0 HcmV?d00001 diff --git a/resources/icons/PrusaSlicerGCodeViewer_128px.png b/resources/icons/PrusaSlicerGCodeViewer_128px.png deleted file mode 100644 index 0bf85abbd6ea0585d127686a8200b4a647a030b8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15949 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Ʊ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 AMF0Q* 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();