diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 03b5cf1d92..280a66711a 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -2465,7 +2465,8 @@ void PrintConfigDef::init_fff_params() def->set_default_value(new ConfigOptionInt(0)); def = this->add("support_filament", coInt); - def->label = L("Support"); + def->gui_type = ConfigOptionDef::GUIType::i_enum_open; + def->label = L("Support"); def->category = L("Support"); def->tooltip = L("Filament to print support and skirt. 0 means no specific filament for support and current filament is used"); def->min = 0; @@ -2489,11 +2490,12 @@ void PrintConfigDef::init_fff_params() def->set_default_value(new ConfigOptionBool(false)); def = this->add("support_interface_filament", coInt); - def->label = L("Support interface"); + def->gui_type = ConfigOptionDef::GUIType::i_enum_open; + def->label = L("Support interface"); def->category = L("Support"); def->tooltip = L("Filament to print support interface. 0 means no specific filament for support interface and current filament is used"); def->min = 0; - //BBS + // BBS def->mode = comSimple; def->set_default_value(new ConfigOptionInt(1)); diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 6fe5d297c8..a76a81a0fb 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -986,13 +986,46 @@ using choice_ctrl = ::ComboBox; // BBS using choice_ctrl = ::ComboBox; // BBS #endif // __WXOSX__ -void Choice::BUILD() { +static std::map dynamic_lists; + +void Choice::register_dynamic_list(std::string const &optname, DynamicList *list) { dynamic_lists.emplace(optname, list); } + +void DynamicList::update() +{ + for (auto c : m_choices) apply_on(c); +} + +void DynamicList::add_choice(Choice *choice) +{ + auto iter = std::find(m_choices.begin(), m_choices.end(), choice); + if (iter != m_choices.end()) return; + apply_on(choice); + m_choices.push_back(choice); +} + +void DynamicList::remove_choice(Choice *choice) +{ + auto iter = std::find(m_choices.begin(), m_choices.end(), choice); + if (iter != m_choices.end()) m_choices.erase(iter); +} + +Choice::~Choice() +{ + if (m_list) { m_list->remove_choice(this); } +} + +void Choice::BUILD() +{ wxSize size(def_width_wider() * m_em_unit, wxDefaultCoord); if (m_opt.height >= 0) size.SetHeight(m_opt.height*m_em_unit); if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit); choice_ctrl* temp; - if (m_opt.gui_type != ConfigOptionDef::GUIType::undefined && m_opt.gui_type != ConfigOptionDef::GUIType::select_open) { + auto dynamic_list = dynamic_lists.find(m_opt.opt_key); + if (dynamic_list != dynamic_lists.end()) + m_list = dynamic_list->second; + if (m_opt.gui_type != ConfigOptionDef::GUIType::undefined && m_opt.gui_type != ConfigOptionDef::GUIType::select_open + && m_list == nullptr) { m_is_editable = true; temp = new choice_ctrl(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxTE_PROCESS_ENTER); } @@ -1051,7 +1084,10 @@ void Choice::BUILD() { } } set_selection(); - } + } else if (m_list) { + m_list->add_choice(this); + set_selection(); + } temp->Bind(wxEVT_MOUSEWHEEL, [this](wxMouseEvent& e) { if (m_suppress_scroll && !m_is_dropped) @@ -1224,7 +1260,9 @@ void Choice::set_value(const boost::any& value, bool change_event) break; ++idx; } - if (idx == enums.size()) { + if (m_list) + field->SetSelection(m_list->index_of(text_value)); + else if (idx == enums.size()) { // For editable Combobox under OSX is needed to set selection to -1 explicitly, // otherwise selection doesn't be changed field->SetSelection(-1); @@ -1344,7 +1382,10 @@ boost::any& Choice::get_value() } else if (m_opt.gui_type == ConfigOptionDef::GUIType::f_enum_open || m_opt.gui_type == ConfigOptionDef::GUIType::i_enum_open) { const int ret_enum = field->GetSelection(); - if (ret_enum < 0 || m_opt.enum_values.empty() || m_opt.type == coStrings || + if (m_list) { + ret_str = m_list->get_value(ret_enum); + get_value_by_opt_type(ret_str); + } else 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); @@ -1802,5 +1843,4 @@ boost::any& SliderCtrl::get_value() } -} // GUI -} // Slic3r +}} // Slic3r diff --git a/src/slic3r/GUI/Field.hpp b/src/slic3r/GUI/Field.hpp index 5ca0eae8aa..879cbdb469 100644 --- a/src/slic3r/GUI/Field.hpp +++ b/src/slic3r/GUI/Field.hpp @@ -335,13 +335,36 @@ public: wxWindow* getWindow() override { return window; } }; +class Choice; + +class DynamicList +{ +public: + virtual ~DynamicList() {} + virtual void apply_on(Choice * choice) = 0; + virtual wxString get_value(int index) = 0; + virtual int index_of(wxString value) = 0; + +protected: + void update(); + + std::vector m_choices; + +private: + friend class Choice; + void add_choice(Choice *choice); + void remove_choice(Choice *choice); +}; + class Choice : public Field { using Field::Field; - + DynamicList * m_list = nullptr; public: Choice(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {} Choice(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {} - ~Choice() {} + ~Choice(); + + static void register_dynamic_list(std::string const &optname, DynamicList *list); wxWindow* window{ nullptr }; void BUILD() override; diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 9a2731f5eb..2571c39502 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -931,7 +931,6 @@ void MainFrame::init_tabpanel() select_tab(MainFrame::tpHome); m_webview->load_url(url); }); - m_tabpanel->AddPage(m_webview, "", "tab_home_active", "tab_home_active"); m_param_panel = new ParamsPanel(m_tabpanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL); } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index da3a6c537e..16c4c5e704 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -420,11 +420,61 @@ void Sidebar::priv::hide_rich_tip(wxButton* btn) // Sidebar / public +static struct DynamicFilamentList : DynamicList +{ + std::vector> items; + + void apply_on(Choice *c) override + { + if (items.empty()) + update(true); + auto cb = dynamic_cast(c->window); + auto n = cb->GetSelection(); + cb->Clear(); + cb->Append(_L("Default")); + for (auto i : items) { + cb->Append(i.first, *i.second); + } + if (n < cb->GetCount()) + cb->SetSelection(n); + } + wxString get_value(int index) override + { + wxString str; + str << index; + return str; + } + int index_of(wxString value) override + { + long n = 0; + return value.ToLong(&n) ? int(n) : -1; + } + void update(bool force = false) + { + items.clear(); + if (!force && m_choices.empty()) + return; + auto icons = get_extruder_color_icons(true); + auto presets = wxGetApp().preset_bundle->filament_presets; + for (int i = 0; i < presets.size(); ++i) { + wxString str; + std::string type; + wxGetApp().preset_bundle->filaments.find_preset(presets[i])->get_filament_type(type); + str << (i + 1) << " - " << type; + items.push_back({str, icons[i]}); + } + DynamicList::update(); + } +} dynamic_filament_list; + Sidebar::Sidebar(Plater *parent) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(42 * wxGetApp().em_unit(), -1)), p(new priv(parent)) { + Choice::register_dynamic_list("support_filament", &dynamic_filament_list); + Choice::register_dynamic_list("support_interface_filament", &dynamic_filament_list); + p->scrolled = new wxPanel(this); -// p->scrolled->SetScrollbars(0, 100, 1, 2); // ys_DELETE_after_testing. pixelsPerUnitY = 100 + // p->scrolled->SetScrollbars(0, 100, 1, 2); // ys_DELETE_after_testing. pixelsPerUnitY = 100 // but this cause the bad layout of the sidebar, when all infoboxes appear. // As a result we can see the empty block at the bottom of the sidebar // But if we set this value to 5, layout will be better @@ -1021,6 +1071,7 @@ void Sidebar::update_presets(Preset::Type preset_type) for (size_t i = 0; i < filament_cnt; i++) p->combos_filament[i]->update(); + dynamic_filament_list.update(); break; } @@ -1290,6 +1341,7 @@ void Sidebar::on_filaments_change(size_t num_filaments) p->m_panel_filament_title->Layout(); p->m_panel_filament_title->Refresh(); update_ui_from_settings(); + dynamic_filament_list.update(); } void Sidebar::on_bed_type_change(BedType bed_type) @@ -1354,6 +1406,7 @@ void Sidebar::sync_ams_list() c->update(); wxGetApp().get_tab(Preset::TYPE_PRINT)->update(); wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); + dynamic_filament_list.update(); } ObjectList* Sidebar::obj_list() @@ -5391,6 +5444,7 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt) wxGetApp().preset_bundle->set_filament_preset(idx, preset_name); wxGetApp().plater()->update_project_dirty_from_presets(); wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); + dynamic_filament_list.update(); } bool select_preset = !combo->selection_is_changed_according_to_physical_printers();