mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	ENH: [STUDIO-1608] select support filament by combobox
Change-Id: I26543530202a53ef5753c38404617458a6d4a1ef
This commit is contained in:
		
							parent
							
								
									278eab5ae2
								
							
						
					
					
						commit
						41b1ad6f2f
					
				
					 5 changed files with 132 additions and 14 deletions
				
			
		|  | @ -2465,6 +2465,7 @@ void PrintConfigDef::init_fff_params() | ||||||
|     def->set_default_value(new ConfigOptionInt(0)); |     def->set_default_value(new ConfigOptionInt(0)); | ||||||
| 
 | 
 | ||||||
|     def = this->add("support_filament", coInt); |     def = this->add("support_filament", coInt); | ||||||
|  |     def->gui_type = ConfigOptionDef::GUIType::i_enum_open; | ||||||
|     def->label    = L("Support"); |     def->label    = L("Support"); | ||||||
|     def->category = 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->tooltip = L("Filament to print support and skirt. 0 means no specific filament for support and current filament is used"); | ||||||
|  | @ -2489,6 +2490,7 @@ void PrintConfigDef::init_fff_params() | ||||||
|     def->set_default_value(new ConfigOptionBool(false)); |     def->set_default_value(new ConfigOptionBool(false)); | ||||||
| 
 | 
 | ||||||
|     def = this->add("support_interface_filament", coInt); |     def = this->add("support_interface_filament", coInt); | ||||||
|  |     def->gui_type = ConfigOptionDef::GUIType::i_enum_open; | ||||||
|     def->label    = L("Support interface"); |     def->label    = L("Support interface"); | ||||||
|     def->category = L("Support"); |     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->tooltip = L("Filament to print support interface. 0 means no specific filament for support interface and current filament is used"); | ||||||
|  |  | ||||||
|  | @ -986,13 +986,46 @@ using choice_ctrl = ::ComboBox; // BBS | ||||||
| using choice_ctrl = ::ComboBox; // BBS
 | using choice_ctrl = ::ComboBox; // BBS
 | ||||||
| #endif // __WXOSX__
 | #endif // __WXOSX__
 | ||||||
| 
 | 
 | ||||||
| void Choice::BUILD() { | static std::map<std::string, DynamicList*> 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); |     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.height >= 0) size.SetHeight(m_opt.height*m_em_unit); | ||||||
|     if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit); |     if (m_opt.width >= 0) size.SetWidth(m_opt.width*m_em_unit); | ||||||
| 
 | 
 | ||||||
| 	choice_ctrl* temp; | 	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; |         m_is_editable = true; | ||||||
|         temp = new choice_ctrl(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxTE_PROCESS_ENTER); |         temp = new choice_ctrl(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxTE_PROCESS_ENTER); | ||||||
|     } |     } | ||||||
|  | @ -1051,6 +1084,9 @@ void Choice::BUILD() { | ||||||
|             } |             } | ||||||
| 		} | 		} | ||||||
| 		set_selection(); | 		set_selection(); | ||||||
|  |     } else if (m_list) { | ||||||
|  |         m_list->add_choice(this); | ||||||
|  |         set_selection(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     temp->Bind(wxEVT_MOUSEWHEEL, [this](wxMouseEvent& e) { |     temp->Bind(wxEVT_MOUSEWHEEL, [this](wxMouseEvent& e) { | ||||||
|  | @ -1224,7 +1260,9 @@ void Choice::set_value(const boost::any& value, bool change_event) | ||||||
| 				break; | 				break; | ||||||
| 			++idx; | 			++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,
 |             // For editable Combobox under OSX is needed to set selection to -1 explicitly,
 | ||||||
|             // otherwise selection doesn't be changed
 |             // otherwise selection doesn't be changed
 | ||||||
|             field->SetSelection(-1); |             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) { |     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(); |         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]))) |             (ret_str != m_opt.enum_values[ret_enum] && ret_str != _(m_opt.enum_labels[ret_enum]))) | ||||||
| 			// modifies ret_string!
 | 			// modifies ret_string!
 | ||||||
|             get_value_by_opt_type(ret_str); |             get_value_by_opt_type(ret_str); | ||||||
|  | @ -1802,5 +1843,4 @@ boost::any& SliderCtrl::get_value() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| } // GUI
 | }} // Slic3r
 | ||||||
| } // Slic3r
 |  | ||||||
|  |  | ||||||
|  | @ -335,13 +335,36 @@ public: | ||||||
| 	wxWindow*		getWindow() override { return window; } | 	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<Choice*> m_choices; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     friend class Choice; | ||||||
|  |     void                  add_choice(Choice *choice); | ||||||
|  |     void                  remove_choice(Choice *choice); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| class Choice : public Field { | class Choice : public Field { | ||||||
| 	using Field::Field; | 	using Field::Field; | ||||||
| 
 | 	DynamicList * m_list = nullptr; | ||||||
| public: | public: | ||||||
| 	Choice(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {} | 	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(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 }; | 	wxWindow*		window{ nullptr }; | ||||||
| 	void			BUILD() override; | 	void			BUILD() override; | ||||||
|  |  | ||||||
|  | @ -931,7 +931,6 @@ void MainFrame::init_tabpanel() | ||||||
|             select_tab(MainFrame::tpHome); |             select_tab(MainFrame::tpHome); | ||||||
|             m_webview->load_url(url); |             m_webview->load_url(url); | ||||||
|         }); |         }); | ||||||
| 
 |  | ||||||
|         m_tabpanel->AddPage(m_webview, "", "tab_home_active", "tab_home_active"); |         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); |         m_param_panel = new ParamsPanel(m_tabpanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -420,9 +420,59 @@ void Sidebar::priv::hide_rich_tip(wxButton* btn) | ||||||
| 
 | 
 | ||||||
| // Sidebar / public
 | // Sidebar / public
 | ||||||
| 
 | 
 | ||||||
|  | static struct DynamicFilamentList : DynamicList | ||||||
|  | { | ||||||
|  |     std::vector<std::pair<wxString, wxBitmap *>> items; | ||||||
|  | 
 | ||||||
|  |     void apply_on(Choice *c) override | ||||||
|  |     { | ||||||
|  |         if (items.empty()) | ||||||
|  |             update(true); | ||||||
|  |         auto cb = dynamic_cast<ComboBox *>(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) | Sidebar::Sidebar(Plater *parent) | ||||||
|     : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(42 * wxGetApp().em_unit(), -1)), p(new priv(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 = 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.
 |     // but this cause the bad layout of the sidebar, when all infoboxes appear.
 | ||||||
|  | @ -1021,6 +1071,7 @@ void Sidebar::update_presets(Preset::Type preset_type) | ||||||
|         for (size_t i = 0; i < filament_cnt; i++) |         for (size_t i = 0; i < filament_cnt; i++) | ||||||
|             p->combos_filament[i]->update(); |             p->combos_filament[i]->update(); | ||||||
| 
 | 
 | ||||||
|  |         dynamic_filament_list.update(); | ||||||
|         break; |         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->Layout(); | ||||||
|     p->m_panel_filament_title->Refresh(); |     p->m_panel_filament_title->Refresh(); | ||||||
|     update_ui_from_settings(); |     update_ui_from_settings(); | ||||||
|  |     dynamic_filament_list.update(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Sidebar::on_bed_type_change(BedType bed_type) | void Sidebar::on_bed_type_change(BedType bed_type) | ||||||
|  | @ -1354,6 +1406,7 @@ void Sidebar::sync_ams_list() | ||||||
|         c->update(); |         c->update(); | ||||||
|     wxGetApp().get_tab(Preset::TYPE_PRINT)->update(); |     wxGetApp().get_tab(Preset::TYPE_PRINT)->update(); | ||||||
|     wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); |     wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); | ||||||
|  |     dynamic_filament_list.update(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ObjectList* Sidebar::obj_list() | 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().preset_bundle->set_filament_preset(idx, preset_name); | ||||||
|         wxGetApp().plater()->update_project_dirty_from_presets(); |         wxGetApp().plater()->update_project_dirty_from_presets(); | ||||||
|         wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); |         wxGetApp().preset_bundle->export_selections(*wxGetApp().app_config); | ||||||
|  |         dynamic_filament_list.update(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     bool select_preset = !combo->selection_is_changed_according_to_physical_printers(); |     bool select_preset = !combo->selection_is_changed_according_to_physical_printers(); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 chunmao.guo
						chunmao.guo