From 0ec718a51022e35ba25131ec67300b02800b471d Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 7 Mar 2019 16:21:56 +0100 Subject: [PATCH 01/19] All wxComboBoxes are changed to the wxBitmapComboBoxes --- src/slic3r/GUI/Field.cpp | 44 ++++++++++++++++++++-------------------- src/slic3r/GUI/Field.hpp | 5 +++-- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index dc0550b3b..3ef482369 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -497,11 +497,11 @@ void Choice::BUILD() { if (m_opt.height >= 0) size.SetHeight(m_opt.height); if (m_opt.width >= 0) size.SetWidth(m_opt.width); - wxComboBox* temp; + wxBitmapComboBox* temp; if (!m_opt.gui_type.empty() && m_opt.gui_type.compare("select_open") != 0) - temp = new wxComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size); + temp = new wxBitmapComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size); else - temp = new wxComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, NULL, wxCB_READONLY); + temp = new wxBitmapComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxCB_READONLY); // recast as a wxWindow to fit the calling convention window = dynamic_cast(temp); @@ -511,7 +511,7 @@ void Choice::BUILD() { else{ for (auto el : m_opt.enum_labels.empty() ? m_opt.enum_values : m_opt.enum_labels) { const wxString& str = _(el);//m_opt_id == "support" ? _(el) : el; - temp->Append(str); + temp->Append(str, *m_undo_bitmap); } set_selection(); } @@ -523,7 +523,7 @@ void Choice::BUILD() { e.Skip(); if (m_opt.type == coStrings) return; double old_val = !m_value.empty() ? boost::any_cast(m_value) : -99999; - if (is_defined_input_value(window, m_opt.type)) { + if (is_defined_input_value(window, m_opt.type)) { if (fabs(old_val - boost::any_cast(get_value())) <= 0.0001) return; else @@ -554,13 +554,13 @@ void Choice::set_selection() } // if (m_opt.type == coPercent) text_value += "%"; idx == m_opt.enum_values.size() ? - dynamic_cast(window)->SetValue(text_value) : - dynamic_cast(window)->SetSelection(idx); + dynamic_cast(window)->SetValue(text_value) : + dynamic_cast(window)->SetSelection(idx); break; } case coEnum:{ int id_value = static_cast*>(m_opt.default_value)->value; //!! - dynamic_cast(window)->SetSelection(id_value); + dynamic_cast(window)->SetSelection(id_value); break; } case coInt:{ @@ -574,8 +574,8 @@ void Choice::set_selection() ++idx; } idx == m_opt.enum_values.size() ? - dynamic_cast(window)->SetValue(text_value) : - dynamic_cast(window)->SetSelection(idx); + dynamic_cast(window)->SetValue(text_value) : + dynamic_cast(window)->SetSelection(idx); break; } case coStrings:{ @@ -589,8 +589,8 @@ void Choice::set_selection() ++idx; } idx == m_opt.enum_values.size() ? - dynamic_cast(window)->SetValue(text_value) : - dynamic_cast(window)->SetSelection(idx); + dynamic_cast(window)->SetValue(text_value) : + dynamic_cast(window)->SetSelection(idx); break; } } @@ -609,8 +609,8 @@ void Choice::set_value(const std::string& value, bool change_event) //! Redunda } idx == m_opt.enum_values.size() ? - dynamic_cast(window)->SetValue(value) : - dynamic_cast(window)->SetSelection(idx); + dynamic_cast(window)->SetValue(value) : + dynamic_cast(window)->SetSelection(idx); m_disable_change_event = false; } @@ -640,11 +640,11 @@ void Choice::set_value(const boost::any& value, bool change_event) if (idx == m_opt.enum_values.size()) { // For editable Combobox under OSX is needed to set selection to -1 explicitly, // otherwise selection doesn't be changed - dynamic_cast(window)->SetSelection(-1); - dynamic_cast(window)->SetValue(text_value); + dynamic_cast(window)->SetSelection(-1); + dynamic_cast(window)->SetValue(text_value); } else - dynamic_cast(window)->SetSelection(idx); + dynamic_cast(window)->SetSelection(idx); break; } case coEnum: { @@ -674,7 +674,7 @@ void Choice::set_value(const boost::any& value, bool change_event) else val = 0; } - dynamic_cast(window)->SetSelection(val); + dynamic_cast(window)->SetSelection(val); break; } default: @@ -693,7 +693,7 @@ void Choice::set_values(const std::vector& values) // # it looks that Clear() also clears the text field in recent wxWidgets versions, // # but we want to preserve it - auto ww = dynamic_cast(window); + auto ww = dynamic_cast(window); auto value = ww->GetValue(); ww->Clear(); ww->Append(""); @@ -707,7 +707,7 @@ void Choice::set_values(const std::vector& values) boost::any& Choice::get_value() { // boost::any m_value; - wxString ret_str = static_cast(window)->GetValue(); + wxString ret_str = static_cast(window)->GetValue(); // options from right panel std::vector right_panel_options{ "support", "scale_unit" }; @@ -717,7 +717,7 @@ boost::any& Choice::get_value() if (m_opt.type == coEnum) { - int ret_enum = static_cast(window)->GetSelection(); + int ret_enum = static_cast(window)->GetSelection(); if (m_opt_id == "top_fill_pattern" || m_opt_id == "bottom_fill_pattern") { if (!m_opt.enum_values.empty()) { @@ -746,7 +746,7 @@ boost::any& Choice::get_value() m_value = static_cast(ret_enum); } else if (m_opt.gui_type == "f_enum_open") { - const int ret_enum = static_cast(window)->GetSelection(); + const int ret_enum = static_cast(window)->GetSelection(); if (ret_enum < 0 || m_opt.enum_values.empty() || m_opt.type == coStrings) // modifies ret_string! get_value_by_opt_type(ret_str); diff --git a/src/slic3r/GUI/Field.hpp b/src/slic3r/GUI/Field.hpp index 8391a111b..457807afa 100644 --- a/src/slic3r/GUI/Field.hpp +++ b/src/slic3r/GUI/Field.hpp @@ -11,6 +11,7 @@ #include #include +#include #include #include "libslic3r/libslic3r.h" @@ -357,8 +358,8 @@ public: void set_values(const std::vector &values); boost::any& get_value() override; - void enable() override { dynamic_cast(window)->Enable(); }; - void disable() override{ dynamic_cast(window)->Disable(); }; + void enable() override { dynamic_cast(window)->Enable(); }; + void disable() override{ dynamic_cast(window)->Disable(); }; wxWindow* getWindow() override { return window; } }; From 99e43d6b24dd344c87e6bb29493ff5981e1aa42b Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 7 Mar 2019 16:23:02 +0100 Subject: [PATCH 02/19] wxBitmapComboBoxes without bitmaps --- src/slic3r/GUI/Field.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 3ef482369..554350b68 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -511,7 +511,7 @@ void Choice::BUILD() { else{ for (auto el : m_opt.enum_labels.empty() ? m_opt.enum_values : m_opt.enum_labels) { const wxString& str = _(el);//m_opt_id == "support" ? _(el) : el; - temp->Append(str, *m_undo_bitmap); + temp->Append(str/*, *m_undo_bitmap*/); } set_selection(); } From b382ad1ffbc1bae64734fcc8e9b70befed5c03c2 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 7 Mar 2019 16:36:39 +0100 Subject: [PATCH 03/19] Some improvements --- resources/icons/empty_icon.png | Bin 0 -> 893 bytes src/slic3r/GUI/Field.cpp | 56 +++++++++++++++++++-------------- src/slic3r/GUI/Field.hpp | 5 +++ src/slic3r/GUI/GUI_App.cpp | 2 +- src/slic3r/GUI/Tab.cpp | 1 + src/slic3r/GUI/Tab.hpp | 3 ++ 6 files changed, 43 insertions(+), 24 deletions(-) create mode 100644 resources/icons/empty_icon.png diff --git a/resources/icons/empty_icon.png b/resources/icons/empty_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2dd8f0afe17e5cc48e754e2b9efe6c061f57ce79 GIT binary patch literal 893 zcmV-@1A_dCP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3sgj>IMmh5vJk9s%1Jo8v$LsW<5H`ykBB&g^!j zRt-uZjXU^C+rFS`JN17 zbVWSjz(YtPo_S>vj6jN1)Uuz(%VKELwy?<0+PyUT5bxRg&@R?vmv<>b%*P>rXmsqP zA9i`B;m;90GQWLj{*e2-c5`;0bKJA5DMP6o&ZHhw*)2FWNO`M~Q4F`DZMzf{#}qFR z>!8_Cu0VwtYEMeksnVpe>x(W7G4Wu?&CD0ewmIZ4d~GOc6`E|o(}OrjT%aZ}^K&e; z^Ol|OB1h&<@MJLbqte*go2)Px5ApwDyNt7~0V>Tk_=-^W^ za+bsm1W1)Tg$Xty8E~9eZuBwQzN~zkakK!0O2$_4wSfRDCB^!&IwZQP`# zrY$#X-b$+%md}+gz4B$3U*)QuyL4>-p1Xzaz4SV0U@46>bmU>fM;UcutxcI}>de!o z&ob+i8l7$XMvXqm{Z5SzwM8s#KYLMw+3XR5)^VbX8HjNr5Vu7D3z`?R=#&yKa*J6k zIHE)u)JPYcPKy`_ra`Qep6p)ae&rT4{VQ(#PvpWv_kWNJ3*902o!bx8dfk5%*?`tA zT$)CiIN0DYyt3EzPx`%{tvs4dl2XEt4N|QJ0`aQX?`hQS6}cV@jyW7d_ecG`#$KDf zguek`1h~~$RE)*|0007FOGiWi|A&vvzW@LL32;bRa{vG?BLDy{BLR4&KXw2B00(qQ zO+^Re0|yWd9@X?=y8r+HA4x<(R0!8&U_b>=7@0U3n0_-d{byuiVr2UI4^18bZ@L8Q Tk26l500000NkvXXu0mjfplzA> literal 0 HcmV?d00001 diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 554350b68..7cc533772 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -2,6 +2,7 @@ #include "GUI_App.hpp" #include "I18N.hpp" #include "Field.hpp" +#include "wxExtensions.hpp" #include "libslic3r/PrintConfig.hpp" @@ -493,13 +494,15 @@ void SpinCtrl::propagate_value() } void Choice::BUILD() { - auto size = wxSize(wxDefaultSize); + wxSize size(15 * wxGetApp().em_unit(), -1); if (m_opt.height >= 0) size.SetHeight(m_opt.height); if (m_opt.width >= 0) size.SetWidth(m_opt.width); wxBitmapComboBox* temp; - if (!m_opt.gui_type.empty() && m_opt.gui_type.compare("select_open") != 0) - temp = new wxBitmapComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size); + if (!m_opt.gui_type.empty() && m_opt.gui_type.compare("select_open") != 0) { + m_is_editable = true; + temp = new wxBitmapComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size); + } else temp = new wxBitmapComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxCB_READONLY); @@ -511,14 +514,14 @@ void Choice::BUILD() { else{ for (auto el : m_opt.enum_labels.empty() ? m_opt.enum_values : m_opt.enum_labels) { const wxString& str = _(el);//m_opt_id == "support" ? _(el) : el; - temp->Append(str/*, *m_undo_bitmap*/); + temp->Append(str, create_scaled_bitmap("empty_icon.png")); } set_selection(); } // temp->Bind(wxEVT_TEXT, ([this](wxCommandEvent e) { on_change_field(); }), temp->GetId()); temp->Bind(wxEVT_COMBOBOX, ([this](wxCommandEvent e) { on_change_field(); }), temp->GetId()); - if (temp->GetWindowStyle() != wxCB_READONLY) { + if (m_is_editable) { temp->Bind(wxEVT_KILL_FOCUS, ([this](wxEvent& e) { e.Skip(); if (m_opt.type == coStrings) return; @@ -540,6 +543,8 @@ void Choice::BUILD() { void Choice::set_selection() { wxString text_value = wxString(""); + + wxBitmapComboBox* field = dynamic_cast(window); switch (m_opt.type) { case coFloat: case coPercent: { @@ -554,13 +559,13 @@ void Choice::set_selection() } // if (m_opt.type == coPercent) text_value += "%"; idx == m_opt.enum_values.size() ? - dynamic_cast(window)->SetValue(text_value) : - dynamic_cast(window)->SetSelection(idx); + field->SetValue(text_value) : + field->SetSelection(idx); break; } case coEnum:{ int id_value = static_cast*>(m_opt.default_value)->value; //!! - dynamic_cast(window)->SetSelection(id_value); + field->SetSelection(id_value); break; } case coInt:{ @@ -574,8 +579,8 @@ void Choice::set_selection() ++idx; } idx == m_opt.enum_values.size() ? - dynamic_cast(window)->SetValue(text_value) : - dynamic_cast(window)->SetSelection(idx); + field->SetValue(text_value) : + field->SetSelection(idx); break; } case coStrings:{ @@ -589,8 +594,8 @@ void Choice::set_selection() ++idx; } idx == m_opt.enum_values.size() ? - dynamic_cast(window)->SetValue(text_value) : - dynamic_cast(window)->SetSelection(idx); + field->SetValue(text_value) : + field->SetSelection(idx); break; } } @@ -608,9 +613,10 @@ void Choice::set_value(const std::string& value, bool change_event) //! Redunda ++idx; } + wxBitmapComboBox* field = dynamic_cast(window); idx == m_opt.enum_values.size() ? - dynamic_cast(window)->SetValue(value) : - dynamic_cast(window)->SetSelection(idx); + field->SetValue(value) : + field->SetSelection(idx); m_disable_change_event = false; } @@ -619,6 +625,8 @@ void Choice::set_value(const boost::any& value, bool change_event) { m_disable_change_event = !change_event; + wxBitmapComboBox* field = dynamic_cast(window); + switch (m_opt.type) { case coInt: case coFloat: @@ -640,11 +648,11 @@ void Choice::set_value(const boost::any& value, bool change_event) if (idx == m_opt.enum_values.size()) { // For editable Combobox under OSX is needed to set selection to -1 explicitly, // otherwise selection doesn't be changed - dynamic_cast(window)->SetSelection(-1); - dynamic_cast(window)->SetValue(text_value); + field->SetSelection(-1); + field->SetValue(text_value); } else - dynamic_cast(window)->SetSelection(idx); + field->SetSelection(idx); break; } case coEnum: { @@ -674,7 +682,7 @@ void Choice::set_value(const boost::any& value, bool change_event) else val = 0; } - dynamic_cast(window)->SetSelection(val); + field->SetSelection(val); break; } default: @@ -706,8 +714,9 @@ void Choice::set_values(const std::vector& values) boost::any& Choice::get_value() { -// boost::any m_value; - wxString ret_str = static_cast(window)->GetValue(); + wxBitmapComboBox* field = dynamic_cast(window); + + wxString ret_str = field->GetValue(); // options from right panel std::vector right_panel_options{ "support", "scale_unit" }; @@ -717,7 +726,7 @@ boost::any& Choice::get_value() if (m_opt.type == coEnum) { - int ret_enum = static_cast(window)->GetSelection(); + int ret_enum = field->GetSelection(); if (m_opt_id == "top_fill_pattern" || m_opt_id == "bottom_fill_pattern") { if (!m_opt.enum_values.empty()) { @@ -746,8 +755,9 @@ boost::any& Choice::get_value() m_value = static_cast(ret_enum); } else if (m_opt.gui_type == "f_enum_open") { - const int ret_enum = static_cast(window)->GetSelection(); - if (ret_enum < 0 || m_opt.enum_values.empty() || m_opt.type == coStrings) + const int ret_enum = field->GetSelection(); + if (ret_enum < 0 || m_opt.enum_values.empty() || m_opt.type == coStrings || + ret_str != m_opt.enum_values[ret_enum] && ret_str != m_opt.enum_labels[ret_enum] ) // modifies ret_string! get_value_by_opt_type(ret_str); else diff --git a/src/slic3r/GUI/Field.hpp b/src/slic3r/GUI/Field.hpp index 457807afa..128d60d47 100644 --- a/src/slic3r/GUI/Field.hpp +++ b/src/slic3r/GUI/Field.hpp @@ -352,6 +352,11 @@ public: wxWindow* window{ nullptr }; void BUILD() override; + /* Under OSX: wxBitmapComboBox->GetWindowStyle() returns some weard value, + * so let use a flag, which has TRUE value for a control without wxCB_READONLY style + */ + bool m_is_editable { false }; + void set_selection(); void set_value(const std::string& value, bool change_event = false); void set_value(const boost::any& value, bool change_event = false); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 7a3d6f13a..b61457226 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -506,7 +506,7 @@ Tab* GUI_App::get_tab(Preset::Type type) { for (Tab* tab: tabs_list) if (tab->type() == type) - return tab; + return tab->complited() ? tab : nullptr; // To avoid actions with no-completed Tab return nullptr; } diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 060eb1383..b3580a285 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -257,6 +257,7 @@ void Tab::create_preset_tab() // Initialize the DynamicPrintConfig by default keys/values. build(); rebuild_page_tree(); + m_complited = true; } void Tab::load_initial_data() diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 7ef066963..2f8cec1de 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -204,6 +204,8 @@ protected: void set_type(); int m_em_unit; + // To avoid actions with no-completed Tab + bool m_complited { false }; public: PresetBundle* m_preset_bundle; @@ -226,6 +228,7 @@ public: wxString title() const { return m_title; } std::string name() const { return m_name; } Preset::Type type() const { return m_type; } + bool complited() const { return m_complited; } virtual bool supports_printer_technology(const PrinterTechnology tech) = 0; void create_preset_tab(); From 2f9e6cf887fcaa57351c9415ea94a75b697b9a88 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Mon, 18 Mar 2019 12:48:39 +0100 Subject: [PATCH 04/19] Moved the Fileds from the Page object to the respective OptionGroups for performance reasons. Disabled clearing of background for most of the static texts and Fields stored into OptionGrops. --- src/slic3r/GUI/Field.cpp | 21 ++++++++++- src/slic3r/GUI/GUI_App.cpp | 3 ++ src/slic3r/GUI/OptionsGroup.cpp | 45 ++++++++++++---------- src/slic3r/GUI/OptionsGroup.hpp | 8 +++- src/slic3r/GUI/Tab.cpp | 66 +++++++++++++++++++++------------ src/slic3r/GUI/Tab.hpp | 3 ++ 6 files changed, 99 insertions(+), 47 deletions(-) diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index dc0550b3b..c9eb9282e 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -36,7 +36,9 @@ void Field::PostInitialize() m_Undo_to_sys_btn = new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); if (wxMSW) { m_Undo_btn->SetBackgroundColour(color); + m_Undo_btn->SetBackgroundStyle(wxBG_STYLE_PAINT); m_Undo_to_sys_btn->SetBackgroundColour(color); + m_Undo_to_sys_btn->SetBackgroundStyle(wxBG_STYLE_PAINT); } m_Undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_initial_value(); })); m_Undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_sys_value(); })); @@ -257,6 +259,7 @@ void TextCtrl::BUILD() { const long style = m_opt.multiline ? wxTE_MULTILINE : wxTE_PROCESS_ENTER/*0*/; auto temp = new wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, style); + temp->SetBackgroundStyle(wxBG_STYLE_PAINT); #ifdef __WXOSX__ temp->OSXDisableAllSmartSubstitutions(); #endif // __WXOSX__ @@ -372,6 +375,7 @@ void CheckBox::BUILD() { false; auto temp = new wxCheckBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size); + temp->SetBackgroundStyle(wxBG_STYLE_PAINT); temp->SetValue(check_value); if (m_opt.readonly) temp->Disable(); @@ -429,6 +433,7 @@ void SpinCtrl::BUILD() { auto temp = new wxSpinCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, 0|wxTE_PROCESS_ENTER, min_val, max_val, default_value); + temp->SetBackgroundStyle(wxBG_STYLE_PAINT); #ifndef __WXOSX__ // #ys_FIXME_KILL_FOCUS @@ -502,6 +507,7 @@ void Choice::BUILD() { temp = new wxComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size); else temp = new wxComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, NULL, wxCB_READONLY); + temp->SetBackgroundStyle(wxBG_STYLE_PAINT); // recast as a wxWindow to fit the calling convention window = dynamic_cast(temp); @@ -774,6 +780,7 @@ void ColourPicker::BUILD() } auto temp = new wxColourPickerCtrl(m_parent, wxID_ANY, clr, wxDefaultPosition, size); + temp->SetBackgroundStyle(wxBG_STYLE_PAINT); // // recast as a wxWindow to fit the calling convention window = dynamic_cast(temp); @@ -808,10 +815,17 @@ void PointCtrl::BUILD() x_textctrl = new wxTextCtrl(m_parent, wxID_ANY, X, wxDefaultPosition, field_size, wxTE_PROCESS_ENTER); y_textctrl = new wxTextCtrl(m_parent, wxID_ANY, Y, wxDefaultPosition, field_size, wxTE_PROCESS_ENTER); + x_textctrl->SetBackgroundStyle(wxBG_STYLE_PAINT); + y_textctrl->SetBackgroundStyle(wxBG_STYLE_PAINT); - temp->Add(new wxStaticText(m_parent, wxID_ANY, "x : "), 0, wxALIGN_CENTER_VERTICAL, 0); + auto static_text_x = new wxStaticText(m_parent, wxID_ANY, "x : "); + auto static_text_y = new wxStaticText(m_parent, wxID_ANY, " y : "); + static_text_x->SetBackgroundStyle(wxBG_STYLE_PAINT); + static_text_y->SetBackgroundStyle(wxBG_STYLE_PAINT); + + temp->Add(static_text_x, 0, wxALIGN_CENTER_VERTICAL, 0); temp->Add(x_textctrl); - temp->Add(new wxStaticText(m_parent, wxID_ANY, " y : "), 0, wxALIGN_CENTER_VERTICAL, 0); + temp->Add(static_text_y, 0, wxALIGN_CENTER_VERTICAL, 0); temp->Add(y_textctrl); // x_textctrl->Bind(wxEVT_TEXT, ([this](wxCommandEvent e) { on_change_field(); }), x_textctrl->GetId()); @@ -880,6 +894,7 @@ void StaticText::BUILD() const wxString legend(static_cast(m_opt.default_value)->value); auto temp = new wxStaticText(m_parent, wxID_ANY, legend, wxDefaultPosition, size, wxST_ELLIPSIZE_MIDDLE); + temp->SetBackgroundStyle(wxBG_STYLE_PAINT); temp->SetFont(wxGetApp().bold_font()); // // recast as a wxWindow to fit the calling convention @@ -903,10 +918,12 @@ void SliderCtrl::BUILD() m_slider = new wxSlider(m_parent, wxID_ANY, def_val * m_scale, min * m_scale, max * m_scale, wxDefaultPosition, size); + m_slider->SetBackgroundStyle(wxBG_STYLE_PAINT); wxSize field_size(40, -1); m_textctrl = new wxTextCtrl(m_parent, wxID_ANY, wxString::Format("%d", m_slider->GetValue()/m_scale), wxDefaultPosition, field_size); + m_textctrl->SetBackgroundStyle(wxBG_STYLE_PAINT); temp->Add(m_slider, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL, 0); temp->Add(m_textctrl, 0, wxALIGN_CENTER_VERTICAL, 0); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 7d448fbe4..79ad70e5a 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include "libslic3r/Utils.hpp" #include "libslic3r/Model.hpp" @@ -98,6 +99,8 @@ bool GUI_App::OnInit() SetAppName("Slic3rPE-alpha"); SetAppDisplayName("Slic3r Prusa Edition"); +// wxSystemOptions::SetOption("msw.staticbox.optimized-paint", 0); + // Slic3r::debugf "wxWidgets version %s, Wx version %s\n", wxVERSION_STRING, wxVERSION; // Set the Slic3r data directory at the Slic3r XS module. diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 0e9fcd75e..5e9c9ac30 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -23,18 +23,18 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co // is the normal type. if (opt.gui_type.compare("select") == 0) { } else if (opt.gui_type.compare("select_open") == 0) { - m_fields.emplace(id, std::move(Choice::Create(parent(), opt, id))); + m_fields.emplace(id, std::move(Choice::Create(this->ctrl_parent(), opt, id))); } else if (opt.gui_type.compare("color") == 0) { - m_fields.emplace(id, std::move(ColourPicker::Create(parent(), opt, id))); + m_fields.emplace(id, std::move(ColourPicker::Create(this->ctrl_parent(), opt, id))); } else if (opt.gui_type.compare("f_enum_open") == 0 || opt.gui_type.compare("i_enum_open") == 0 || opt.gui_type.compare("i_enum_closed") == 0) { - m_fields.emplace(id, std::move(Choice::Create(parent(), opt, id))); + m_fields.emplace(id, std::move(Choice::Create(this->ctrl_parent(), opt, id))); } else if (opt.gui_type.compare("slider") == 0) { - m_fields.emplace(id, std::move(SliderCtrl::Create(parent(), opt, id))); + m_fields.emplace(id, std::move(SliderCtrl::Create(this->ctrl_parent(), opt, id))); } else if (opt.gui_type.compare("i_spin") == 0) { // Spinctrl } else if (opt.gui_type.compare("legend") == 0) { // StaticText - m_fields.emplace(id, std::move(StaticText::Create(parent(), opt, id))); + m_fields.emplace(id, std::move(StaticText::Create(this->ctrl_parent(), opt, id))); } else { switch (opt.type) { case coFloatOrPercent: @@ -44,21 +44,21 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co case coPercents: case coString: case coStrings: - m_fields.emplace(id, std::move(TextCtrl::Create(parent(), opt, id))); + m_fields.emplace(id, std::move(TextCtrl::Create(this->ctrl_parent(), opt, id))); break; case coBool: case coBools: - m_fields.emplace(id, std::move(CheckBox::Create(parent(), opt, id))); + m_fields.emplace(id, std::move(CheckBox::Create(this->ctrl_parent(), opt, id))); break; case coInt: case coInts: - m_fields.emplace(id, std::move(SpinCtrl::Create(parent(), opt, id))); + m_fields.emplace(id, std::move(SpinCtrl::Create(this->ctrl_parent(), opt, id))); break; case coEnum: - m_fields.emplace(id, std::move(Choice::Create(parent(), opt, id))); + m_fields.emplace(id, std::move(Choice::Create(this->ctrl_parent(), opt, id))); break; case coPoints: - m_fields.emplace(id, std::move(PointCtrl::Create(parent(), opt, id))); + m_fields.emplace(id, std::move(PointCtrl::Create(this->ctrl_parent(), opt, id))); break; case coNone: break; default: @@ -119,7 +119,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n return; } if (line.widget != nullptr) { - sizer->Add(line.widget(m_parent), 0, wxEXPAND | wxALL, wxOSX ? 0 : 15); + sizer->Add(line.widget(this->ctrl_parent()), 0, wxEXPAND | wxALL, wxOSX ? 0 : 15); return; } } @@ -167,7 +167,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n // if we have an extra column, build it if (extra_column) - grid_sizer->Add(extra_column(parent(), line), 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3); + grid_sizer->Add(extra_column(this->ctrl_parent(), line), 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3); // Build a label if we have it wxStaticText* label=nullptr; @@ -179,18 +179,21 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n // Text is properly aligned only when Ellipsize is checked. label_style |= staticbox ? 0 : wxST_ELLIPSIZE_END; #endif /* __WXGTK__ */ - label = new wxStaticText(parent(), wxID_ANY, line.label + (line.label.IsEmpty() ? "" : ": "), + label = new wxStaticText(this->ctrl_parent(), wxID_ANY, line.label + (line.label.IsEmpty() ? "" : ": "), wxDefaultPosition, wxSize(label_width, -1), label_style); + label->SetBackgroundStyle(wxBG_STYLE_PAINT); label->SetFont(label_font); label->Wrap(label_width); // avoid a Linux/GTK bug if (!line.near_label_widget) grid_sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, line.label.IsEmpty() ? 0 : 5); + else if (line.near_label_widget && line.label.IsEmpty()) + grid_sizer->Add(line.near_label_widget(this->ctrl_parent()), 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 7); else { // If we're here, we have some widget near the label // so we need a horizontal sizer to arrange these things auto sizer = new wxBoxSizer(wxHORIZONTAL); grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM | wxTOP | wxLEFT), staticbox ? 0 : 1); - sizer->Add(line.near_label_widget(parent()), 0, wxRIGHT, 7); + sizer->Add(line.near_label_widget(this->ctrl_parent()), 0, wxRIGHT, 7); sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, 5); } if (line.label_tooltip.compare("") != 0) @@ -201,7 +204,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n *full_Label = label; // Initiate the pointer to the control of the full label, if we need this one. // If there's a widget, build it and add the result to the sizer. if (line.widget != nullptr) { - auto wgt = line.widget(parent()); + auto wgt = line.widget(this->ctrl_parent()); // If widget doesn't have label, don't use border grid_sizer->Add(wgt, 0, wxEXPAND | wxBOTTOM | wxTOP, (wxOSX || line.label.IsEmpty()) ? 0 : 5); return; @@ -237,7 +240,8 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n wxString str_label = (option.label == "Top" || option.label == "Bottom") ? _CTX(option.label, "Layers") : _(option.label); - label = new wxStaticText(parent(), wxID_ANY, str_label + ": ", wxDefaultPosition, wxDefaultSize); + label = new wxStaticText(this->ctrl_parent(), wxID_ANY, str_label + ": ", wxDefaultPosition, wxDefaultSize); + label->SetBackgroundStyle(wxBG_STYLE_PAINT); label->SetFont(label_font); sizer_tmp->Add(label, 0, /*wxALIGN_RIGHT |*/ wxALIGN_CENTER_VERTICAL, 0); } @@ -262,8 +266,9 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n // add sidetext if any if (option.sidetext != "") { - auto sidetext = new wxStaticText( parent(), wxID_ANY, _(option.sidetext), wxDefaultPosition, + auto sidetext = new wxStaticText( this->ctrl_parent(), wxID_ANY, _(option.sidetext), wxDefaultPosition, wxSize(sidetext_width, -1)/*wxDefaultSize*/, wxALIGN_LEFT); + sidetext->SetBackgroundStyle(wxBG_STYLE_PAINT); sidetext->SetFont(sidetext_font); sizer_tmp->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4); field->set_side_text_ptr(sidetext); @@ -271,7 +276,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n // add side widget if any if (opt.side_widget != nullptr) { - sizer_tmp->Add(opt.side_widget(parent())/*!.target()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 1); //! requires verification + sizer_tmp->Add(opt.side_widget(this->ctrl_parent())/*!.target()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 1); //! requires verification } if (opt.opt_id != option_set.back().opt_id) //! istead of (opt != option_set.back()) @@ -287,11 +292,11 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n // extra widget for non-staticbox option group (like for the frequently used parameters on the sidebar) should be wxALIGN_RIGHT const auto v_sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(v_sizer, 1, wxEXPAND); - v_sizer->Add(extra_widget(parent()), 0, wxALIGN_RIGHT); + v_sizer->Add(extra_widget(this->ctrl_parent()), 0, wxALIGN_RIGHT); return; } - sizer->Add(extra_widget(parent())/*!.target()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4); //! requires verification + sizer->Add(extra_widget(this->ctrl_parent())/*!.target()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4); //! requires verification } } diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp index d9ff6a01a..661aadbd7 100644 --- a/src/slic3r/GUI/OptionsGroup.hpp +++ b/src/slic3r/GUI/OptionsGroup.hpp @@ -112,6 +112,10 @@ public: } #endif /* __WXGTK__ */ + wxWindow* ctrl_parent() const { + return this->stb ? (wxWindow*)this->stb : this->parent(); + } + void append_line(const Line& line, wxStaticText** full_Label = nullptr); Line create_single_option_line(const Option& option) const; void append_single_option_line(const Option& option) { append_line(create_single_option_line(option)); } @@ -161,8 +165,10 @@ public: staticbox(title!=""), extra_column(extra_clmn) { if (staticbox) { stb = new wxStaticBox(_parent, wxID_ANY, title); + stb->SetBackgroundStyle(wxBG_STYLE_PAINT); stb->SetFont(wxGetApp().bold_font()); - } + } else + stb = nullptr; sizer = (staticbox ? new wxStaticBoxSizer(stb, wxVERTICAL) : new wxBoxSizer(wxVERTICAL)); auto num_columns = 1U; if (label_width != 0) num_columns++; diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index ae33443c3..faee25270 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -58,6 +58,13 @@ Tab::Tab(wxNotebook* parent, const wxString& title, const char* name) : wxGetApp().tabs_list.push_back(this); m_em_unit = wxGetApp().em_unit(); + + Bind(wxEVT_SIZE, ([this](wxSizeEvent &evt) { + for (auto page : m_pages) + if (! page.get()->IsShown()) + page->layout_valid = false; + evt.Skip(); + })); } void Tab::set_type() @@ -74,7 +81,7 @@ void Tab::set_type() void Tab::create_preset_tab() { #ifdef __WINDOWS__ -// SetDoubleBuffered(true); + SetDoubleBuffered(true); #endif //__WINDOWS__ m_preset_bundle = wxGetApp().preset_bundle; @@ -293,6 +300,11 @@ Slic3r::GUI::PageShp Tab::add_options_page(const wxString& title, const std::str auto panel = this; #endif PageShp page(new Page(panel, title, icon_idx)); +// page->SetBackgroundStyle(wxBG_STYLE_SYSTEM); +#ifdef __WINDOWS__ +// page->SetDoubleBuffered(true); +#endif //__WINDOWS__ + page->SetScrollbars(1, 20, 1, 2); page->Hide(); m_hsizer->Add(page.get(), 1, wxEXPAND | wxLEFT, 5); @@ -318,7 +330,7 @@ void Tab::OnActivate() void Tab::update_labels_colour() { - Freeze(); +// Freeze(); //update options "decoration" for (const auto opt : m_options_list) { @@ -345,7 +357,7 @@ void Tab::update_labels_colour() if (field == nullptr) continue; field->set_label_colour_force(color); } - Thaw(); +// Thaw(); auto cur_item = m_treectrl->GetFirstVisibleItem(); while (cur_item) { @@ -389,7 +401,7 @@ void Tab::update_changed_ui() for (auto opt_key : dirty_options) m_options_list[opt_key] &= ~osInitValue; for (auto opt_key : nonsys_options) m_options_list[opt_key] &= ~osSystemValue; - Freeze(); +// Freeze(); //update options "decoration" for (const auto opt : m_options_list) { @@ -439,7 +451,7 @@ void Tab::update_changed_ui() field->set_undo_to_sys_tooltip(sys_tt); field->set_label_colour(color); } - Thaw(); +// Thaw(); wxTheApp->CallAfter([this]() { update_changed_tree_ui(); @@ -686,16 +698,16 @@ void Tab::load_config(const DynamicPrintConfig& config) // Reload current $self->{config} (aka $self->{presets}->edited_preset->config) into the UI fields. void Tab::reload_config() { - Freeze(); +// Freeze(); for (auto page : m_pages) page->reload_config(); - Thaw(); +// Thaw(); } void Tab::update_visibility() { const ConfigOptionMode mode = wxGetApp().get_mode(); - Freeze(); +// Freeze(); for (auto page : m_pages) page->update_visibility(mode); @@ -705,7 +717,7 @@ void Tab::update_visibility() m_mode_sizer->SetMode(mode); Layout(); - Thaw(); +// Thaw(); // to update tree items color // wxTheApp->CallAfter([this]() { @@ -1180,7 +1192,7 @@ void TabPrint::update() // return; // ! TODO Let delete this part of code after a common aplication testing m_update_cnt++; - Freeze(); +// Freeze(); double fill_density = m_config->option("fill_density")->value; @@ -1391,7 +1403,7 @@ void TabPrint::update() m_recommended_thin_wall_thickness_description_line->SetText( from_u8(PresetHints::recommended_thin_wall_thickness(*m_preset_bundle))); - Thaw(); +// Thaw(); m_update_cnt--; if (m_update_cnt==0) @@ -1566,7 +1578,7 @@ void TabFilament::update() return; // ys_FIXME m_update_cnt++; - Freeze(); +// Freeze(); wxString text = from_u8(PresetHints::cooling_description(m_presets->get_edited_preset())); m_cooling_description_line->SetText(text); text = from_u8(PresetHints::maximum_volumetric_flow_description(*m_preset_bundle)); @@ -1580,7 +1592,7 @@ void TabFilament::update() for (auto el : { "min_fan_speed", "disable_fan_first_layers" }) get_field(el)->toggle(fan_always_on); - Thaw(); +// Thaw(); m_update_cnt--; if (m_update_cnt == 0) @@ -2261,7 +2273,7 @@ void TabPrinter::update() void TabPrinter::update_fff() { - Freeze(); +// Freeze(); bool en; auto serial_speed = get_field("serial_speed"); @@ -2360,7 +2372,7 @@ void TabPrinter::update_fff() (have_multiple_extruders && toolchange_retraction); } - Thaw(); +// Thaw(); } void TabPrinter::update_sla() @@ -2674,7 +2686,7 @@ void Tab::OnTreeSelChange(wxTreeEvent& event) #ifdef __linux__ std::unique_ptr no_updates(new wxWindowUpdateLocker(this)); #else - wxWindowUpdateLocker noUpdates(this); +// wxWindowUpdateLocker noUpdates(this); #endif if (m_pages.empty()) @@ -2694,17 +2706,22 @@ void Tab::OnTreeSelChange(wxTreeEvent& event) if (page == nullptr) return; for (auto& el : m_pages) - el.get()->Hide(); +// if (el.get()->IsShown()) { + el.get()->Hide(); +// break; +// } -#ifdef __linux__ - no_updates.reset(nullptr); -#endif - - page->Show(); - m_hsizer->Layout(); - Refresh(); + #ifdef __linux__ + no_updates.reset(nullptr); + #endif update_undo_buttons(); + page->Show(); +// if (! page->layout_valid) { + page->layout_valid = true; + m_hsizer->Layout(); + Refresh(); +// } } void Tab::OnKeyDown(wxKeyEvent& event) @@ -3040,6 +3057,7 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la } // auto bmp = new wxStaticBitmap(parent, wxID_ANY, bmp_name.empty() ? wxNullBitmap : wxBitmap(from_u8(var(bmp_name)), wxBITMAP_TYPE_PNG)); auto bmp = new wxStaticBitmap(parent, wxID_ANY, bmp_name.empty() ? wxNullBitmap : create_scaled_bitmap(bmp_name)); + bmp->SetBackgroundStyle(wxBG_STYLE_PAINT); return bmp; }; diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 7ef066963..5f8a7f706 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -65,6 +65,9 @@ public: bool m_is_modified_values{ false }; bool m_is_nonsys_values{ true }; + // Delayed layout after resizing the main window. + bool layout_valid = false; + public: std::vector m_optgroups; DynamicPrintConfig* m_config; From cf53604ae8899c3165d7d819979c981281505bff Mon Sep 17 00:00:00 2001 From: bubnikv Date: Mon, 18 Mar 2019 12:48:39 +0100 Subject: [PATCH 05/19] Moved the Fileds from the Page object to the respective OptionGroups for performance reasons. Disabled clearing of background for most of the static texts and Fields stored into OptionGrops. --- src/slic3r/GUI/Field.cpp | 21 ++++++++++- src/slic3r/GUI/GUI_App.cpp | 3 ++ src/slic3r/GUI/OptionsGroup.cpp | 45 ++++++++++++---------- src/slic3r/GUI/OptionsGroup.hpp | 8 +++- src/slic3r/GUI/Tab.cpp | 66 +++++++++++++++++++++------------ src/slic3r/GUI/Tab.hpp | 3 ++ 6 files changed, 99 insertions(+), 47 deletions(-) diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index dc0550b3b..c9eb9282e 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -36,7 +36,9 @@ void Field::PostInitialize() m_Undo_to_sys_btn = new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); if (wxMSW) { m_Undo_btn->SetBackgroundColour(color); + m_Undo_btn->SetBackgroundStyle(wxBG_STYLE_PAINT); m_Undo_to_sys_btn->SetBackgroundColour(color); + m_Undo_to_sys_btn->SetBackgroundStyle(wxBG_STYLE_PAINT); } m_Undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_initial_value(); })); m_Undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_sys_value(); })); @@ -257,6 +259,7 @@ void TextCtrl::BUILD() { const long style = m_opt.multiline ? wxTE_MULTILINE : wxTE_PROCESS_ENTER/*0*/; auto temp = new wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, style); + temp->SetBackgroundStyle(wxBG_STYLE_PAINT); #ifdef __WXOSX__ temp->OSXDisableAllSmartSubstitutions(); #endif // __WXOSX__ @@ -372,6 +375,7 @@ void CheckBox::BUILD() { false; auto temp = new wxCheckBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size); + temp->SetBackgroundStyle(wxBG_STYLE_PAINT); temp->SetValue(check_value); if (m_opt.readonly) temp->Disable(); @@ -429,6 +433,7 @@ void SpinCtrl::BUILD() { auto temp = new wxSpinCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, 0|wxTE_PROCESS_ENTER, min_val, max_val, default_value); + temp->SetBackgroundStyle(wxBG_STYLE_PAINT); #ifndef __WXOSX__ // #ys_FIXME_KILL_FOCUS @@ -502,6 +507,7 @@ void Choice::BUILD() { temp = new wxComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size); else temp = new wxComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, NULL, wxCB_READONLY); + temp->SetBackgroundStyle(wxBG_STYLE_PAINT); // recast as a wxWindow to fit the calling convention window = dynamic_cast(temp); @@ -774,6 +780,7 @@ void ColourPicker::BUILD() } auto temp = new wxColourPickerCtrl(m_parent, wxID_ANY, clr, wxDefaultPosition, size); + temp->SetBackgroundStyle(wxBG_STYLE_PAINT); // // recast as a wxWindow to fit the calling convention window = dynamic_cast(temp); @@ -808,10 +815,17 @@ void PointCtrl::BUILD() x_textctrl = new wxTextCtrl(m_parent, wxID_ANY, X, wxDefaultPosition, field_size, wxTE_PROCESS_ENTER); y_textctrl = new wxTextCtrl(m_parent, wxID_ANY, Y, wxDefaultPosition, field_size, wxTE_PROCESS_ENTER); + x_textctrl->SetBackgroundStyle(wxBG_STYLE_PAINT); + y_textctrl->SetBackgroundStyle(wxBG_STYLE_PAINT); - temp->Add(new wxStaticText(m_parent, wxID_ANY, "x : "), 0, wxALIGN_CENTER_VERTICAL, 0); + auto static_text_x = new wxStaticText(m_parent, wxID_ANY, "x : "); + auto static_text_y = new wxStaticText(m_parent, wxID_ANY, " y : "); + static_text_x->SetBackgroundStyle(wxBG_STYLE_PAINT); + static_text_y->SetBackgroundStyle(wxBG_STYLE_PAINT); + + temp->Add(static_text_x, 0, wxALIGN_CENTER_VERTICAL, 0); temp->Add(x_textctrl); - temp->Add(new wxStaticText(m_parent, wxID_ANY, " y : "), 0, wxALIGN_CENTER_VERTICAL, 0); + temp->Add(static_text_y, 0, wxALIGN_CENTER_VERTICAL, 0); temp->Add(y_textctrl); // x_textctrl->Bind(wxEVT_TEXT, ([this](wxCommandEvent e) { on_change_field(); }), x_textctrl->GetId()); @@ -880,6 +894,7 @@ void StaticText::BUILD() const wxString legend(static_cast(m_opt.default_value)->value); auto temp = new wxStaticText(m_parent, wxID_ANY, legend, wxDefaultPosition, size, wxST_ELLIPSIZE_MIDDLE); + temp->SetBackgroundStyle(wxBG_STYLE_PAINT); temp->SetFont(wxGetApp().bold_font()); // // recast as a wxWindow to fit the calling convention @@ -903,10 +918,12 @@ void SliderCtrl::BUILD() m_slider = new wxSlider(m_parent, wxID_ANY, def_val * m_scale, min * m_scale, max * m_scale, wxDefaultPosition, size); + m_slider->SetBackgroundStyle(wxBG_STYLE_PAINT); wxSize field_size(40, -1); m_textctrl = new wxTextCtrl(m_parent, wxID_ANY, wxString::Format("%d", m_slider->GetValue()/m_scale), wxDefaultPosition, field_size); + m_textctrl->SetBackgroundStyle(wxBG_STYLE_PAINT); temp->Add(m_slider, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL, 0); temp->Add(m_textctrl, 0, wxALIGN_CENTER_VERTICAL, 0); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 7d448fbe4..79ad70e5a 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include "libslic3r/Utils.hpp" #include "libslic3r/Model.hpp" @@ -98,6 +99,8 @@ bool GUI_App::OnInit() SetAppName("Slic3rPE-alpha"); SetAppDisplayName("Slic3r Prusa Edition"); +// wxSystemOptions::SetOption("msw.staticbox.optimized-paint", 0); + // Slic3r::debugf "wxWidgets version %s, Wx version %s\n", wxVERSION_STRING, wxVERSION; // Set the Slic3r data directory at the Slic3r XS module. diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 0e9fcd75e..5e9c9ac30 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -23,18 +23,18 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co // is the normal type. if (opt.gui_type.compare("select") == 0) { } else if (opt.gui_type.compare("select_open") == 0) { - m_fields.emplace(id, std::move(Choice::Create(parent(), opt, id))); + m_fields.emplace(id, std::move(Choice::Create(this->ctrl_parent(), opt, id))); } else if (opt.gui_type.compare("color") == 0) { - m_fields.emplace(id, std::move(ColourPicker::Create(parent(), opt, id))); + m_fields.emplace(id, std::move(ColourPicker::Create(this->ctrl_parent(), opt, id))); } else if (opt.gui_type.compare("f_enum_open") == 0 || opt.gui_type.compare("i_enum_open") == 0 || opt.gui_type.compare("i_enum_closed") == 0) { - m_fields.emplace(id, std::move(Choice::Create(parent(), opt, id))); + m_fields.emplace(id, std::move(Choice::Create(this->ctrl_parent(), opt, id))); } else if (opt.gui_type.compare("slider") == 0) { - m_fields.emplace(id, std::move(SliderCtrl::Create(parent(), opt, id))); + m_fields.emplace(id, std::move(SliderCtrl::Create(this->ctrl_parent(), opt, id))); } else if (opt.gui_type.compare("i_spin") == 0) { // Spinctrl } else if (opt.gui_type.compare("legend") == 0) { // StaticText - m_fields.emplace(id, std::move(StaticText::Create(parent(), opt, id))); + m_fields.emplace(id, std::move(StaticText::Create(this->ctrl_parent(), opt, id))); } else { switch (opt.type) { case coFloatOrPercent: @@ -44,21 +44,21 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co case coPercents: case coString: case coStrings: - m_fields.emplace(id, std::move(TextCtrl::Create(parent(), opt, id))); + m_fields.emplace(id, std::move(TextCtrl::Create(this->ctrl_parent(), opt, id))); break; case coBool: case coBools: - m_fields.emplace(id, std::move(CheckBox::Create(parent(), opt, id))); + m_fields.emplace(id, std::move(CheckBox::Create(this->ctrl_parent(), opt, id))); break; case coInt: case coInts: - m_fields.emplace(id, std::move(SpinCtrl::Create(parent(), opt, id))); + m_fields.emplace(id, std::move(SpinCtrl::Create(this->ctrl_parent(), opt, id))); break; case coEnum: - m_fields.emplace(id, std::move(Choice::Create(parent(), opt, id))); + m_fields.emplace(id, std::move(Choice::Create(this->ctrl_parent(), opt, id))); break; case coPoints: - m_fields.emplace(id, std::move(PointCtrl::Create(parent(), opt, id))); + m_fields.emplace(id, std::move(PointCtrl::Create(this->ctrl_parent(), opt, id))); break; case coNone: break; default: @@ -119,7 +119,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n return; } if (line.widget != nullptr) { - sizer->Add(line.widget(m_parent), 0, wxEXPAND | wxALL, wxOSX ? 0 : 15); + sizer->Add(line.widget(this->ctrl_parent()), 0, wxEXPAND | wxALL, wxOSX ? 0 : 15); return; } } @@ -167,7 +167,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n // if we have an extra column, build it if (extra_column) - grid_sizer->Add(extra_column(parent(), line), 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3); + grid_sizer->Add(extra_column(this->ctrl_parent(), line), 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3); // Build a label if we have it wxStaticText* label=nullptr; @@ -179,18 +179,21 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n // Text is properly aligned only when Ellipsize is checked. label_style |= staticbox ? 0 : wxST_ELLIPSIZE_END; #endif /* __WXGTK__ */ - label = new wxStaticText(parent(), wxID_ANY, line.label + (line.label.IsEmpty() ? "" : ": "), + label = new wxStaticText(this->ctrl_parent(), wxID_ANY, line.label + (line.label.IsEmpty() ? "" : ": "), wxDefaultPosition, wxSize(label_width, -1), label_style); + label->SetBackgroundStyle(wxBG_STYLE_PAINT); label->SetFont(label_font); label->Wrap(label_width); // avoid a Linux/GTK bug if (!line.near_label_widget) grid_sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, line.label.IsEmpty() ? 0 : 5); + else if (line.near_label_widget && line.label.IsEmpty()) + grid_sizer->Add(line.near_label_widget(this->ctrl_parent()), 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 7); else { // If we're here, we have some widget near the label // so we need a horizontal sizer to arrange these things auto sizer = new wxBoxSizer(wxHORIZONTAL); grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM | wxTOP | wxLEFT), staticbox ? 0 : 1); - sizer->Add(line.near_label_widget(parent()), 0, wxRIGHT, 7); + sizer->Add(line.near_label_widget(this->ctrl_parent()), 0, wxRIGHT, 7); sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, 5); } if (line.label_tooltip.compare("") != 0) @@ -201,7 +204,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n *full_Label = label; // Initiate the pointer to the control of the full label, if we need this one. // If there's a widget, build it and add the result to the sizer. if (line.widget != nullptr) { - auto wgt = line.widget(parent()); + auto wgt = line.widget(this->ctrl_parent()); // If widget doesn't have label, don't use border grid_sizer->Add(wgt, 0, wxEXPAND | wxBOTTOM | wxTOP, (wxOSX || line.label.IsEmpty()) ? 0 : 5); return; @@ -237,7 +240,8 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n wxString str_label = (option.label == "Top" || option.label == "Bottom") ? _CTX(option.label, "Layers") : _(option.label); - label = new wxStaticText(parent(), wxID_ANY, str_label + ": ", wxDefaultPosition, wxDefaultSize); + label = new wxStaticText(this->ctrl_parent(), wxID_ANY, str_label + ": ", wxDefaultPosition, wxDefaultSize); + label->SetBackgroundStyle(wxBG_STYLE_PAINT); label->SetFont(label_font); sizer_tmp->Add(label, 0, /*wxALIGN_RIGHT |*/ wxALIGN_CENTER_VERTICAL, 0); } @@ -262,8 +266,9 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n // add sidetext if any if (option.sidetext != "") { - auto sidetext = new wxStaticText( parent(), wxID_ANY, _(option.sidetext), wxDefaultPosition, + auto sidetext = new wxStaticText( this->ctrl_parent(), wxID_ANY, _(option.sidetext), wxDefaultPosition, wxSize(sidetext_width, -1)/*wxDefaultSize*/, wxALIGN_LEFT); + sidetext->SetBackgroundStyle(wxBG_STYLE_PAINT); sidetext->SetFont(sidetext_font); sizer_tmp->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4); field->set_side_text_ptr(sidetext); @@ -271,7 +276,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n // add side widget if any if (opt.side_widget != nullptr) { - sizer_tmp->Add(opt.side_widget(parent())/*!.target()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 1); //! requires verification + sizer_tmp->Add(opt.side_widget(this->ctrl_parent())/*!.target()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 1); //! requires verification } if (opt.opt_id != option_set.back().opt_id) //! istead of (opt != option_set.back()) @@ -287,11 +292,11 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n // extra widget for non-staticbox option group (like for the frequently used parameters on the sidebar) should be wxALIGN_RIGHT const auto v_sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(v_sizer, 1, wxEXPAND); - v_sizer->Add(extra_widget(parent()), 0, wxALIGN_RIGHT); + v_sizer->Add(extra_widget(this->ctrl_parent()), 0, wxALIGN_RIGHT); return; } - sizer->Add(extra_widget(parent())/*!.target()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4); //! requires verification + sizer->Add(extra_widget(this->ctrl_parent())/*!.target()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4); //! requires verification } } diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp index d9ff6a01a..661aadbd7 100644 --- a/src/slic3r/GUI/OptionsGroup.hpp +++ b/src/slic3r/GUI/OptionsGroup.hpp @@ -112,6 +112,10 @@ public: } #endif /* __WXGTK__ */ + wxWindow* ctrl_parent() const { + return this->stb ? (wxWindow*)this->stb : this->parent(); + } + void append_line(const Line& line, wxStaticText** full_Label = nullptr); Line create_single_option_line(const Option& option) const; void append_single_option_line(const Option& option) { append_line(create_single_option_line(option)); } @@ -161,8 +165,10 @@ public: staticbox(title!=""), extra_column(extra_clmn) { if (staticbox) { stb = new wxStaticBox(_parent, wxID_ANY, title); + stb->SetBackgroundStyle(wxBG_STYLE_PAINT); stb->SetFont(wxGetApp().bold_font()); - } + } else + stb = nullptr; sizer = (staticbox ? new wxStaticBoxSizer(stb, wxVERTICAL) : new wxBoxSizer(wxVERTICAL)); auto num_columns = 1U; if (label_width != 0) num_columns++; diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index ae33443c3..faee25270 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -58,6 +58,13 @@ Tab::Tab(wxNotebook* parent, const wxString& title, const char* name) : wxGetApp().tabs_list.push_back(this); m_em_unit = wxGetApp().em_unit(); + + Bind(wxEVT_SIZE, ([this](wxSizeEvent &evt) { + for (auto page : m_pages) + if (! page.get()->IsShown()) + page->layout_valid = false; + evt.Skip(); + })); } void Tab::set_type() @@ -74,7 +81,7 @@ void Tab::set_type() void Tab::create_preset_tab() { #ifdef __WINDOWS__ -// SetDoubleBuffered(true); + SetDoubleBuffered(true); #endif //__WINDOWS__ m_preset_bundle = wxGetApp().preset_bundle; @@ -293,6 +300,11 @@ Slic3r::GUI::PageShp Tab::add_options_page(const wxString& title, const std::str auto panel = this; #endif PageShp page(new Page(panel, title, icon_idx)); +// page->SetBackgroundStyle(wxBG_STYLE_SYSTEM); +#ifdef __WINDOWS__ +// page->SetDoubleBuffered(true); +#endif //__WINDOWS__ + page->SetScrollbars(1, 20, 1, 2); page->Hide(); m_hsizer->Add(page.get(), 1, wxEXPAND | wxLEFT, 5); @@ -318,7 +330,7 @@ void Tab::OnActivate() void Tab::update_labels_colour() { - Freeze(); +// Freeze(); //update options "decoration" for (const auto opt : m_options_list) { @@ -345,7 +357,7 @@ void Tab::update_labels_colour() if (field == nullptr) continue; field->set_label_colour_force(color); } - Thaw(); +// Thaw(); auto cur_item = m_treectrl->GetFirstVisibleItem(); while (cur_item) { @@ -389,7 +401,7 @@ void Tab::update_changed_ui() for (auto opt_key : dirty_options) m_options_list[opt_key] &= ~osInitValue; for (auto opt_key : nonsys_options) m_options_list[opt_key] &= ~osSystemValue; - Freeze(); +// Freeze(); //update options "decoration" for (const auto opt : m_options_list) { @@ -439,7 +451,7 @@ void Tab::update_changed_ui() field->set_undo_to_sys_tooltip(sys_tt); field->set_label_colour(color); } - Thaw(); +// Thaw(); wxTheApp->CallAfter([this]() { update_changed_tree_ui(); @@ -686,16 +698,16 @@ void Tab::load_config(const DynamicPrintConfig& config) // Reload current $self->{config} (aka $self->{presets}->edited_preset->config) into the UI fields. void Tab::reload_config() { - Freeze(); +// Freeze(); for (auto page : m_pages) page->reload_config(); - Thaw(); +// Thaw(); } void Tab::update_visibility() { const ConfigOptionMode mode = wxGetApp().get_mode(); - Freeze(); +// Freeze(); for (auto page : m_pages) page->update_visibility(mode); @@ -705,7 +717,7 @@ void Tab::update_visibility() m_mode_sizer->SetMode(mode); Layout(); - Thaw(); +// Thaw(); // to update tree items color // wxTheApp->CallAfter([this]() { @@ -1180,7 +1192,7 @@ void TabPrint::update() // return; // ! TODO Let delete this part of code after a common aplication testing m_update_cnt++; - Freeze(); +// Freeze(); double fill_density = m_config->option("fill_density")->value; @@ -1391,7 +1403,7 @@ void TabPrint::update() m_recommended_thin_wall_thickness_description_line->SetText( from_u8(PresetHints::recommended_thin_wall_thickness(*m_preset_bundle))); - Thaw(); +// Thaw(); m_update_cnt--; if (m_update_cnt==0) @@ -1566,7 +1578,7 @@ void TabFilament::update() return; // ys_FIXME m_update_cnt++; - Freeze(); +// Freeze(); wxString text = from_u8(PresetHints::cooling_description(m_presets->get_edited_preset())); m_cooling_description_line->SetText(text); text = from_u8(PresetHints::maximum_volumetric_flow_description(*m_preset_bundle)); @@ -1580,7 +1592,7 @@ void TabFilament::update() for (auto el : { "min_fan_speed", "disable_fan_first_layers" }) get_field(el)->toggle(fan_always_on); - Thaw(); +// Thaw(); m_update_cnt--; if (m_update_cnt == 0) @@ -2261,7 +2273,7 @@ void TabPrinter::update() void TabPrinter::update_fff() { - Freeze(); +// Freeze(); bool en; auto serial_speed = get_field("serial_speed"); @@ -2360,7 +2372,7 @@ void TabPrinter::update_fff() (have_multiple_extruders && toolchange_retraction); } - Thaw(); +// Thaw(); } void TabPrinter::update_sla() @@ -2674,7 +2686,7 @@ void Tab::OnTreeSelChange(wxTreeEvent& event) #ifdef __linux__ std::unique_ptr no_updates(new wxWindowUpdateLocker(this)); #else - wxWindowUpdateLocker noUpdates(this); +// wxWindowUpdateLocker noUpdates(this); #endif if (m_pages.empty()) @@ -2694,17 +2706,22 @@ void Tab::OnTreeSelChange(wxTreeEvent& event) if (page == nullptr) return; for (auto& el : m_pages) - el.get()->Hide(); +// if (el.get()->IsShown()) { + el.get()->Hide(); +// break; +// } -#ifdef __linux__ - no_updates.reset(nullptr); -#endif - - page->Show(); - m_hsizer->Layout(); - Refresh(); + #ifdef __linux__ + no_updates.reset(nullptr); + #endif update_undo_buttons(); + page->Show(); +// if (! page->layout_valid) { + page->layout_valid = true; + m_hsizer->Layout(); + Refresh(); +// } } void Tab::OnKeyDown(wxKeyEvent& event) @@ -3040,6 +3057,7 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la } // auto bmp = new wxStaticBitmap(parent, wxID_ANY, bmp_name.empty() ? wxNullBitmap : wxBitmap(from_u8(var(bmp_name)), wxBITMAP_TYPE_PNG)); auto bmp = new wxStaticBitmap(parent, wxID_ANY, bmp_name.empty() ? wxNullBitmap : create_scaled_bitmap(bmp_name)); + bmp->SetBackgroundStyle(wxBG_STYLE_PAINT); return bmp; }; diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 7ef066963..5f8a7f706 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -65,6 +65,9 @@ public: bool m_is_modified_values{ false }; bool m_is_nonsys_values{ true }; + // Delayed layout after resizing the main window. + bool layout_valid = false; + public: std::vector m_optgroups; DynamicPrintConfig* m_config; From ba54ce030993ac00a1a58e3f646561f842d75d95 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Mon, 18 Mar 2019 15:10:40 +0100 Subject: [PATCH 06/19] Added "Edit Preset" buttons on the sidebar. + fixed Filament presets updating for the multi-material Printer (inside update_compatible(...) function) --- src/slic3r/GUI/Plater.cpp | 44 ++++++++++++++++++++++++++++++--- src/slic3r/GUI/Plater.hpp | 2 ++ src/slic3r/GUI/PresetBundle.cpp | 30 ++++++++++++---------- 3 files changed, 59 insertions(+), 17 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 601c2ddb6..b5074ccc1 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -275,9 +275,36 @@ wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(15 * dialog->Destroy(); }); } + + edit_btn = new wxButton(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); +#ifdef __WINDOWS__ + edit_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); +#endif + edit_btn->SetBitmap(create_scaled_bitmap("cog.png")); + edit_btn->SetToolTip(_(L("Click to Edit a selected Filament Preset"))); + + edit_btn->Bind(wxEVT_BUTTON, ([preset_type, this](wxCommandEvent) + { + Tab* tab = wxGetApp().get_tab(preset_type); + if (!tab) + return; + + int page_id = wxGetApp().tab_panel()->FindPage(tab); + if (page_id == wxNOT_FOUND) + return; + + wxGetApp().tab_panel()->ChangeSelection(page_id); + + tab->select_preset(GetString(GetSelection()).ToUTF8().data()); + + })); } -PresetComboBox::~PresetComboBox() {} +PresetComboBox::~PresetComboBox() +{ + if (edit_btn) + edit_btn->Destroy(); +} void PresetComboBox::set_label_marker(int item) @@ -611,13 +638,18 @@ Sidebar::Sidebar(Plater *parent) text->SetFont(wxGetApp().small_font()); *combo = new PresetComboBox(p->presets_panel, preset_type); + auto combo_and_btn_sizer = new wxBoxSizer(wxHORIZONTAL); + combo_and_btn_sizer->Add(*combo, 1, wxEXPAND); + if ((*combo)->edit_btn) + combo_and_btn_sizer->Add((*combo)->edit_btn, 0, wxLEFT|wxRIGHT, int(0.3*wxGetApp().em_unit())); + auto *sizer_presets = this->p->sizer_presets; auto *sizer_filaments = this->p->sizer_filaments; sizer_presets->Add(text, 0, wxALIGN_LEFT | wxEXPAND | wxRIGHT, 4); if (! filament) { - sizer_presets->Add(*combo, 0, wxEXPAND | wxBOTTOM, 1); + sizer_presets->Add(combo_and_btn_sizer, 0, wxEXPAND | wxBOTTOM, 1); } else { - sizer_filaments->Add(*combo, 0, wxEXPAND | wxBOTTOM, 1); + sizer_filaments->Add(combo_and_btn_sizer, 0, wxEXPAND | wxBOTTOM, 1); (*combo)->set_extruder_idx(0); sizer_presets->Add(sizer_filaments, 1, wxEXPAND); } @@ -714,8 +746,12 @@ void Sidebar::init_filament_combo(PresetComboBox **combo, const int extr_idx) { (*combo)->set_extruder_idx(extr_idx); + auto combo_and_btn_sizer = new wxBoxSizer(wxHORIZONTAL); + combo_and_btn_sizer->Add(*combo, 1, wxEXPAND); + combo_and_btn_sizer->Add((*combo)->edit_btn, 0, wxLEFT | wxRIGHT, int(0.3*wxGetApp().em_unit())); + auto /***/sizer_filaments = this->p->sizer_filaments; - sizer_filaments->Add(*combo, 1, wxEXPAND | wxBOTTOM, 1); + sizer_filaments->Add(combo_and_btn_sizer, 1, wxEXPAND | wxBOTTOM, 1); } void Sidebar::remove_unused_filament_combos(const int current_extruder_count) diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index ecce63805..d24a9bf32 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -46,6 +46,8 @@ public: PresetComboBox(wxWindow *parent, Preset::Type preset_type); ~PresetComboBox(); + wxButton* edit_btn { nullptr }; + void set_label_marker(int item); void set_extruder_idx(const int extr_idx) { extruder_idx = extr_idx; } int get_extruder_idx() const { return extruder_idx; } diff --git a/src/slic3r/GUI/PresetBundle.cpp b/src/slic3r/GUI/PresetBundle.cpp index f0bb4de01..b8c9fedac 100644 --- a/src/slic3r/GUI/PresetBundle.cpp +++ b/src/slic3r/GUI/PresetBundle.cpp @@ -1308,19 +1308,23 @@ void PresetBundle::update_compatible(bool select_other_if_incompatible) { return std::find(prefered_filament_profiles.begin(), prefered_filament_profiles.end(), profile_name) != prefered_filament_profiles.end(); }); if (select_other_if_incompatible) { // Verify validity of the current filament presets. - this->filament_presets.front() = this->filaments.get_edited_preset().name; - for (size_t idx = 1; idx < this->filament_presets.size(); ++ idx) { - std::string &filament_name = this->filament_presets[idx]; - Preset *preset = this->filaments.find_preset(filament_name, false); - if (preset == nullptr || ! preset->is_compatible) { - // Pick a compatible profile. If there are prefered_filament_profiles, use them. - if (prefered_filament_profiles.empty()) - filament_name = this->filaments.first_compatible().name; - else { - const std::string &preferred = (idx < prefered_filament_profiles.size()) ? - prefered_filament_profiles[idx] : prefered_filament_profiles.front(); - filament_name = this->filaments.first_compatible( - [&preferred](const std::string& profile_name) { return profile_name == preferred; }).name; + if (this->filament_presets.size() == 1) + this->filament_presets.front() = this->filaments.get_edited_preset().name; + else + { + for (size_t idx = 0; idx < this->filament_presets.size(); ++idx) { + std::string &filament_name = this->filament_presets[idx]; + Preset *preset = this->filaments.find_preset(filament_name, false); + if (preset == nullptr || !preset->is_compatible) { + // Pick a compatible profile. If there are prefered_filament_profiles, use them. + if (prefered_filament_profiles.empty()) + filament_name = this->filaments.first_compatible().name; + else { + const std::string &preferred = (idx < prefered_filament_profiles.size()) ? + prefered_filament_profiles[idx] : prefered_filament_profiles.front(); + filament_name = this->filaments.first_compatible( + [&preferred](const std::string& profile_name) { return profile_name == preferred; }).name; + } } } } From a90d5c8a286dc687dd1139351cbe5d18edadfc74 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Mon, 18 Mar 2019 20:54:01 +0100 Subject: [PATCH 07/19] Performance fix of rendering of the parameter tabs on Windows: Disabled Windows Vista themes for the wxNotebook. --- src/slic3r/GUI/Field.cpp | 17 ++++++++++++++++- src/slic3r/GUI/GUI_App.cpp | 5 +++++ src/slic3r/GUI/GUI_App.hpp | 2 ++ src/slic3r/GUI/MainFrame.cpp | 4 +++- src/slic3r/GUI/Tab.cpp | 9 ++++++++- 5 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index c9eb9282e..f691a8065 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -259,7 +259,12 @@ void TextCtrl::BUILD() { const long style = m_opt.multiline ? wxTE_MULTILINE : wxTE_PROCESS_ENTER/*0*/; auto temp = new wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, style); - temp->SetBackgroundStyle(wxBG_STYLE_PAINT); + temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); + + if (! m_opt.multiline) + // Only disable background refresh for single line input fields, as they are completely painted over by the edit control. + // This does not apply to the multi-line edit field, where the last line and a narrow frame around the text is not cleared. + temp->SetBackgroundStyle(wxBG_STYLE_PAINT); #ifdef __WXOSX__ temp->OSXDisableAllSmartSubstitutions(); #endif // __WXOSX__ @@ -375,6 +380,7 @@ void CheckBox::BUILD() { false; auto temp = new wxCheckBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size); + temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); temp->SetBackgroundStyle(wxBG_STYLE_PAINT); temp->SetValue(check_value); if (m_opt.readonly) temp->Disable(); @@ -433,6 +439,7 @@ void SpinCtrl::BUILD() { auto temp = new wxSpinCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, 0|wxTE_PROCESS_ENTER, min_val, max_val, default_value); + temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); temp->SetBackgroundStyle(wxBG_STYLE_PAINT); #ifndef __WXOSX__ @@ -507,6 +514,7 @@ void Choice::BUILD() { temp = new wxComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size); else temp = new wxComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, NULL, wxCB_READONLY); + temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); temp->SetBackgroundStyle(wxBG_STYLE_PAINT); // recast as a wxWindow to fit the calling convention @@ -815,12 +823,16 @@ void PointCtrl::BUILD() x_textctrl = new wxTextCtrl(m_parent, wxID_ANY, X, wxDefaultPosition, field_size, wxTE_PROCESS_ENTER); y_textctrl = new wxTextCtrl(m_parent, wxID_ANY, Y, wxDefaultPosition, field_size, wxTE_PROCESS_ENTER); + x_textctrl->SetFont(Slic3r::GUI::wxGetApp().normal_font()); x_textctrl->SetBackgroundStyle(wxBG_STYLE_PAINT); + y_textctrl->SetFont(Slic3r::GUI::wxGetApp().normal_font()); y_textctrl->SetBackgroundStyle(wxBG_STYLE_PAINT); auto static_text_x = new wxStaticText(m_parent, wxID_ANY, "x : "); auto static_text_y = new wxStaticText(m_parent, wxID_ANY, " y : "); + static_text_x->SetFont(Slic3r::GUI::wxGetApp().normal_font()); static_text_x->SetBackgroundStyle(wxBG_STYLE_PAINT); + static_text_y->SetFont(Slic3r::GUI::wxGetApp().normal_font()); static_text_y->SetBackgroundStyle(wxBG_STYLE_PAINT); temp->Add(static_text_x, 0, wxALIGN_CENTER_VERTICAL, 0); @@ -894,6 +906,7 @@ void StaticText::BUILD() const wxString legend(static_cast(m_opt.default_value)->value); auto temp = new wxStaticText(m_parent, wxID_ANY, legend, wxDefaultPosition, size, wxST_ELLIPSIZE_MIDDLE); + temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); temp->SetBackgroundStyle(wxBG_STYLE_PAINT); temp->SetFont(wxGetApp().bold_font()); @@ -918,11 +931,13 @@ void SliderCtrl::BUILD() m_slider = new wxSlider(m_parent, wxID_ANY, def_val * m_scale, min * m_scale, max * m_scale, wxDefaultPosition, size); + m_slider->SetFont(Slic3r::GUI::wxGetApp().normal_font()); m_slider->SetBackgroundStyle(wxBG_STYLE_PAINT); wxSize field_size(40, -1); m_textctrl = new wxTextCtrl(m_parent, wxID_ANY, wxString::Format("%d", m_slider->GetValue()/m_scale), wxDefaultPosition, field_size); + m_textctrl->SetFont(Slic3r::GUI::wxGetApp().normal_font()); m_textctrl->SetBackgroundStyle(wxBG_STYLE_PAINT); temp->Add(m_slider, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL, 0); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 84bbf42fc..3b506850a 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -94,7 +94,11 @@ bool GUI_App::OnInit() SetAppName("Slic3rPE-beta"); SetAppDisplayName("Slic3r Prusa Edition"); +// 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; @@ -249,6 +253,7 @@ void GUI_App::init_fonts() { m_small_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); m_bold_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold(); + m_normal_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); #ifdef __WXMAC__ m_small_font.SetPointSize(11); diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 8f332b855..e10a7b95e 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -78,6 +78,7 @@ class GUI_App : public wxApp wxFont m_small_font; wxFont m_bold_font; + wxFont m_normal_font; size_t m_em_unit; // width of a "m"-symbol in pixels for current system font // Note: for 100% Scale m_em_unit = 10 -> it's a good enough coefficient for a size setting of controls @@ -106,6 +107,7 @@ public: const wxFont& small_font() { return m_small_font; } const wxFont& bold_font() { return m_bold_font; } + const wxFont& normal_font() { return m_normal_font; } size_t em_unit() const { return m_em_unit; } void set_em_unit(const size_t em_unit) { m_em_unit = em_unit; } diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 9e54b9b36..4ded9b1ff 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -127,7 +127,9 @@ wxFrame(NULL, wxID_ANY, SLIC3R_BUILD, wxDefaultPosition, wxDefaultSize, wxDEFAUL void MainFrame::init_tabpanel() { - m_tabpanel = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL); + // wxNB_NOPAGETHEME: Disable Windows Vista theme for the Notebook background. The theme performance is terrible on Windows 10 + // with multiple high resolution displays connected. + m_tabpanel = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME); m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, [this](wxEvent&) { auto panel = m_tabpanel->GetCurrentPage(); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index a9c76d764..70adfd9ee 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1498,6 +1498,7 @@ void TabFilament::build() line = optgroup->create_single_option_line("filament_ramming_parameters");// { _(L("Ramming")), "" }; line.widget = [this](wxWindow* parent) { auto ramming_dialog_btn = new wxButton(parent, wxID_ANY, _(L("Ramming settings"))+dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); + ramming_dialog_btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(ramming_dialog_btn); @@ -1633,6 +1634,7 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) auto printhost_browse = [=](wxWindow* parent) { auto btn = m_printhost_browse_btn = new wxButton(parent, wxID_ANY, _(L(" Browse "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT); + btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); btn->SetBitmap(create_scaled_bitmap("zoom.png")); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn); @@ -1651,6 +1653,7 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) auto print_host_test = [this](wxWindow* parent) { auto btn = m_print_host_test_btn = new wxButton(parent, wxID_ANY, _(L("Test")), wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); + btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); btn->SetBitmap(create_scaled_bitmap("wrench.png")); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn); @@ -1688,6 +1691,7 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) auto printhost_cafile_browse = [this, optgroup] (wxWindow* parent) { auto btn = new wxButton(parent, wxID_ANY, _(L(" Browse "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT); // btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("zoom.png")), wxBITMAP_TYPE_PNG)); + btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); btn->SetBitmap(create_scaled_bitmap("zoom.png")); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(btn); @@ -1726,6 +1730,7 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) \tOn this system, Slic3r uses HTTPS certificates from the system Certificate Store or Keychain.\n\ \tTo use a custom CA file, please import your CA file into Certificate Store / Keychain.")), ca_file_hint)); + txt->SetFont(Slic3r::GUI::wxGetApp().normal_font()); auto sizer = new wxBoxSizer(wxHORIZONTAL); sizer->Add(txt); return sizer; @@ -1966,7 +1971,7 @@ void TabPrinter::build_sla() Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" }; line.widget = [this](wxWindow* parent) { auto btn = new wxButton(parent, wxID_ANY, _(L(" Set ")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); - // btn->SetFont(Slic3r::GUI::small_font); + btn->SetFont(wxGetApp().small_font()); // btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("printer_empty.png")), wxBITMAP_TYPE_PNG)); btn->SetBitmap(create_scaled_bitmap("printer_empty.png")); @@ -2883,7 +2888,9 @@ void Tab::update_ui_from_settings() wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &deps) { deps.checkbox = new wxCheckBox(parent, wxID_ANY, _(L("All"))); + deps.checkbox->SetFont(Slic3r::GUI::wxGetApp().normal_font()); deps.btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); + deps.btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); // deps.btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("printer_empty.png")), wxBITMAP_TYPE_PNG)); deps.btn->SetBitmap(create_scaled_bitmap("printer_empty.png")); From 20be57dc582b53014cca5e51b73a585ebdcff8c1 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Mon, 18 Mar 2019 23:22:38 +0100 Subject: [PATCH 08/19] Weird things happen as the Paint messages are floating around the windows being destructed. Avoid the Paint messages by hiding the main window. Also the application closes much faster without these unnecessary screen refreshes. In addition, there were some crashes due to the Paint events sent to already destructed windows. --- src/slic3r/GUI/MainFrame.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 4ded9b1ff..d69480b28 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -96,6 +96,12 @@ wxFrame(NULL, wxID_ANY, SLIC3R_BUILD, wxDefaultPosition, wxDefaultSize, wxDEFAUL return; } + // Weird things happen as the Paint messages are floating around the windows being destructed. + // Avoid the Paint messages by hiding the main window. + // Also the application closes much faster without these unnecessary screen refreshes. + // In addition, there were some crashes due to the Paint events sent to already destructed windows. + this->Show(false); + // Save the slic3r.ini.Usually the ini file is saved from "on idle" callback, // but in rare cases it may not have been called yet. wxGetApp().app_config->save(); From b7a1bd927aec366478238269a6f9f0fef542fce3 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 19 Mar 2019 14:36:32 +0100 Subject: [PATCH 09/19] Some improvements --- src/slic3r/GUI/GUI_App.cpp | 7 +++++++ src/slic3r/GUI/GUI_App.hpp | 1 + src/slic3r/GUI/GUI_ObjectList.cpp | 3 +-- src/slic3r/GUI/Plater.cpp | 11 ++++++++++- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 1cf2ca17c..94b070e47 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -743,6 +743,13 @@ wxNotebook* GUI_App::tab_panel() const return mainframe->m_tabpanel; } +int GUI_App::extruders_cnt() const +{ + const Preset& preset = preset_bundle->printers.get_selected_preset(); + return preset.printer_technology() == ptSLA ? 1 : + preset.config.option("nozzle_diameter")->values.size(); +} + void GUI_App::window_pos_save(wxTopLevelWindow* window, const std::string &name) { if (name.empty()) { return; } diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 4c23e3eb7..81ef3d040 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -163,6 +163,7 @@ public: Plater* plater_{ nullptr }; wxNotebook* tab_panel() const ; + int extruders_cnt() const; std::vector tabs_list; diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 7eef82063..d0f78a6da 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -51,8 +51,7 @@ static DynamicPrintConfig& printer_config() static int extruders_count() { - return printer_technology() == ptSLA ? 1 : - printer_config().option("nozzle_diameter")->values.size(); + return wxGetApp().extruders_cnt(); } ObjectList::ObjectList(wxWindow* parent) : diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index b5074ccc1..92b9c4171 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -295,8 +295,17 @@ wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(15 * wxGetApp().tab_panel()->ChangeSelection(page_id); - tab->select_preset(GetString(GetSelection()).ToUTF8().data()); + /* In a case of a multi-material printing, for editing another Filament Preset + * it's needed to select this preset for the "Filament settings" Tab + */ + if (preset_type == Preset::TYPE_FILAMENT && wxGetApp().extruders_cnt() > 1) + { + const std::string& selected_preset = GetString(GetSelection()).ToUTF8().data(); + // Call select_preset() only if there is new preset and not just modified + if ( !boost::algorithm::ends_with(selected_preset, "(modified)") ) + tab->select_preset(selected_preset); + } })); } From 438010f0f86723bdd32ffc4c8d4f8e4b0676b2fb Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 20 Mar 2019 10:14:49 +0100 Subject: [PATCH 10/19] Some code refactoring --- src/slic3r/GUI/Plater.cpp | 4 ++-- src/slic3r/GUI/Preset.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 92b9c4171..b0140a197 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -281,7 +281,7 @@ wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(15 * edit_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); #endif edit_btn->SetBitmap(create_scaled_bitmap("cog.png")); - edit_btn->SetToolTip(_(L("Click to Edit a selected Filament Preset"))); + edit_btn->SetToolTip(_(L("Click to edit preset"))); edit_btn->Bind(wxEVT_BUTTON, ([preset_type, this](wxCommandEvent) { @@ -303,7 +303,7 @@ wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(15 * const std::string& selected_preset = GetString(GetSelection()).ToUTF8().data(); // Call select_preset() only if there is new preset and not just modified - if ( !boost::algorithm::ends_with(selected_preset, "(modified)") ) + if ( !boost::algorithm::ends_with(selected_preset, Preset::suffix_modified()) ) tab->select_preset(selected_preset); } })); diff --git a/src/slic3r/GUI/Preset.hpp b/src/slic3r/GUI/Preset.hpp index 074e665c9..511313715 100644 --- a/src/slic3r/GUI/Preset.hpp +++ b/src/slic3r/GUI/Preset.hpp @@ -201,6 +201,7 @@ public: static const std::vector& sla_print_options(); static void update_suffix_modified(); + static const std::string& suffix_modified(); static void normalize(DynamicPrintConfig &config); // Report configuration fields, which are misplaced into a wrong group, remove them from the config. static std::string remove_invalid_keys(DynamicPrintConfig &config, const DynamicPrintConfig &default_config); @@ -210,7 +211,6 @@ protected: friend class PresetBundle; // Resize the extruder specific vectors () static void set_num_extruders(DynamicPrintConfig &config, unsigned int n); - static const std::string& suffix_modified(); static std::string remove_suffix_modified(const std::string &name); }; From e2349bdd2eb99094c561e503bca8a7d3ed7ce70f Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 20 Mar 2019 11:54:48 +0100 Subject: [PATCH 11/19] Added workaround for the non-editable wxBitmapComboBoxs under OSXDisableAllSmartSubstitutions + experiments with Linux --- src/slic3r/GUI/Field.cpp | 16 ++++++++++++++-- src/slic3r/GUI/OptionsGroup.cpp | 6 +++--- src/slic3r/GUI/OptionsGroup.hpp | 8 ++++---- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 217b9380a..026b62ab5 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -515,8 +515,20 @@ void Choice::BUILD() { m_is_editable = true; temp = new wxBitmapComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size); } - else - temp = new wxBitmapComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxCB_READONLY); + else { +#ifdef __WXOSX__ + /* wxBitmapComboBox with wxCB_READONLY style return NULL for GetTextCtrl(), + * so ToolTip doesn't shown. + * Next workaround helps to solve this problem + */ + temp = new wxBitmapComboBox(); + temp->SetTextCtrlStyle(wxTE_READONLY); + temp->Create(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr); +#else + temp = new wxBitmapComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxCB_READONLY); +#endif //__WXOSX__ + } + temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); temp->SetBackgroundStyle(wxBG_STYLE_PAINT); diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 5e9c9ac30..df2f7b582 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -138,7 +138,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n option_set.front().opt.sidetext.size() == 0 && option_set.front().side_widget == nullptr && line.get_extra_widgets().size() == 0) { wxSizer* tmp_sizer; -#ifdef __WXGTK__ +#if 0//#ifdef __WXGTK__ tmp_sizer = new wxBoxSizer(wxVERTICAL); m_panel->SetSizer(tmp_sizer); m_panel->Layout(); @@ -160,7 +160,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n } auto grid_sizer = m_grid_sizer; -#ifdef __WXGTK__ +#if 0//#ifdef __WXGTK__ m_panel->SetSizer(m_grid_sizer); m_panel->Layout(); #endif /* __WXGTK__ */ @@ -443,7 +443,7 @@ void ConfigOptionsGroup::Hide() void ConfigOptionsGroup::Show(const bool show) { sizer->ShowItems(show); -#ifdef __WXGTK__ +#if 0//#ifdef __WXGTK__ m_panel->Show(show); m_grid_sizer->Show(show); #endif /* __WXGTK__ */ diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp index 661aadbd7..dbe1ea1a2 100644 --- a/src/slic3r/GUI/OptionsGroup.hpp +++ b/src/slic3r/GUI/OptionsGroup.hpp @@ -100,13 +100,13 @@ public: /// Accessor function is because users are not allowed to change the parent /// but defining it as const means a lot of const_casts to deal with wx functions. inline wxWindow* parent() const { -#ifdef __WXGTK__ +#if 0//#ifdef __WXGTK__ return m_panel; #else return m_parent; #endif /* __WXGTK__ */ } -#ifdef __WXGTK__ +#if 0//#ifdef __WXGTK__ wxWindow* get_parent() const { return m_parent; } @@ -176,7 +176,7 @@ public: m_grid_sizer = new wxFlexGridSizer(0, num_columns, 1,0); static_cast(m_grid_sizer)->SetFlexibleDirection(wxBOTH/*wxHORIZONTAL*/); static_cast(m_grid_sizer)->AddGrowableCol(label_width == 0 ? 0 : !extra_column ? 1 : 2 ); -#ifdef __WXGTK__ +#if 0//#ifdef __WXGTK__ m_panel = new wxPanel( _parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); sizer->Fit(m_panel); sizer->Add(m_panel, 0, wxEXPAND | wxALL, wxOSX||!staticbox ? 0: 5); @@ -204,7 +204,7 @@ protected: // This panel is needed for correct showing of the ToolTips for Button, StaticText and CheckBox // Tooltips on GTK doesn't work inside wxStaticBoxSizer unless you insert a panel // inside it before you insert the other controls. -#ifdef __WXGTK__ +#if 0//#ifdef__WXGTK__ wxPanel* m_panel {nullptr}; #endif /* __WXGTK__ */ From 452eb62f1102e0a59d0b3979fc1101a6421029a5 Mon Sep 17 00:00:00 2001 From: YuSanka Date: Wed, 20 Mar 2019 16:22:01 +0100 Subject: [PATCH 12/19] Some code refactoring --- src/slic3r/GUI/GUI_App.cpp | 2 +- src/slic3r/GUI/Tab.cpp | 38 ++++++++++++++++++-------------------- src/slic3r/GUI/Tab.hpp | 4 +++- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 3b7ddd1d8..d68257a0a 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -530,7 +530,7 @@ void GUI_App::update_mode() sidebar().update_mode(); for (auto tab : tabs_list) - tab->update_visibility(); + tab->update_mode(); plater()->update_object_menu(); } diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index d54d01572..46a6de6ab 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -705,25 +705,28 @@ void Tab::reload_config() // Thaw(); } -void Tab::update_visibility() +void Tab::update_mode() { - const ConfigOptionMode mode = wxGetApp().get_mode(); -// Freeze(); - - for (auto page : m_pages) - page->update_visibility(mode); - update_page_tree_visibility(); + m_mode = wxGetApp().get_mode(); // update mode for ModeSizer - m_mode_sizer->SetMode(mode); + m_mode_sizer->SetMode(m_mode); + + update_visibility(); +} + +void Tab::update_visibility() +{ + Freeze(); // There is needed Freeze/Thaw to avoid a flashing after Show/Layout + + for (auto page : m_pages) + page->update_visibility(m_mode); + update_page_tree_visibility(); Layout(); -// Thaw(); + Thaw(); - // to update tree items color -// wxTheApp->CallAfter([this]() { - update_changed_tree_ui(); -// }); + update_changed_tree_ui(); } Field* Tab::get_field(const t_config_option_key& opt_key, int opt_index/* = -1*/) const @@ -2264,7 +2267,7 @@ void TabPrinter::update_pages() else m_pages_sla.empty() ? build_sla() : m_pages.swap(m_pages_sla); - rebuild_page_tree(true); + rebuild_page_tree(); } void TabPrinter::update() @@ -2470,10 +2473,8 @@ void Tab::load_current_preset() } //Regerenerate content of the page tree. -void Tab::rebuild_page_tree(bool tree_sel_change_event /*= false*/) +void Tab::rebuild_page_tree() { -// Freeze(); - // get label of the currently selected item const auto sel_item = m_treectrl->GetSelection(); const auto selected = sel_item ? m_treectrl->GetItemText(sel_item) : ""; @@ -2486,10 +2487,7 @@ void Tab::rebuild_page_tree(bool tree_sel_change_event /*= false*/) auto itemId = m_treectrl->AppendItem(rootItem, p->title(), p->iconID()); m_treectrl->SetItemTextColour(itemId, p->get_item_colour()); if (p->title() == selected) { -// if (!(p->title() == _(L("Machine limits")) || p->title() == _(L("Single extruder MM setup")))) // These Pages have to be updated inside OnTreeSelChange -// m_disable_tree_sel_changed_event = !tree_sel_change_event; m_treectrl->SelectItem(itemId); - m_disable_tree_sel_changed_event = false; have_selection = 1; } } diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index 81a79c58c..15ae0443c 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -209,6 +209,7 @@ protected: int m_em_unit; // To avoid actions with no-completed Tab bool m_complited { false }; + ConfigOptionMode m_mode = comSimple; public: PresetBundle* m_preset_bundle; @@ -236,7 +237,7 @@ public: void create_preset_tab(); void load_current_preset(); - void rebuild_page_tree(bool tree_sel_change_event = false); + void rebuild_page_tree(); void update_page_tree_visibility(); void select_preset(std::string preset_name = ""); bool may_discard_current_dirty_preset(PresetCollection* presets = nullptr, const std::string& new_printer_name = ""); @@ -270,6 +271,7 @@ public: void update_tab_ui(); void load_config(const DynamicPrintConfig& config); virtual void reload_config(); + void update_mode(); void update_visibility(); Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const; bool set_value(const t_config_option_key& opt_key, const boost::any& value); From 0198e717893f7b3766469ec220549507afe6cbbb Mon Sep 17 00:00:00 2001 From: YuSanka Date: Thu, 21 Mar 2019 09:04:11 +0100 Subject: [PATCH 13/19] Implemented issue #1990 --- src/slic3r/GUI/GUI_ObjectList.cpp | 39 ++++++++++++++++++++----------- src/slic3r/GUI/GUI_ObjectList.hpp | 4 ++-- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 2dda6b7cd..928924b3e 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -96,7 +96,7 @@ ObjectList::ObjectList(wxWindow* parent) : #endif //__WXMSW__ }); -// Bind(wxEVT_CHAR, [this](wxKeyEvent& event) { key_event(event); }); // doesn't work on OSX + Bind(wxEVT_CHAR, [this](wxKeyEvent& event) { key_event(event); }); // doesn't work on OSX #ifdef __WXMSW__ GetMainWindow()->Bind(wxEVT_MOTION, [this](wxMouseEvent& event) { @@ -443,8 +443,6 @@ void ObjectList::OnContextMenu(wxDataViewEvent&) if (is_windows10()) fix_through_netfabb(); } - else if (title == _("Extruder")) - show_extruder_selection_menu(); #ifndef __WXMSW__ GetMainWindow()->SetToolTip(""); // hide tooltip @@ -458,7 +456,7 @@ void ObjectList::show_context_menu() if (selected_instances_of_same_object()) wxGetApp().plater()->PopupMenu(&m_menu_instance); else - show_extruder_selection_menu(); + show_multi_selection_menu(); return; } @@ -990,10 +988,14 @@ wxMenuItem* ObjectList::append_menu_item_instance_to_object(wxMenu* menu) [this](wxCommandEvent&) { split_instances(); }, "", menu); } -void ObjectList::append_menu_item_rename(wxMenu* menu) +void ObjectList::append_menu_items_osx(wxMenu* menu) { + append_menu_item(menu, wxID_ANY, _(L("Delete item")), "", + [this](wxCommandEvent&) { remove(); }, "", menu); + append_menu_item(menu, wxID_ANY, _(L("Rename")), "", [this](wxCommandEvent&) { rename_item(); }, "", menu); + menu->AppendSeparator(); } @@ -1016,7 +1018,7 @@ void ObjectList::append_menu_item_export_stl(wxMenu* menu) const void ObjectList::create_object_popupmenu(wxMenu *menu) { #ifdef __WXOSX__ - append_menu_item_rename(menu); + append_menu_items_osx(menu); #endif // __WXOSX__ append_menu_item_export_stl(menu); @@ -1037,7 +1039,7 @@ void ObjectList::create_object_popupmenu(wxMenu *menu) void ObjectList::create_sla_object_popupmenu(wxMenu *menu) { #ifdef __WXOSX__ - append_menu_item_rename(menu); + append_menu_items_osx(menu); #endif // __WXOSX__ append_menu_item_export_stl(menu); @@ -1049,7 +1051,7 @@ void ObjectList::create_sla_object_popupmenu(wxMenu *menu) void ObjectList::create_part_popupmenu(wxMenu *menu) { #ifdef __WXOSX__ - append_menu_item_rename(menu); + append_menu_items_osx(menu); #endif // __WXOSX__ append_menu_item_fix_through_netfabb(menu); @@ -1857,8 +1859,11 @@ void ObjectList::remove() { if (m_objects_model->GetParent(item) == wxDataViewItem(0)) delete_from_model_and_list(itObject, m_objects_model->GetIdByItem(item), -1); - else + else { + if (sels.size() == 1) + select_item(m_objects_model->GetParent(item)); del_subobject_item(item); + } } } @@ -2358,7 +2363,7 @@ void ObjectList::OnEditingDone(wxDataViewEvent &event) _(L("the following characters are not allowed:")) + " <>:/\\|?*\""); } -void ObjectList::show_extruder_selection_menu() +void ObjectList::show_multi_selection_menu() { wxDataViewItemArray sels; GetSelections(sels); @@ -2369,9 +2374,17 @@ void ObjectList::show_extruder_selection_menu() return; wxMenu* menu = new wxMenu(); - append_menu_item(menu, wxID_ANY, _(L("Set extruder for selected items")), - _(L("Select extruder number for selected objects and/or parts")), - [this](wxCommandEvent&) { extruder_selection(); }, "", menu); + +#ifdef __WXOSX__ + append_menu_item(menu, wxID_ANY, _(L("Delete items")), "", + [this](wxCommandEvent&) { remove(); }, "", menu); +#endif //__WXOSX__ + + if (extruders_count() > 1) + append_menu_item(menu, wxID_ANY, _(L("Set extruder for selected items")), + _(L("Select extruder number for selected objects and/or parts")), + [this](wxCommandEvent&) { extruder_selection(); }, "", menu); + PopupMenu(menu); } diff --git a/src/slic3r/GUI/GUI_ObjectList.hpp b/src/slic3r/GUI/GUI_ObjectList.hpp index fa4db8f9d..e0df8dd40 100644 --- a/src/slic3r/GUI/GUI_ObjectList.hpp +++ b/src/slic3r/GUI/GUI_ObjectList.hpp @@ -184,7 +184,7 @@ public: wxMenuItem* append_menu_item_settings(wxMenu* menu); wxMenuItem* append_menu_item_change_type(wxMenu* menu); wxMenuItem* append_menu_item_instance_to_object(wxMenu* menu); - void append_menu_item_rename(wxMenu* menu); + void append_menu_items_osx(wxMenu* menu); void append_menu_item_fix_through_netfabb(wxMenu* menu); void append_menu_item_export_stl(wxMenu* menu) const ; void create_object_popupmenu(wxMenu *menu); @@ -283,7 +283,7 @@ private: void ItemValueChanged(wxDataViewEvent &event); void OnEditingDone(wxDataViewEvent &event); - void show_extruder_selection_menu(); + void show_multi_selection_menu(); void extruder_selection(); void set_extruder_for_selected_items(const int extruder) const ; From 8105fc33d5d43484e8f4d2bc3c85295e7ed44b44 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 21 Mar 2019 10:46:40 +0100 Subject: [PATCH 14/19] Fixed a merge issue --- src/slic3r/GUI/Tab.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 271d8e350..46a6de6ab 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -724,7 +724,7 @@ void Tab::update_visibility() update_page_tree_visibility(); Layout(); -// Thaw(); + Thaw(); update_changed_tree_ui(); } From 213ff2852a247d2ba8d27d750879bf13d3c08190 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 21 Mar 2019 11:44:39 +0100 Subject: [PATCH 15/19] We are getting mysterious crashes on Linux in gtk due to OpenGL context activation GH #1874 #1955. So we are applying a workaround here, just on linux. --- src/slic3r/GUI/GUI_Preview.cpp | 22 ++++++++++------------ src/slic3r/GUI/GUI_Preview.hpp | 4 ++++ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index be3fad9ec..e5e2ce6be 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -354,23 +354,14 @@ void Preview::load_print(bool keep_z_range) void Preview::reload_print(bool keep_volumes) { -#ifndef __linux__ - if (m_volumes_cleanup_required || !keep_volumes) - { - m_canvas->reset_volumes(); - m_canvas->reset_legend_texture(); - m_loaded = false; - m_volumes_cleanup_required = false; - } -#endif // __linux__ - +#ifdef __linux__ + // We are getting mysterious crashes on Linux in gtk due to OpenGL context activation GH #1874 #1955. + // So we are applying a workaround here: a delayed release of OpenGL vertex buffers. if (!IsShown()) { m_volumes_cleanup_required = !keep_volumes; return; } - -#ifdef __linux__ if (m_volumes_cleanup_required || !keep_volumes) { m_canvas->reset_volumes(); @@ -378,6 +369,13 @@ void Preview::reload_print(bool keep_volumes) m_loaded = false; m_volumes_cleanup_required = false; } +#else // __linux__ + if (!keep_volumes) + { + m_canvas->reset_volumes(); + m_canvas->reset_legend_texture(); + m_loaded = false; + } #endif // __linux__ load_print(); diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 182eaa952..96c49e54f 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -84,7 +84,11 @@ class Preview : public wxPanel BackgroundSlicingProcess* m_process; GCodePreviewData* m_gcode_preview_data; +#ifdef __linux__ + // We are getting mysterious crashes on Linux in gtk due to OpenGL context activation GH #1874 #1955. + // So we are applying a workaround here. bool m_volumes_cleanup_required; +#endif /* __linux__ */ // Calling this function object forces Plater::schedule_background_process. std::function m_schedule_background_process; From f76880cd5e5eed894e6ee0e9fac58ebf4d3e243c Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 21 Mar 2019 11:54:25 +0100 Subject: [PATCH 16/19] Fix and optimization of the previous commit. --- src/slic3r/GUI/GUI_Preview.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index e5e2ce6be..980843e8c 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -174,7 +174,9 @@ Preview::Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_t , m_loaded(false) , m_enabled(false) , m_schedule_background_process(schedule_background_process_func) +#ifdef __linux__ , m_volumes_cleanup_required(false) +#endif // __linux__ { if (init(parent, bed, camera, view_toolbar)) { @@ -362,21 +364,19 @@ void Preview::reload_print(bool keep_volumes) m_volumes_cleanup_required = !keep_volumes; return; } - if (m_volumes_cleanup_required || !keep_volumes) + if ( +#ifdef __linux__ + m_volumes_cleanup_required || +#endif /* __linux__ */ + !keep_volumes) { m_canvas->reset_volumes(); m_canvas->reset_legend_texture(); m_loaded = false; +#ifdef __linux__ m_volumes_cleanup_required = false; +#endif /* __linux__ */ } -#else // __linux__ - if (!keep_volumes) - { - m_canvas->reset_volumes(); - m_canvas->reset_legend_texture(); - m_loaded = false; - } -#endif // __linux__ load_print(); } From f9e3b935d3a8960d51c89c23d74243ed0577ef08 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 21 Mar 2019 12:09:14 +0100 Subject: [PATCH 17/19] Yet another fix. --- src/slic3r/GUI/GUI_Preview.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 980843e8c..9bb6c9790 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -364,6 +364,7 @@ void Preview::reload_print(bool keep_volumes) m_volumes_cleanup_required = !keep_volumes; return; } +#endif /* __linux __ */ if ( #ifdef __linux__ m_volumes_cleanup_required || From 562343cd2a1b932dcc21ac24d7029c37d2a9c1ce Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 21 Mar 2019 14:33:55 +0100 Subject: [PATCH 18/19] Localization fix of the warning texts in the 3D scene. Improved anti-aliasing of the warning texts in the 3D scene and the G-code legend. A ClearType rendering has been suppressed by rendering of the text into a red channel only. --- src/slic3r/GUI/GLCanvas3D.cpp | 146 ++++++++++++++++++++++++++-------- 1 file changed, 111 insertions(+), 35 deletions(-) diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 1c09096a8..b08688784 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -34,6 +34,7 @@ #include #include #include +#include // Print now includes tbb, and tbb includes Windows. This breaks compilation of wxWidgets if included before wx. #include "libslic3r/Print.hpp" @@ -1659,13 +1660,69 @@ void GLCanvas3D::WarningTexture::activate(WarningTexture::Warning warning, bool _generate(text, canvas, red_colored); // GUI::GLTexture::reset() is called at the beginning of generate(...) } -bool GLCanvas3D::WarningTexture::_generate(const std::string& msg, const GLCanvas3D& canvas, const bool red_colored/* = false*/) + +#ifdef __WXMSW__ +static bool is_font_cleartype(const wxFont &font) +{ + // Native font description: on MSW, it is a version number plus the content of LOGFONT, separated by semicolon. + wxString font_desc = font.GetNativeFontInfoDesc(); + // Find the quality field. + wxString sep(";"); + size_t startpos = 0; + for (size_t i = 0; i < 12; ++ i) + startpos = font_desc.find(sep, startpos + 1); + ++ startpos; + size_t endpos = font_desc.find(sep, startpos); + int quality = wxAtoi(font_desc(startpos, endpos - startpos)); + return quality == CLEARTYPE_QUALITY; +} + +// ClearType produces renders, which are difficult to convert into an alpha blended OpenGL texture. +// Therefore it is better to disable it, though Vojtech found out, that the font returned with ClearType +// disabled is signifcantly thicker than the default ClearType font. +// This function modifies the font provided. +static void msw_disable_cleartype(wxFont &font) +{ + // Native font description: on MSW, it is a version number plus the content of LOGFONT, separated by semicolon. + wxString font_desc = font.GetNativeFontInfoDesc(); + // Find the quality field. + wxString sep(";"); + size_t startpos_weight = 0; + for (size_t i = 0; i < 5; ++ i) + startpos_weight = font_desc.find(sep, startpos_weight + 1); + ++ startpos_weight; + size_t endpos_weight = font_desc.find(sep, startpos_weight); + // Parse the weight field. + unsigned int weight = atoi(font_desc(startpos_weight, endpos_weight - startpos_weight)); + size_t startpos = endpos_weight; + for (size_t i = 0; i < 6; ++ i) + startpos = font_desc.find(sep, startpos + 1); + ++ startpos; + size_t endpos = font_desc.find(sep, startpos); + int quality = wxAtoi(font_desc(startpos, endpos - startpos)); + if (quality == CLEARTYPE_QUALITY) { + // Replace the weight with a smaller value to compensate the weight of non ClearType font. + wxString sweight = std::to_string(weight * 2 / 4); + size_t len_weight = endpos_weight - startpos_weight; + wxString squality = std::to_string(ANTIALIASED_QUALITY); + font_desc.replace(startpos_weight, len_weight, sweight); + font_desc.replace(startpos + sweight.size() - len_weight, endpos - startpos, squality); + font.SetNativeFontInfo(font_desc); + wxString font_desc2 = font.GetNativeFontInfoDesc(); + } + wxString font_desc2 = font.GetNativeFontInfoDesc(); +} +#endif /* __WXMSW__ */ + +bool GLCanvas3D::WarningTexture::_generate(const std::string& msg_utf8, const GLCanvas3D& canvas, const bool red_colored/* = false*/) { reset(); - if (msg.empty()) + if (msg_utf8.empty()) return false; + wxString msg = GUI::from_u8(msg_utf8); + wxMemoryDC memDC; // select default font const float scale = canvas.get_canvas_size().get_scale_factor(); @@ -1676,46 +1733,47 @@ bool GLCanvas3D::WarningTexture::_generate(const std::string& msg, const GLCanva // calculates texture size wxCoord w, h; -// memDC.GetTextExtent(msg, &w, &h); memDC.GetMultiLineTextExtent(msg, &w, &h); - int pow_of_two_size = next_highest_power_of_2(std::max(w, h)); - m_original_width = (int)w; m_original_height = (int)h; - m_width = pow_of_two_size; - m_height = pow_of_two_size; + m_width = (int)next_highest_power_of_2((uint32_t)w); + m_height = (int)next_highest_power_of_2((uint32_t)h); // generates bitmap wxBitmap bitmap(m_width, m_height); memDC.SelectObject(bitmap); - memDC.SetBackground(wxBrush(wxColour(Background_Color[0], Background_Color[1], Background_Color[2]))); + memDC.SetBackground(wxBrush(*wxBLACK)); memDC.Clear(); // draw message - memDC.SetTextForeground(red_colored ? wxColour(255,72,65/*204,204*/) : *wxWHITE); -// memDC.DrawText(msg, 0, 0); - memDC.DrawLabel(msg, wxRect(0,0, m_original_width, m_original_height), wxALIGN_CENTER); + memDC.SetTextForeground(*wxRED); + memDC.DrawLabel(msg, wxRect(0,0, m_original_width, m_original_height), wxALIGN_CENTER); memDC.SelectObject(wxNullBitmap); // Convert the bitmap into a linear data ready to be loaded into the GPU. wxImage image = bitmap.ConvertToImage(); - image.SetMaskColour(Background_Color[0], Background_Color[1], Background_Color[2]); // prepare buffer std::vector data(4 * m_width * m_height, 0); + const unsigned char *src = image.GetData(); for (int h = 0; h < m_height; ++h) { - int hh = h * m_width; - unsigned char* px_ptr = data.data() + 4 * hh; + unsigned char* dst = data.data() + 4 * h * m_width; for (int w = 0; w < m_width; ++w) { - *px_ptr++ = image.GetRed(w, h); - *px_ptr++ = image.GetGreen(w, h); - *px_ptr++ = image.GetBlue(w, h); - *px_ptr++ = image.IsTransparent(w, h) ? 0 : Opacity; + *dst++ = 255; + if (red_colored) { + *dst++ = 72; // 204 + *dst++ = 65; // 204 + } else { + *dst++ = 255; + *dst++ = 255; + } + *dst++ = (unsigned char)std::min(255, *src); + src += 3; } } @@ -1839,7 +1897,15 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c const int scaled_border = Px_Border * scale; // select default font - const wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale_gl); + wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale_gl); +#ifdef __WXMSW__ + // Disabling ClearType works, but the font returned is very different (much thicker) from the default. +// msw_disable_cleartype(font); + bool cleartype = is_font_cleartype(font); +#else + bool cleartype = false; +#endif /* __WXMSW__ */ + memDC.SetFont(font); mask_memDC.SetFont(font); @@ -1863,10 +1929,8 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c if (items_count > 1) m_original_height += (items_count - 1) * scaled_square_contour; - int pow_of_two_size = (int)next_highest_power_of_2(std::max(m_original_width, m_original_height)); - - m_width = pow_of_two_size; - m_height = pow_of_two_size; + m_width = (int)next_highest_power_of_2((uint32_t)m_original_width); + m_height = (int)next_highest_power_of_2((uint32_t)m_original_height); // generates bitmap wxBitmap bitmap(m_width, m_height); @@ -1883,16 +1947,13 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c // draw title memDC.SetTextForeground(*wxWHITE); - mask_memDC.SetTextForeground(*wxWHITE); + mask_memDC.SetTextForeground(*wxRED); int title_x = scaled_border; int title_y = scaled_border; memDC.DrawText(title, title_x, title_y); mask_memDC.DrawText(title, title_x, title_y); - mask_memDC.SetPen(wxPen(*wxWHITE)); - mask_memDC.SetBrush(wxBrush(*wxWHITE)); - // draw icons contours as background int squares_contour_x = scaled_border; int squares_contour_y = scaled_border + title_height + scaled_title_offset; @@ -1907,7 +1968,6 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c memDC.SetPen(pen); memDC.SetBrush(brush); memDC.DrawRectangle(wxRect(squares_contour_x, squares_contour_y, squares_contour_width, squares_contour_height)); - mask_memDC.DrawRectangle(wxRect(squares_contour_x, squares_contour_y, squares_contour_width, squares_contour_height)); // draw items (colored icon + text) int icon_x = squares_contour_x + scaled_square_contour; @@ -1943,7 +2003,6 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c memDC.DrawRectangle(wxRect(icon_x_inner, icon_y + 1, px_inner_square, px_inner_square)); // draw text - memDC.DrawText(GUI::from_u8(item.text), text_x, icon_y + text_y_offset); mask_memDC.DrawText(GUI::from_u8(item.text), text_x, icon_y + text_y_offset); // update y @@ -1959,17 +2018,34 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c // prepare buffer std::vector data(4 * m_width * m_height, 0); - for (int h = 0; h < m_height; ++h) + const unsigned char *src_image = image.GetData(); + const unsigned char *src_mask = mask_image.GetData(); + for (int h = 0; h < m_height; ++h) { int hh = h * m_width; unsigned char* px_ptr = data.data() + 4 * hh; for (int w = 0; w < m_width; ++w) { - unsigned char alpha = (mask_image.GetRed(w, h) + mask_image.GetGreen(w, h) + mask_image.GetBlue(w, h)) / 3; - *px_ptr++ = image.GetRed(w, h); - *px_ptr++ = image.GetGreen(w, h); - *px_ptr++ = image.GetBlue(w, h); - *px_ptr++ = (alpha == 0) ? 128 : 255; + if (w >= squares_contour_x && w < squares_contour_x + squares_contour_width && + h >= squares_contour_y && h < squares_contour_y + squares_contour_height) { + // Color palette, use the color verbatim. + *px_ptr++ = *src_image++; + *px_ptr++ = *src_image++; + *px_ptr++ = *src_image++; + *px_ptr++ = 255; + } else { + // Text or background + unsigned char alpha = *src_mask; + // Compensate the white color for the 50% opacity reduction at the character edges. + //unsigned char color = (unsigned char)floor(alpha * 255.f / (128.f + 0.5f * alpha)); + unsigned char color = alpha; + *px_ptr++ = color; + *px_ptr++ = color; // *src_mask ++; + *px_ptr++ = color; // *src_mask ++; + *px_ptr++ = 128 + (alpha / 2); // (alpha > 0) ? 255 : 128; + src_image += 3; + } + src_mask += 3; } } From 4be6c17fd358d19e8fce0766a85b081f9315afe5 Mon Sep 17 00:00:00 2001 From: bubnikv Date: Thu, 21 Mar 2019 14:56:20 +0100 Subject: [PATCH 19/19] Limit number of perimeters to 10 thousands, that is 50 meters with 0.2mm nozzle. The number of perimeters has to be limited due to a numerical overflow of fixed point 32bit coordinates in the offsetting algorithm. --- src/libslic3r/PrintConfig.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 8c67cc067..630dbfb5f 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -1375,6 +1375,7 @@ void PrintConfigDef::init_fff_params() def->sidetext = L("(minimum)"); def->aliases = { "perimeter_offsets" }; def->min = 0; + def->max = 10000; def->default_value = new ConfigOptionInt(3); def = this->add("post_process", coStrings);