From ef0dae8c97839686e41753cb03232b5a04d6e954 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 26 Oct 2021 14:52:20 +0200 Subject: [PATCH] Implemented possibility to apply conversion from inches/meters to mm for all loaded objects at once + Added MessageWithCheckBox dialog + some code refactoring for MessageDlg --- src/slic3r/GUI/MsgDialog.cpp | 83 +++++++++++++++++++++++------------- src/slic3r/GUI/MsgDialog.hpp | 19 +++++++++ src/slic3r/GUI/Plater.cpp | 61 ++++++++++++++++++-------- 3 files changed, 115 insertions(+), 48 deletions(-) diff --git a/src/slic3r/GUI/MsgDialog.cpp b/src/slic3r/GUI/MsgDialog.cpp index 9f3f34f844..c4cdde3d90 100644 --- a/src/slic3r/GUI/MsgDialog.cpp +++ b/src/slic3r/GUI/MsgDialog.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -75,6 +76,26 @@ void MsgDialog::add_btn(wxWindowID btn_id, bool set_focus /*= false*/) btn->Bind(wxEVT_BUTTON, [this, btn_id](wxCommandEvent&) { this->EndModal(btn_id); }); }; +void MsgDialog::apply_style(long style) +{ + if (style & wxOK) add_btn(wxID_OK, true); + if (style & wxYES) add_btn(wxID_YES); + if (style & wxNO) add_btn(wxID_NO); + if (style & wxCANCEL) add_btn(wxID_CANCEL); + + logo->SetBitmap(create_scaled_bitmap(style & wxICON_WARNING ? "exclamation" : + style & wxICON_INFORMATION ? "info" : + style & wxICON_QUESTION ? "question" : "PrusaSlicer"/*"_192px_grayscale.png"*/, this, 84)); +} + +void MsgDialog::finalize() +{ + wxGetApp().UpdateDlgDarkUI(this); + Fit(); + this->CenterOnParent(); +} + + // Text shown as HTML, so that mouse selection and Ctrl-V to copy will work. static void add_msg_content(wxWindow* parent, wxBoxSizer* content_sizer, wxString msg, bool monospaced_font = false) { @@ -156,11 +177,9 @@ ErrorDialog::ErrorDialog(wxWindow *parent, const wxString &msg, bool monospaced_ // Use a small bitmap with monospaced font, as the error text will not be wrapped. logo->SetBitmap(create_scaled_bitmap("PrusaSlicer_192px_grayscale.png", this, monospaced_font ? 48 : /*1*/84)); - wxGetApp().UpdateDlgDarkUI(this); - SetMaxSize(wxSize(-1, CONTENT_MAX_HEIGHT*wxGetApp().em_unit())); - Fit(); - this->CenterOnParent(); + + finalize(); } // WarningDialog @@ -173,16 +192,8 @@ WarningDialog::WarningDialog(wxWindow *parent, wxString::Format(_L("%s has a warning")+":", SLIC3R_APP_NAME), wxID_NONE) { add_msg_content(this, content_sizer, message); - - if (style & wxOK) add_btn(wxID_OK, true); - if (style & wxYES) add_btn(wxID_YES); - if (style & wxNO) add_btn(wxID_NO); - - logo->SetBitmap(create_scaled_bitmap("PrusaSlicer_192px_grayscale.png", this, 84)); - - wxGetApp().UpdateDlgDarkUI(this); - Fit(); - this->CenterOnParent(); + apply_style(style); + finalize(); } #ifdef _WIN32 @@ -195,23 +206,37 @@ MessageDialog::MessageDialog(wxWindow* parent, : MsgDialog(parent, caption.IsEmpty() ? wxString::Format(_L("%s info"), SLIC3R_APP_NAME) : caption, wxEmptyString, wxID_NONE) { add_msg_content(this, content_sizer, message); - - if (style & wxOK) add_btn(wxID_OK, true); - if (style & wxYES) add_btn(wxID_YES); - if (style & wxNO) add_btn(wxID_NO); - if (style & wxCANCEL) add_btn(wxID_CANCEL); - - logo->SetBitmap(create_scaled_bitmap(style & wxICON_WARNING ? "exclamation" : - style & wxICON_INFORMATION ? "info" : - style & wxICON_QUESTION ? "question" : "PrusaSlicer_192px_grayscale.png", this, 84)); - - wxGetApp().UpdateDlgDarkUI(this); - Fit(); - this->CenterOnParent(); + apply_style(style); + finalize(); } #endif +// MessageWithCheckDialog + +MessageWithCheckDialog::MessageWithCheckDialog( wxWindow* parent, + const wxString& message, + const wxString& checkbox_label, + const wxString& caption/* = wxEmptyString*/, + long style/* = wxOK*/) + : MsgDialog(parent, caption.IsEmpty() ? wxString::Format(_L("%s info"), SLIC3R_APP_NAME) : caption, wxEmptyString, wxID_NONE) +{ + add_msg_content(this, content_sizer, message); + + m_check = new wxCheckBox(this, wxID_ANY, checkbox_label); + content_sizer->Add(m_check, 0, wxTOP, 10); + + apply_style(style); + finalize(); +} + +bool MessageWithCheckDialog::GetCheckVal() +{ + if (m_check) + return m_check->GetValue(); + return false; +} + // InfoDialog InfoDialog::InfoDialog(wxWindow* parent, const wxString &title, const wxString& msg) @@ -222,9 +247,7 @@ InfoDialog::InfoDialog(wxWindow* parent, const wxString &title, const wxString& // Set info bitmap logo->SetBitmap(create_scaled_bitmap("info", this, 84)); - wxGetApp().UpdateDlgDarkUI(this); - - Fit(); + finalize(); } diff --git a/src/slic3r/GUI/MsgDialog.hpp b/src/slic3r/GUI/MsgDialog.hpp index 77617fea1b..d3263f970e 100644 --- a/src/slic3r/GUI/MsgDialog.hpp +++ b/src/slic3r/GUI/MsgDialog.hpp @@ -43,6 +43,8 @@ protected: MsgDialog(wxWindow *parent, const wxString &title, const wxString &headline, wxWindowID button_id = wxID_OK, wxBitmap bitmap = wxNullBitmap); void add_btn(wxWindowID btn_id, bool set_focus = false); + void apply_style(long style); + void finalize(); wxFont boldfont; wxBoxSizer *content_sizer; @@ -113,6 +115,23 @@ public: }; #endif +class MessageWithCheckDialog : public MsgDialog +{ + wxCheckBox* m_check{ nullptr }; +public: + MessageWithCheckDialog(wxWindow* parent, + const wxString& message, + const wxString& checkbox_label, + const wxString& caption = wxEmptyString, + long style = wxOK); + MessageWithCheckDialog(MessageWithCheckDialog&&) = delete; + MessageWithCheckDialog(const MessageWithCheckDialog&) = delete; + MessageWithCheckDialog& operator=(MessageWithCheckDialog&&) = delete; + MessageWithCheckDialog& operator=(const MessageWithCheckDialog&) = delete; + virtual ~MessageWithCheckDialog() = default; + + bool GetCheckVal(); +}; // Generic info dialog, used for displaying exceptions class InfoDialog : public MsgDialog diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index ec4fc2d80d..f138c0af17 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2312,6 +2312,9 @@ std::vector Plater::priv::load_files(const std::vector& input_ auto *new_model = (!load_model || one_by_one) ? nullptr : new Slic3r::Model(); std::vector obj_idxs; + int answer_convert_from_meters = wxOK_DEFAULT; + int answer_convert_from_imperial_units = wxOK_DEFAULT; + for (size_t i = 0; i < input_files.size(); ++i) { #ifdef _WIN32 auto path = input_files[i]; @@ -2469,26 +2472,48 @@ std::vector Plater::priv::load_files(const std::vector& input_ // Convert even if the object is big. convert_from_imperial_units(model, false); else if (model.looks_like_saved_in_meters()) { - MessageDialog msg_dlg(q, format_wxstr(_L_PLURAL( - "The dimensions of the object from file %s seem to be defined in meters.\n" - "The internal unit of PrusaSlicer are millimeters. Do you want to recalculate the dimensions of the object?", - "The dimensions of some objects from file %s seem to be defined in meters.\n" - "The internal unit of PrusaSlicer are millimeters. Do you want to recalculate the dimensions of these objects?", model.objects.size()), from_path(filename)) + "\n", - _L("The object is too small"), wxICON_WARNING | wxYES | wxNO); - if (msg_dlg.ShowModal() == wxID_YES) - //FIXME up-scale only the small parts? - model.convert_from_meters(true); + auto convert_model_if = [](Model& model, bool condition) { + if (condition) + //FIXME up-scale only the small parts? + model.convert_from_meters(true); + }; + if (answer_convert_from_meters == wxOK_DEFAULT) { + MessageWithCheckDialog dlg(q, format_wxstr(_L_PLURAL( + "The dimensions of the object from file %s seem to be defined in meters.\n" + "The internal unit of PrusaSlicer are millimeters. Do you want to recalculate the dimensions of the object?", + "The dimensions of some objects from file %s seem to be defined in meters.\n" + "The internal unit of PrusaSlicer are millimeters. Do you want to recalculate the dimensions of these objects?", model.objects.size()), from_path(filename)) + "\n", + _L("Apply to all the remaining small objects being loaded."), + _L("The object is too small"), wxICON_WARNING | wxYES | wxNO); + int answer = dlg.ShowModal(); + if (dlg.GetCheckVal()) + answer_convert_from_meters = answer; + else + convert_model_if(model, answer == wxID_YES); + } + convert_model_if(model, answer_convert_from_meters == wxID_YES); } else if (model.looks_like_imperial_units()) { - MessageDialog msg_dlg(q, format_wxstr(_L_PLURAL( - "The dimensions of the object from file %s seem to be defined in inches.\n" - "The internal unit of PrusaSlicer are millimeters. Do you want to recalculate the dimensions of the object?", - "The dimensions of some objects from file %s seem to be defined in inches.\n" - "The internal unit of PrusaSlicer are millimeters. Do you want to recalculate the dimensions of these objects?", model.objects.size()), from_path(filename)) + "\n", - _L("The object is too small"), wxICON_WARNING | wxYES | wxNO); - if (msg_dlg.ShowModal() == wxID_YES) - //FIXME up-scale only the small parts? - convert_from_imperial_units(model, true); + auto convert_model_if = [convert_from_imperial_units](Model& model, bool condition) { + if (condition) + //FIXME up-scale only the small parts? + convert_from_imperial_units(model, true); + }; + if (answer_convert_from_imperial_units == wxOK_DEFAULT) { + MessageWithCheckDialog dlg(q, format_wxstr(_L_PLURAL( + "The dimensions of the object from file %s seem to be defined in inches.\n" + "The internal unit of PrusaSlicer are millimeters. Do you want to recalculate the dimensions of the object?", + "The dimensions of some objects from file %s seem to be defined in inches.\n" + "The internal unit of PrusaSlicer are millimeters. Do you want to recalculate the dimensions of these objects?", model.objects.size()), from_path(filename)) + "\n", + _L("Apply to all the remaining small objects being loaded."), + _L("The object is too small"), wxICON_WARNING | wxYES | wxNO); + int answer = dlg.ShowModal(); + if (dlg.GetCheckVal()) + answer_convert_from_imperial_units = answer; + else + convert_model_if(model, answer == wxID_YES); + } + convert_model_if(model, answer_convert_from_imperial_units == wxID_YES); } if (model.looks_like_multipart_object()) {