From 3c37aed2f8c52634fdc9e74a8f59f4cc505d8c3c Mon Sep 17 00:00:00 2001 From: YuSanka <yusanka@gmail.com> Date: Wed, 10 Feb 2021 11:24:25 +0100 Subject: [PATCH] Fixed old (MSW specific) focus issue: Description of issue: When for some parameter set a value which is out of rage or inaccurate and than click to another parameter, receive a warning message dialog with description of a problem. After closing of this Dialog any button on settings tab doesn't work for first click. Looks like after dialog is closed Notebook page loses a focus. Workaround: Use self-created WarningDialog (inherited from the wxDialog) instead of wxMessageDialog --- src/slic3r/GUI/Field.cpp | 10 +++++--- src/slic3r/GUI/MsgDialog.cpp | 50 ++++++++++++++++++++++++++++++++++++ src/slic3r/GUI/MsgDialog.hpp | 21 +++++++++++++++ 3 files changed, 77 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index be7d7c1c7..de050a477 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -16,6 +16,7 @@ #include <wx/tokenzr.h> #include <boost/algorithm/string/predicate.hpp> #include "OG_CustomCtrl.hpp" +#include "MsgDialog.hpp" #ifdef __WXOSX__ #define wxOSX true @@ -263,7 +264,8 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true if (m_value.empty() || boost::any_cast<double>(m_value) != val) { wxString msg_text = format_wxstr(_L("Input value is out of range\n" "Are you sure that %s is a correct value and that you want to continue?"), str); - wxMessageDialog dialog(m_parent, msg_text, _L("Parameter validation") + ": " + m_opt_id, wxICON_WARNING | wxYES | wxNO); +// wxMessageDialog dialog(m_parent, msg_text, _L("Parameter validation") + ": " + m_opt_id, wxICON_WARNING | wxYES | wxNO); + WarningDialog dialog(m_parent, msg_text, _L("Parameter validation") + ": " + m_opt_id, wxYES | wxNO); if (dialog.ShowModal() == wxID_NO) { if (m_value.empty()) { if (m_opt.min > val) val = m_opt.min; @@ -323,7 +325,8 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true const wxString msg_text = from_u8((boost::format(_utf8(L("Do you mean %s%% instead of %s %s?\n" "Select YES if you want to change this value to %s%%, \n" "or NO if you are sure that %s %s is a correct value."))) % stVal % stVal % sidetext % stVal % stVal % sidetext).str()); - wxMessageDialog dialog(m_parent, msg_text, _(L("Parameter validation")) + ": " + m_opt_id , wxICON_WARNING | wxYES | wxNO); +// wxMessageDialog dialog(m_parent, msg_text, _(L("Parameter validation")) + ": " + m_opt_id , wxICON_WARNING | wxYES | wxNO); + WarningDialog dialog(m_parent, msg_text, _L("Parameter validation") + ": " + m_opt_id, wxYES | wxNO); if ((!infill_anchors || val > 100) && dialog.ShowModal() == wxID_YES) { set_value(from_u8((boost::format("%s%%") % stVal).str()), false/*true*/); str += "%%"; @@ -370,8 +373,7 @@ void Field::get_value_by_opt_type(wxString& str, const bool check_value/* = true if (!m_value.empty()) text_value = get_thumbnails_string(boost::any_cast<std::vector<Vec2d>>(m_value)); set_value(text_value, true); - show_error(m_parent, _L("Input value is out of range") - ); + show_error(m_parent, _L("Input value is out of range")); } else if (invalid_val) { wxString text_value; diff --git a/src/slic3r/GUI/MsgDialog.cpp b/src/slic3r/GUI/MsgDialog.cpp index d90f4de10..de4c7e00f 100644 --- a/src/slic3r/GUI/MsgDialog.cpp +++ b/src/slic3r/GUI/MsgDialog.cpp @@ -107,5 +107,55 @@ ErrorDialog::ErrorDialog(wxWindow *parent, const wxString &msg, bool monospaced_ Fit(); } +// WarningDialog + +WarningDialog::WarningDialog(wxWindow *parent, + const wxString& message, + const wxString& caption/* = wxEmptyString*/, + long style/* = wxOK*/) + : MsgDialog(parent, caption.IsEmpty() ? wxString::Format(_L("%s warning"), SLIC3R_APP_NAME) : caption, + wxString::Format(_L("%s has a warning")+":", SLIC3R_APP_NAME), wxID_NONE) + , msg(message) +{ + // Text shown as HTML, so that mouse selection and Ctrl-V to copy will work. + wxHtmlWindow* html = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO); + { + html->SetMinSize(wxSize(40 * wxGetApp().em_unit(), 10 * wxGetApp().em_unit())); + wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); + wxFont monospace = wxGetApp().code_font(); + wxColour text_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); + wxColour bgr_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); + auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue()); + auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue()); + const int font_size = font.GetPointSize(); + int size[] = {font_size, font_size, font_size, font_size, font_size, font_size, font_size}; + html->SetFonts(font.GetFaceName(), monospace.GetFaceName(), size); + html->SetBorders(2); + std::string msg_escaped = xml_escape(msg.ToUTF8().data()); + boost::replace_all(msg_escaped, "\r\n", "<br>"); + boost::replace_all(msg_escaped, "\n", "<br>"); + html->SetPage("<html><body bgcolor=\"" + bgr_clr_str + "\"><font color=\"" + text_clr_str + "\">" + wxString::FromUTF8(msg_escaped.data()) + "</font></body></html>"); + content_sizer->Add(html, 1, wxEXPAND|wxBOTTOM, BORDER); + } + + auto add_btn = [this](wxWindowID btn_id) { + auto* btn = new wxButton(this, btn_id); + btn_sizer->Add(btn, 0, wxRIGHT, HORIZ_SPACING); + btn->Bind(wxEVT_BUTTON, [this, btn_id](wxCommandEvent&) { this->EndModal(btn_id); }); + }; + + if (style & wxOK) + add_btn(wxID_OK); + if (style & wxYES) + add_btn(wxID_YES); + if (style & wxNO) + add_btn(wxID_NO); + + logo->SetBitmap(create_scaled_bitmap("PrusaSlicer_192px_grayscale.png", this, 150)); + + SetMaxSize(wxSize(-1, CONTENT_MAX_HEIGHT*wxGetApp().em_unit())); + Fit(); +} + } } diff --git a/src/slic3r/GUI/MsgDialog.hpp b/src/slic3r/GUI/MsgDialog.hpp index 70032089b..20d7f8dd5 100644 --- a/src/slic3r/GUI/MsgDialog.hpp +++ b/src/slic3r/GUI/MsgDialog.hpp @@ -66,6 +66,27 @@ private: }; +// Generic error dialog, used for displaying exceptions +class WarningDialog : public MsgDialog +{ +public: + // If monospaced_font is true, the error message is displayed using html <code><pre></pre></code> tags, + // so that the code formatting will be preserved. This is useful for reporting errors from the placeholder parser. + WarningDialog( wxWindow *parent, + const wxString& message, + const wxString& caption = wxEmptyString, + long style = wxOK); + WarningDialog(WarningDialog&&) = delete; + WarningDialog(const WarningDialog&) = delete; + WarningDialog &operator=(WarningDialog&&) = delete; + WarningDialog &operator=(const WarningDialog&) = delete; + virtual ~WarningDialog() = default; + +private: + wxString msg; +}; + + } }