diff --git a/resources/icons/empty_icon.png b/resources/icons/empty_icon.png new file mode 100644 index 0000000000..2dd8f0afe1 Binary files /dev/null and b/resources/icons/empty_icon.png differ diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 554350b684..7cc533772b 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 457807afaa..128d60d47b 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 7a3d6f13a5..b614572261 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 060eb13833..b3580a285b 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 7ef066963e..2f8cec1de9 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();