mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 20:51:12 -06:00 
			
		
		
		
	Merge branch 'profile_changes_reset' into updating
This commit is contained in:
		
						commit
						62d67d35ec
					
				
					 28 changed files with 803 additions and 394 deletions
				
			
		|  | @ -212,6 +212,8 @@ add_library(libslic3r_gui STATIC | |||
|     ${LIBDIR}/slic3r/GUI/RammingChart.hpp | ||||
|     ${LIBDIR}/slic3r/GUI/BonjourDialog.cpp | ||||
|     ${LIBDIR}/slic3r/GUI/BonjourDialog.hpp | ||||
|     ${LIBDIR}/slic3r/GUI/ButtonsDescription.cpp | ||||
|     ${LIBDIR}/slic3r/GUI/ButtonsDescription.hpp | ||||
|     ${LIBDIR}/slic3r/Config/Snapshot.cpp | ||||
|     ${LIBDIR}/slic3r/Config/Snapshot.hpp | ||||
|     ${LIBDIR}/slic3r/Config/Version.cpp | ||||
|  |  | |||
|  | @ -206,6 +206,44 @@ t_config_option_keys ConfigBase::diff(const ConfigBase &other) const | |||
|     return diff; | ||||
| } | ||||
| 
 | ||||
| template<class T> | ||||
| void add_correct_opts_to_diff(const std::string &opt_key, t_config_option_keys& vec, const ConfigBase &other, const ConfigBase *this_c) | ||||
| { | ||||
| 	const T* opt_init = static_cast<const T*>(other.option(opt_key)); | ||||
| 	const T* opt_cur = static_cast<const T*>(this_c->option(opt_key)); | ||||
| 	int opt_init_max_id = opt_init->values.size() - 1; | ||||
| 	for (int i = 0; i < opt_cur->values.size(); i++) | ||||
| 	{ | ||||
| 		int init_id = i <= opt_init_max_id ? i : 0; | ||||
| 		if (opt_cur->values[i] != opt_init->values[init_id]) | ||||
| 			vec.emplace_back(opt_key + "#" + std::to_string(i)); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| t_config_option_keys ConfigBase::deep_diff(const ConfigBase &other) const | ||||
| { | ||||
|     t_config_option_keys diff; | ||||
|     for (const t_config_option_key &opt_key : this->keys()) { | ||||
|         const ConfigOption *this_opt  = this->option(opt_key); | ||||
|         const ConfigOption *other_opt = other.option(opt_key); | ||||
| 		if (this_opt != nullptr && other_opt != nullptr && *this_opt != *other_opt) | ||||
| 		{ | ||||
| 			if (opt_key == "bed_shape"){ diff.emplace_back(opt_key);		continue; } | ||||
| 			switch (other_opt->type()) | ||||
| 			{ | ||||
| 			case coInts:	add_correct_opts_to_diff<ConfigOptionInts		>(opt_key, diff, other, this);	break; | ||||
| 			case coBools:	add_correct_opts_to_diff<ConfigOptionBools		>(opt_key, diff, other, this);	break; | ||||
| 			case coFloats:	add_correct_opts_to_diff<ConfigOptionFloats		>(opt_key, diff, other, this);	break; | ||||
| 			case coStrings:	add_correct_opts_to_diff<ConfigOptionStrings	>(opt_key, diff, other, this);	break; | ||||
| 			case coPercents:add_correct_opts_to_diff<ConfigOptionPercents	>(opt_key, diff, other, this);	break; | ||||
| 			case coPoints:	add_correct_opts_to_diff<ConfigOptionPoints		>(opt_key, diff, other, this);	break; | ||||
| 			default:		diff.emplace_back(opt_key);		break; | ||||
| 			} | ||||
| 		} | ||||
|     } | ||||
|     return diff; | ||||
| } | ||||
| 
 | ||||
| t_config_option_keys ConfigBase::equal(const ConfigBase &other) const | ||||
| { | ||||
|     t_config_option_keys equal; | ||||
|  |  | |||
|  | @ -1047,6 +1047,9 @@ public: | |||
|     void apply_only(const ConfigBase &other, const t_config_option_keys &keys, bool ignore_nonexistent = false); | ||||
|     bool equals(const ConfigBase &other) const { return this->diff(other).empty(); } | ||||
|     t_config_option_keys diff(const ConfigBase &other) const; | ||||
| 	// Use deep_diff to correct return of changed options,
 | ||||
| 	// considering individual options for each extruder
 | ||||
| 	t_config_option_keys deep_diff(const ConfigBase &other) const; | ||||
|     t_config_option_keys equal(const ConfigBase &other) const; | ||||
|     std::string serialize(const t_config_option_key &opt_key) const; | ||||
|     // Set a configuration value from a string, it will call an overridable handle_legacy() 
 | ||||
|  |  | |||
|  | @ -1,3 +1,6 @@ | |||
| #ifndef slic3r_2DBed_hpp_ | ||||
| #define slic3r_2DBed_hpp_ | ||||
| 
 | ||||
| #include <wx/wx.h> | ||||
| #include "Config.hpp" | ||||
| 
 | ||||
|  | @ -45,3 +48,5 @@ public: | |||
| 
 | ||||
| } // GUI
 | ||||
| } // Slic3r
 | ||||
| 
 | ||||
| #endif /* slic3r_2DBed_hpp_ */ | ||||
|  |  | |||
|  | @ -1,3 +1,5 @@ | |||
| #ifndef slic3r_BedShapeDialog_hpp_ | ||||
| #define slic3r_BedShapeDialog_hpp_ | ||||
| // The bed shape dialog.
 | ||||
| // The dialog opens from Print Settins tab->Bed Shape : Set...
 | ||||
| 
 | ||||
|  | @ -49,3 +51,6 @@ public: | |||
| 
 | ||||
| } // GUI
 | ||||
| } // Slic3r
 | ||||
| 
 | ||||
| 
 | ||||
| #endif  /* slic3r_BedShapeDialog_hpp_ */ | ||||
|  |  | |||
							
								
								
									
										44
									
								
								xs/src/slic3r/GUI/ButtonsDescription.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								xs/src/slic3r/GUI/ButtonsDescription.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,44 @@ | |||
| #include "ButtonsDescription.hpp" | ||||
| #include <wx/sizer.h> | ||||
| #include <wx/stattext.h> | ||||
| #include <wx/statbmp.h> | ||||
| 
 | ||||
| #include "GUI.hpp" | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| namespace GUI { | ||||
| 
 | ||||
| ButtonsDescription::ButtonsDescription(wxWindow* parent, t_icon_descriptions* icon_descriptions) : | ||||
| 	wxDialog(parent, wxID_ANY, "Buttons Description", wxDefaultPosition, wxDefaultSize), | ||||
| 	m_icon_descriptions(icon_descriptions) | ||||
| { | ||||
| 	auto grid_sizer = new wxFlexGridSizer(3, 20, 20); | ||||
| 
 | ||||
| 	auto main_sizer = new wxBoxSizer(wxVERTICAL); | ||||
| 	main_sizer->Add(grid_sizer, 0, wxEXPAND | wxALL, 20); | ||||
| 
 | ||||
| 	for (auto pair : *m_icon_descriptions) | ||||
| 	{ | ||||
| 		auto icon = new wxStaticBitmap(this, wxID_ANY, *pair.first); | ||||
| 		grid_sizer->Add(icon, -1, wxALIGN_CENTRE_VERTICAL); | ||||
| 
 | ||||
| 		std::istringstream f(pair.second); | ||||
| 		std::string s; | ||||
| 		getline(f, s, ';'); | ||||
| 		auto description = new wxStaticText(this, wxID_ANY, _(s)); | ||||
| 		grid_sizer->Add(description, -1, wxALIGN_CENTRE_VERTICAL); | ||||
| 		getline(f, s, ';'); | ||||
| 		description = new wxStaticText(this, wxID_ANY, _(s)); | ||||
| 		grid_sizer->Add(description, -1, wxALIGN_CENTRE_VERTICAL | wxEXPAND); | ||||
| 	} | ||||
| 
 | ||||
| 	auto button = CreateStdDialogButtonSizer(wxOK); | ||||
| 	main_sizer->Add(button, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, 10); | ||||
| 
 | ||||
| 	SetSizer(main_sizer); | ||||
| 	main_sizer->SetSizeHints(this); | ||||
| } | ||||
| 
 | ||||
| } // GUI
 | ||||
| } // Slic3r
 | ||||
| 
 | ||||
							
								
								
									
										27
									
								
								xs/src/slic3r/GUI/ButtonsDescription.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								xs/src/slic3r/GUI/ButtonsDescription.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,27 @@ | |||
| #ifndef slic3r_ButtonsDescription_hpp | ||||
| #define slic3r_ButtonsDescription_hpp | ||||
| 
 | ||||
| #include <wx/dialog.h> | ||||
| #include <vector> | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| namespace GUI { | ||||
| 
 | ||||
| using t_icon_descriptions = std::vector<std::pair<wxBitmap*, std::string>>; | ||||
| 
 | ||||
| class ButtonsDescription : public wxDialog | ||||
| { | ||||
| 	t_icon_descriptions* m_icon_descriptions; | ||||
| public: | ||||
| 	ButtonsDescription(wxWindow* parent, t_icon_descriptions* icon_descriptions); | ||||
| 	~ButtonsDescription(){} | ||||
| 
 | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| } // GUI
 | ||||
| } // Slic3r
 | ||||
| 
 | ||||
| 
 | ||||
| #endif  | ||||
| 
 | ||||
|  | @ -20,23 +20,22 @@ namespace Slic3r { namespace GUI { | |||
| 
 | ||||
| 	void Field::PostInitialize(){ | ||||
| 		auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); | ||||
| 		m_Undo_btn			= new wxButton(m_parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); | ||||
| 		m_Undo_to_sys_btn	= new wxButton(m_parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); | ||||
| 		auto sz = 16; | ||||
| 	#ifdef __WXGTK__ | ||||
| 		sz = 28; | ||||
| 	#endif // __WXGTK__
 | ||||
| 		m_Undo_btn			= new wxButton(m_parent, wxID_ANY, "", wxDefaultPosition, wxSize(sz,sz), wxNO_BORDER); | ||||
| 		m_Undo_to_sys_btn	= new wxButton(m_parent, wxID_ANY, "", wxDefaultPosition, wxSize(sz,sz), wxNO_BORDER); | ||||
| 		if (wxMSW) { | ||||
| 			m_Undo_btn->SetBackgroundColour(color); | ||||
| 			m_Undo_to_sys_btn->SetBackgroundColour(color); | ||||
| 		} | ||||
| 		m_Undo_btn->SetBitmap(wxBitmap(from_u8(var("bullet_white.png")), wxBITMAP_TYPE_PNG)); | ||||
| 		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(); })); | ||||
| 
 | ||||
| 		BUILD(); | ||||
| 	} | ||||
| 
 | ||||
| 	void Field::set_nonsys_btn_icon(const std::string& icon){ | ||||
| 		m_Undo_to_sys_btn->SetBitmap(wxBitmap(from_u8(var(icon)), wxBITMAP_TYPE_PNG)); | ||||
| 	} | ||||
| 
 | ||||
| 	void Field::on_kill_focus(wxEvent& event) { | ||||
|         // Without this, there will be nasty focus bugs on Windows.
 | ||||
|         // Also, docs for wxEvent::Skip() say "In general, it is recommended to skip all 
 | ||||
|  | @ -81,12 +80,13 @@ namespace Slic3r { namespace GUI { | |||
| 		return std::regex_match(string, regex_pattern); | ||||
| 	} | ||||
| 
 | ||||
| 	boost::any Field::get_value_by_opt_type(wxString& str) | ||||
| // 	boost::any Field::get_value_by_opt_type(wxString& str)
 | ||||
| 	void Field::get_value_by_opt_type(wxString& str) | ||||
| 	{ | ||||
| 		boost::any ret_val; | ||||
| // 		boost::any m_value;
 | ||||
| 		switch (m_opt.type){ | ||||
| 		case coInt: | ||||
| 			ret_val = wxAtoi(str); | ||||
| 			m_value = wxAtoi(str); | ||||
| 			break; | ||||
| 		case coPercent: | ||||
| 		case coPercents: | ||||
|  | @ -96,18 +96,18 @@ namespace Slic3r { namespace GUI { | |||
| 				str.RemoveLast(); | ||||
| 			double val; | ||||
| 			str.ToCDouble(&val); | ||||
| 			ret_val = val; | ||||
| 			m_value = val; | ||||
| 			break; } | ||||
| 		case coString: | ||||
| 		case coStrings: | ||||
| 		case coFloatOrPercent: | ||||
| 			ret_val = str.ToStdString(); | ||||
| 			m_value = str.ToStdString(); | ||||
| 			break; | ||||
| 		default: | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 		return ret_val; | ||||
| // 		return m_value;
 | ||||
| 	} | ||||
| 
 | ||||
| 	void TextCtrl::BUILD() { | ||||
|  | @ -183,12 +183,12 @@ namespace Slic3r { namespace GUI { | |||
|         window = dynamic_cast<wxWindow*>(temp); | ||||
|     }	 | ||||
| 
 | ||||
| 	boost::any TextCtrl::get_value() | ||||
| 	boost::any& TextCtrl::get_value() | ||||
| 	{ | ||||
| 		wxString ret_str = static_cast<wxTextCtrl*>(window)->GetValue(); | ||||
| 		boost::any ret_val = get_value_by_opt_type(ret_str); | ||||
| 		/*boost::any ret_val*/get_value_by_opt_type(ret_str); | ||||
| 
 | ||||
| 		return ret_val; | ||||
| 		return m_value;//ret_val;
 | ||||
| 	} | ||||
| 
 | ||||
| 	void TextCtrl::enable() { dynamic_cast<wxTextCtrl*>(window)->Enable(); dynamic_cast<wxTextCtrl*>(window)->SetEditable(true); } | ||||
|  | @ -216,15 +216,15 @@ void CheckBox::BUILD() { | |||
| 	window = dynamic_cast<wxWindow*>(temp); | ||||
| } | ||||
| 
 | ||||
| boost::any CheckBox::get_value() | ||||
| boost::any& CheckBox::get_value() | ||||
| { | ||||
| 	boost::any ret_val; | ||||
| // 	boost::any m_value;
 | ||||
| 	bool value = dynamic_cast<wxCheckBox*>(window)->GetValue(); | ||||
| 	if (m_opt.type == coBool) | ||||
| 		ret_val = static_cast<bool>(value); | ||||
| 		m_value = static_cast<bool>(value); | ||||
| 	else | ||||
| 		ret_val = static_cast<unsigned char>(value); | ||||
|  	return ret_val; | ||||
| 		m_value = static_cast<unsigned char>(value); | ||||
|  	return m_value; | ||||
| } | ||||
| 
 | ||||
| int undef_spin_val = -9999;		//! Probably, It's not necessary
 | ||||
|  | @ -424,7 +424,33 @@ void Choice::set_value(const boost::any& value, bool change_event) | |||
| 		break; | ||||
| 	} | ||||
| 	case coEnum:{ | ||||
| 		dynamic_cast<wxComboBox*>(window)->SetSelection(boost::any_cast<int>(value)); | ||||
| 		int val = boost::any_cast<int>(value); | ||||
| 		if (m_opt_id.compare("external_fill_pattern") == 0) | ||||
| 		{ | ||||
| 			if (!m_opt.enum_values.empty()){ | ||||
| 				std::string key; | ||||
| 				t_config_enum_values map_names = ConfigOptionEnum<InfillPattern>::get_enum_values();				 | ||||
| 				for (auto it : map_names) { | ||||
| 					if (val == it.second) { | ||||
| 						key = it.first; | ||||
| 						break; | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				size_t idx = 0; | ||||
| 				for (auto el : m_opt.enum_values) | ||||
| 				{ | ||||
| 					if (el.compare(key) == 0) | ||||
| 						break; | ||||
| 					++idx; | ||||
| 				} | ||||
| 
 | ||||
| 				val = idx == m_opt.enum_values.size() ? 0 : idx; | ||||
| 			} | ||||
| 			else | ||||
| 				val = 0; | ||||
| 		} | ||||
| 		dynamic_cast<wxComboBox*>(window)->SetSelection(val); | ||||
| 		break; | ||||
| 	} | ||||
| 	default: | ||||
|  | @ -454,16 +480,16 @@ void Choice::set_values(const std::vector<std::string>& values) | |||
| 	m_disable_change_event = false; | ||||
| } | ||||
| 
 | ||||
| boost::any Choice::get_value() | ||||
| boost::any& Choice::get_value() | ||||
| { | ||||
| 	boost::any ret_val; | ||||
| // 	boost::any m_value;
 | ||||
| 	wxString ret_str = static_cast<wxComboBox*>(window)->GetValue();	 | ||||
| 
 | ||||
| 	if (m_opt_id == "support") | ||||
| 		return ret_str; | ||||
| 		return m_value = boost::any(ret_str);//ret_str;
 | ||||
| 
 | ||||
| 	if (m_opt.type != coEnum) | ||||
| 		ret_val = get_value_by_opt_type(ret_str); | ||||
| 		/*m_value = */get_value_by_opt_type(ret_str); | ||||
| 	else | ||||
| 	{ | ||||
| 		int ret_enum = static_cast<wxComboBox*>(window)->GetSelection();  | ||||
|  | @ -474,22 +500,22 @@ boost::any Choice::get_value() | |||
| 				t_config_enum_values map_names = ConfigOptionEnum<InfillPattern>::get_enum_values(); | ||||
| 				int value = map_names.at(key); | ||||
| 
 | ||||
| 				ret_val = static_cast<InfillPattern>(value); | ||||
| 				m_value = static_cast<InfillPattern>(value); | ||||
| 			} | ||||
| 			else | ||||
| 				ret_val = static_cast<InfillPattern>(0); | ||||
| 				m_value = static_cast<InfillPattern>(0); | ||||
| 		} | ||||
| 		if (m_opt_id.compare("fill_pattern") == 0) | ||||
| 			ret_val = static_cast<InfillPattern>(ret_enum); | ||||
| 			m_value = static_cast<InfillPattern>(ret_enum); | ||||
| 		else if (m_opt_id.compare("gcode_flavor") == 0) | ||||
| 			ret_val = static_cast<GCodeFlavor>(ret_enum); | ||||
| 			m_value = static_cast<GCodeFlavor>(ret_enum); | ||||
| 		else if (m_opt_id.compare("support_material_pattern") == 0) | ||||
| 			ret_val = static_cast<SupportMaterialPattern>(ret_enum); | ||||
| 			m_value = static_cast<SupportMaterialPattern>(ret_enum); | ||||
| 		else if (m_opt_id.compare("seam_position") == 0) | ||||
| 			ret_val = static_cast<SeamPosition>(ret_enum); | ||||
| 			m_value = static_cast<SeamPosition>(ret_enum); | ||||
| 	}	 | ||||
| 
 | ||||
| 	return ret_val; | ||||
| 	return m_value; | ||||
| } | ||||
| 
 | ||||
| void ColourPicker::BUILD() | ||||
|  | @ -509,14 +535,14 @@ void ColourPicker::BUILD() | |||
| 	temp->SetToolTip(get_tooltip_text(clr)); | ||||
| } | ||||
| 
 | ||||
| boost::any ColourPicker::get_value(){ | ||||
| 	boost::any ret_val; | ||||
| boost::any& ColourPicker::get_value(){ | ||||
| // 	boost::any m_value;
 | ||||
| 
 | ||||
| 	auto colour = static_cast<wxColourPickerCtrl*>(window)->GetColour(); | ||||
| 	auto clr_str = wxString::Format(wxT("#%02X%02X%02X"), colour.Red(), colour.Green(), colour.Blue()); | ||||
| 	ret_val = clr_str.ToStdString(); | ||||
| 	m_value = clr_str.ToStdString(); | ||||
| 
 | ||||
| 	return ret_val; | ||||
| 	return m_value; | ||||
| } | ||||
| 
 | ||||
| void PointCtrl::BUILD() | ||||
|  | @ -580,7 +606,7 @@ void PointCtrl::set_value(const boost::any& value, bool change_event) | |||
| 	set_value(pt, change_event); | ||||
| } | ||||
| 
 | ||||
| boost::any PointCtrl::get_value() | ||||
| boost::any& PointCtrl::get_value() | ||||
| { | ||||
| 	Pointf ret_point; | ||||
| 	double val; | ||||
|  | @ -588,7 +614,7 @@ boost::any PointCtrl::get_value() | |||
| 	ret_point.x = val; | ||||
| 	y_textctrl->GetValue().ToDouble(&val); | ||||
| 	ret_point.y = val; | ||||
| 	return ret_point; | ||||
| 	return m_value = ret_point; | ||||
| } | ||||
| 
 | ||||
| } // GUI
 | ||||
|  |  | |||
|  | @ -85,22 +85,18 @@ public: | |||
|      | ||||
|     /// Gets a boost::any representing this control.
 | ||||
|     /// subclasses should overload with a specific version
 | ||||
|     virtual boost::any	get_value() = 0; | ||||
|     virtual boost::any&	get_value() = 0; | ||||
| 
 | ||||
|     virtual void		enable() = 0; | ||||
|     virtual void		disable() = 0; | ||||
| 
 | ||||
| 	wxStaticText*		m_Label = nullptr; | ||||
| 	wxButton*			m_Undo_btn = nullptr; | ||||
| 	wxButton*			m_Undo_to_sys_btn = nullptr; | ||||
| 
 | ||||
|     /// Fires the enable or disable function, based on the input.
 | ||||
| 	/// Fires the enable or disable function, based on the input.
 | ||||
|     inline void			toggle(bool en) { en ? enable() : disable(); } | ||||
| 
 | ||||
| 	virtual wxString	get_tooltip_text(const wxString& default_string); | ||||
| 
 | ||||
|     // set icon to "UndoToSystemValue" button according to an inheritance of preset
 | ||||
| 	void				set_nonsys_btn_icon(const std::string& icon); | ||||
| //	void				set_nonsys_btn_icon(const wxBitmap& icon);
 | ||||
| 
 | ||||
|     Field(const ConfigOptionDef& opt, const t_config_option_key& id) : m_opt(opt), m_opt_id(id) {}; | ||||
|     Field(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : m_parent(parent), m_opt(opt), m_opt_id(id) {}; | ||||
|  | @ -110,7 +106,8 @@ public: | |||
|     virtual wxWindow*	getWindow() { return nullptr; } | ||||
| 
 | ||||
| 	bool				is_matched(const std::string& string, const std::string& pattern); | ||||
| 	boost::any			get_value_by_opt_type(wxString& str); | ||||
| // 	boost::any			get_value_by_opt_type(wxString& str);
 | ||||
| 	void				get_value_by_opt_type(wxString& str); | ||||
| 
 | ||||
|     /// Factory method for generating new derived classes.
 | ||||
|     template<class T> | ||||
|  | @ -120,6 +117,71 @@ public: | |||
|         p->PostInitialize(); | ||||
| 		return std::move(p); //!p;
 | ||||
|     } | ||||
| 
 | ||||
|     bool 	set_undo_bitmap(const wxBitmap *bmp) { | ||||
|     	if (m_undo_bitmap != bmp) { | ||||
|     		m_undo_bitmap = bmp; | ||||
|     		m_Undo_btn->SetBitmap(*bmp); | ||||
|     		return true; | ||||
|     	} | ||||
|     	return false; | ||||
|     } | ||||
| 
 | ||||
|     bool 	set_undo_to_sys_bitmap(const wxBitmap *bmp) { | ||||
|     	if (m_undo_to_sys_bitmap != bmp) { | ||||
|     		m_undo_to_sys_bitmap = bmp; | ||||
|     		m_Undo_to_sys_btn->SetBitmap(*bmp); | ||||
|     		return true; | ||||
|     	} | ||||
|     	return false; | ||||
|     } | ||||
| 
 | ||||
| 	bool	set_label_colour(const wxColour *clr) { | ||||
| 		if (m_Label == nullptr) return false; | ||||
| 		if (m_label_color != clr) { | ||||
| 			m_label_color = clr; | ||||
| 			m_Label->SetForegroundColour(*clr); | ||||
| 			m_Label->Refresh(true); | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	bool 	set_undo_tooltip(const wxString *tip) { | ||||
| 		if (m_undo_tooltip != tip) { | ||||
| 			m_undo_tooltip = tip; | ||||
| 			m_Undo_btn->SetToolTip(*tip); | ||||
| 			return true; | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	bool 	set_undo_to_sys_tooltip(const wxString *tip) { | ||||
| 		if (m_undo_to_sys_tooltip != tip) { | ||||
| 			m_undo_to_sys_tooltip = tip; | ||||
| 			m_Undo_to_sys_btn->SetToolTip(*tip); | ||||
| 			return true; | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| protected: | ||||
| 	wxButton*			m_Undo_btn = nullptr; | ||||
| 	// Bitmap and Tooltip text for m_Undo_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one.
 | ||||
| 	const wxBitmap*		m_undo_bitmap = nullptr; | ||||
| 	const wxString*		m_undo_tooltip = nullptr; | ||||
| 	wxButton*			m_Undo_to_sys_btn = nullptr; | ||||
| 	// Bitmap and Tooltip text for m_Undo_to_sys_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one.
 | ||||
| 	const wxBitmap*		m_undo_to_sys_bitmap = nullptr; | ||||
| 	const wxString*		m_undo_to_sys_tooltip = nullptr; | ||||
| 
 | ||||
| 	wxStaticText*		m_Label = nullptr; | ||||
| 	// Color for Label. The wxColour will be updated only if the new wxColour pointer differs from the currently rendered one.
 | ||||
| 	const wxColour*		m_label_color; | ||||
| 
 | ||||
| 	// current value
 | ||||
| 	boost::any			m_value; | ||||
| 
 | ||||
| 	friend class OptionsGroup; | ||||
| }; | ||||
| 
 | ||||
| /// Convenience function, accepts a const reference to t_field and checks to see whether 
 | ||||
|  | @ -153,7 +215,7 @@ public: | |||
| 		m_disable_change_event = false; | ||||
|     } | ||||
| 
 | ||||
| 	boost::any		get_value() override; | ||||
| 	boost::any&		get_value() override; | ||||
| 
 | ||||
|     virtual void	enable(); | ||||
|     virtual void	disable(); | ||||
|  | @ -180,7 +242,7 @@ public: | |||
| 		dynamic_cast<wxCheckBox*>(window)->SetValue(boost::any_cast<bool>(value)); | ||||
| 		m_disable_change_event = false; | ||||
| 	} | ||||
| 	boost::any		get_value() override; | ||||
| 	boost::any&		get_value() override; | ||||
| 
 | ||||
| 	void			enable() override { dynamic_cast<wxCheckBox*>(window)->Enable(); } | ||||
| 	void			disable() override { dynamic_cast<wxCheckBox*>(window)->Disable(); } | ||||
|  | @ -210,8 +272,9 @@ public: | |||
| 		dynamic_cast<wxSpinCtrl*>(window)->SetValue(tmp_value); | ||||
| 		m_disable_change_event = false; | ||||
| 	} | ||||
| 	boost::any		get_value() override { | ||||
| 		return boost::any(tmp_value); | ||||
| 	boost::any&		get_value() override { | ||||
| // 		return boost::any(tmp_value);
 | ||||
| 		return m_value = tmp_value; | ||||
| 	} | ||||
| 
 | ||||
| 	void			enable() override { dynamic_cast<wxSpinCtrl*>(window)->Enable(); } | ||||
|  | @ -233,7 +296,7 @@ public: | |||
| 	void			set_value(const std::string& value, bool change_event = false); | ||||
| 	void			set_value(const boost::any& value, bool change_event = false); | ||||
| 	void			set_values(const std::vector<std::string> &values); | ||||
| 	boost::any		get_value() override; | ||||
| 	boost::any&		get_value() override; | ||||
| 
 | ||||
| 	void			enable() override { dynamic_cast<wxComboBox*>(window)->Enable(); }; | ||||
| 	void			disable() override{ dynamic_cast<wxComboBox*>(window)->Disable(); }; | ||||
|  | @ -261,7 +324,7 @@ public: | |||
| 		m_disable_change_event = false; | ||||
| 	} | ||||
| 
 | ||||
| 	boost::any		get_value() override; | ||||
| 	boost::any&		get_value() override; | ||||
| 
 | ||||
| 	void			enable() override { dynamic_cast<wxColourPickerCtrl*>(window)->Enable(); }; | ||||
| 	void			disable() override{ dynamic_cast<wxColourPickerCtrl*>(window)->Disable(); }; | ||||
|  | @ -283,7 +346,7 @@ public: | |||
| 
 | ||||
| 	void			set_value(const Pointf& value, bool change_event = false); | ||||
| 	void			set_value(const boost::any& value, bool change_event = false); | ||||
| 	boost::any		get_value() override; | ||||
| 	boost::any&		get_value() override; | ||||
| 
 | ||||
| 	void			enable() override { | ||||
| 		x_textctrl->Enable(); | ||||
|  |  | |||
|  | @ -187,6 +187,7 @@ PresetBundle *g_PresetBundle= nullptr; | |||
| PresetUpdater *g_PresetUpdater = nullptr; | ||||
| wxColour    g_color_label_modified; | ||||
| wxColour    g_color_label_sys; | ||||
| wxColour    g_color_label_default; | ||||
| 
 | ||||
| std::vector<Tab *> g_tabs_list; | ||||
| 
 | ||||
|  | @ -206,6 +207,7 @@ static void init_label_colours() | |||
| 		g_color_label_modified = wxColour(253, 111, 40); | ||||
| 		g_color_label_sys = wxColour(115, 220, 103); | ||||
| 	} | ||||
| 	g_color_label_default = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); | ||||
| } | ||||
| 
 | ||||
| void set_wxapp(wxApp *app) | ||||
|  | @ -699,6 +701,10 @@ const wxColour& get_sys_label_clr() { | |||
| 	return g_color_label_sys; | ||||
| } | ||||
| 
 | ||||
| const wxColour& get_default_label_clr() { | ||||
| 	return g_color_label_default; | ||||
| } | ||||
| 
 | ||||
| unsigned get_colour_approx_luma(const wxColour &colour) | ||||
| { | ||||
| 	double r = colour.Red(); | ||||
|  |  | |||
|  | @ -86,6 +86,7 @@ PresetBundle* get_preset_bundle(); | |||
| 
 | ||||
| const wxColour& get_modified_label_clr(); | ||||
| const wxColour& get_sys_label_clr(); | ||||
| const wxColour& get_default_label_clr(); | ||||
| unsigned get_colour_approx_luma(const wxColour &colour); | ||||
| 
 | ||||
| extern void add_config_menu(wxMenuBar *menu, int event_preferences_changed, int event_language_change); | ||||
|  |  | |||
|  | @ -90,8 +90,8 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co | |||
| 		field->m_Undo_btn->Hide(); | ||||
| 		field->m_Undo_to_sys_btn->Hide(); | ||||
| 	} | ||||
| 	if (nonsys_btn_icon != nullptr) | ||||
| 		field->set_nonsys_btn_icon(nonsys_btn_icon()); | ||||
| //	if (nonsys_btn_icon != nullptr)
 | ||||
| //		field->set_nonsys_btn_icon(*nonsys_btn_icon);
 | ||||
|      | ||||
| 	// assign function objects for callbacks, etc.
 | ||||
|     return field; | ||||
|  | @ -149,7 +149,8 @@ void OptionsGroup::append_line(const Line& line, wxStaticText**	colored_Label/* | |||
|     // If there's a widget, build it and add the result to the sizer.
 | ||||
| 	if (line.widget != nullptr) { | ||||
| 		auto wgt = line.widget(parent()); | ||||
| 		grid_sizer->Add(wgt, 0, wxEXPAND | wxBOTTOM | wxTOP, wxOSX ? 0 : 5); | ||||
| 		// If widget doesn't have label, don't use border
 | ||||
| 		grid_sizer->Add(wgt, 0, wxEXPAND | wxBOTTOM | wxTOP, (wxOSX || line.label.IsEmpty()) ? 0 : 5); | ||||
| 		if (colored_Label != nullptr) *colored_Label = label; | ||||
| 		return; | ||||
| 	} | ||||
|  |  | |||
|  | @ -1,3 +1,6 @@ | |||
| #ifndef slic3r_OptionsGroup_hpp_ | ||||
| #define slic3r_OptionsGroup_hpp_ | ||||
| 
 | ||||
| #include <wx/wx.h> | ||||
| #include <wx/stattext.h> | ||||
| #include <wx/settings.h> | ||||
|  | @ -86,7 +89,7 @@ public: | |||
|     wxFont			sidetext_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) }; | ||||
|     wxFont			label_font {wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT) }; | ||||
| 
 | ||||
| 	std::function<std::string()>	nonsys_btn_icon{ nullptr }; | ||||
| //	std::function<const wxBitmap&()>	nonsys_btn_icon{ nullptr };
 | ||||
| 
 | ||||
|     /// Returns a copy of the pointer of the parent wxWindow.
 | ||||
|     /// Accessor function is because users are not allowed to change the parent
 | ||||
|  | @ -204,3 +207,5 @@ public: | |||
| }; | ||||
| 
 | ||||
| }} | ||||
| 
 | ||||
| #endif /* slic3r_OptionsGroup_hpp_ */ | ||||
|  |  | |||
|  | @ -1,3 +1,6 @@ | |||
| #ifndef slic3r_Preferences_hpp_ | ||||
| #define slic3r_Preferences_hpp_ | ||||
| 
 | ||||
| #include "GUI.hpp" | ||||
| 
 | ||||
| #include <wx/dialog.h> | ||||
|  | @ -25,3 +28,5 @@ public: | |||
| } // GUI
 | ||||
| } // Slic3r
 | ||||
| 
 | ||||
| 
 | ||||
| #endif /* slic3r_Preferences_hpp_ */ | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ | |||
| 
 | ||||
| #include "Preset.hpp" | ||||
| #include "AppConfig.hpp" | ||||
| #include "BitmapCache.hpp" | ||||
| 
 | ||||
| #include <fstream> | ||||
| #include <stdexcept> | ||||
|  | @ -340,7 +341,8 @@ PresetCollection::PresetCollection(Preset::Type type, const std::vector<std::str | |||
|     m_type(type), | ||||
|     m_edited_preset(type, "", false), | ||||
|     m_idx_selected(0), | ||||
|     m_bitmap_main_frame(new wxBitmap) | ||||
|     m_bitmap_main_frame(new wxBitmap), | ||||
| 	m_bitmap_cache(new GUI::BitmapCache) | ||||
| { | ||||
|     // Insert just the default preset.
 | ||||
|     m_presets.emplace_back(Preset(type, "- default -", true)); | ||||
|  | @ -352,6 +354,8 @@ PresetCollection::~PresetCollection() | |||
| { | ||||
|     delete m_bitmap_main_frame; | ||||
|     m_bitmap_main_frame = nullptr; | ||||
| 	delete m_bitmap_cache; | ||||
| 	m_bitmap_cache = nullptr; | ||||
| } | ||||
| 
 | ||||
| void PresetCollection::reset(bool delete_files) | ||||
|  | @ -585,17 +589,41 @@ void PresetCollection::update_platter_ui(wxBitmapComboBox *ui) | |||
|     // Otherwise fill in the list from scratch.
 | ||||
|     ui->Freeze(); | ||||
|     ui->Clear(); | ||||
| 	std::map<wxString, bool> nonsys_presets; | ||||
| 
 | ||||
| 	const Preset &selected_preset = this->get_selected_preset(); | ||||
| 	// Show wide icons if the currently selected preset is not compatible with the current printer,
 | ||||
| 	// and draw a red flag in front of the selected preset.
 | ||||
| 	bool wide_icons = !selected_preset.is_compatible && m_bitmap_incompatible != nullptr; | ||||
| 
 | ||||
| 	std::map<wxString, wxBitmap*> nonsys_presets; | ||||
| 	wxString selected = ""; | ||||
|     for (size_t i = this->m_presets.front().is_visible ? 0 : 1; i < this->m_presets.size(); ++ i) { | ||||
| 	if (!this->m_presets.front().is_visible) | ||||
| 		ui->Append("------- System presets -------", wxNullBitmap); | ||||
| 	for (size_t i = this->m_presets.front().is_visible ? 0 : 1; i < this->m_presets.size(); ++i) { | ||||
|         const Preset &preset = this->m_presets[i]; | ||||
|         if (! preset.is_visible || (! preset.is_compatible && i != m_idx_selected)) | ||||
|             continue; | ||||
|         const wxBitmap *bmp = (i == 0 || preset.is_compatible) ? m_bitmap_main_frame : m_bitmap_incompatible; | ||||
| //         ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()),
 | ||||
| //             (bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp);
 | ||||
| // 		if (i == m_idx_selected)
 | ||||
| //             ui->SetSelection(ui->GetCount() - 1);
 | ||||
| 		std::string   bitmap_key = ""; | ||||
| 		// If the filament preset is not compatible and there is a "red flag" icon loaded, show it left
 | ||||
| 		// to the filament color image.
 | ||||
| 		if (wide_icons) | ||||
| 			bitmap_key += preset.is_compatible ? ",cmpt" : ",ncmpt"; | ||||
| 		bitmap_key += (preset.is_system || preset.is_default) ? ",syst" : ",nsyst"; | ||||
| 		wxBitmap     *bmp = m_bitmap_cache->find(bitmap_key); | ||||
| 		if (bmp == nullptr) { | ||||
| 			// Create the bitmap with color bars.
 | ||||
| 			std::vector<wxBitmap> bmps; | ||||
| 			if (wide_icons) | ||||
| 				// Paint a red flag for incompatible presets.
 | ||||
| 				bmps.emplace_back(preset.is_compatible ? m_bitmap_cache->mkclear(16, 16) : *m_bitmap_incompatible); | ||||
| 			// Paint the color bars.
 | ||||
| 			bmps.emplace_back(m_bitmap_cache->mkclear(4, 16)); | ||||
| 			bmps.emplace_back(*m_bitmap_main_frame); | ||||
| 			// Paint a lock at the system presets.
 | ||||
|  			bmps.emplace_back(m_bitmap_cache->mkclear(6, 16)); | ||||
| 			bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmap_lock : m_bitmap_cache->mkclear(16, 16)); | ||||
| 			bmp = m_bitmap_cache->insert(bitmap_key, bmps); | ||||
| 		} | ||||
| 
 | ||||
| 		if (preset.is_default || preset.is_system){ | ||||
| 			ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), | ||||
|  | @ -605,20 +633,18 @@ void PresetCollection::update_platter_ui(wxBitmapComboBox *ui) | |||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			nonsys_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), preset.is_compatible); | ||||
| 			nonsys_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), bmp/*preset.is_compatible*/); | ||||
| 			if (i == m_idx_selected) | ||||
| 				selected = wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()); | ||||
| 		} | ||||
| 		if (preset.is_default) | ||||
| 			ui->Append("------------------------------------", wxNullBitmap); | ||||
| 			ui->Append("------- System presets -------", wxNullBitmap); | ||||
| 	} | ||||
| 	if (!nonsys_presets.empty()) | ||||
| 	{ | ||||
| 		ui->Append("------------------------------------", wxNullBitmap); | ||||
| 		for (std::map<wxString, bool>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) { | ||||
| 			const wxBitmap *bmp = it->second ? m_bitmap_compatible : m_bitmap_incompatible; | ||||
| 			ui->Append(it->first, | ||||
| 				(bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp); | ||||
| 		ui->Append("-------  User presets  -------", wxNullBitmap); | ||||
| 		for (std::map<wxString, wxBitmap*>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) { | ||||
| 			ui->Append(it->first, *it->second); | ||||
| 			if (it->first == selected) | ||||
| 				ui->SetSelection(ui->GetCount() - 1); | ||||
| 		} | ||||
|  | @ -626,51 +652,63 @@ void PresetCollection::update_platter_ui(wxBitmapComboBox *ui) | |||
|     ui->Thaw(); | ||||
| } | ||||
| 
 | ||||
| void PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompatible) | ||||
| size_t PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompatible) | ||||
| { | ||||
|     if (ui == nullptr) | ||||
|         return; | ||||
|         return 0; | ||||
|     ui->Freeze(); | ||||
|     ui->Clear(); | ||||
| 	std::map<wxString, bool> nonsys_presets; | ||||
| 	size_t selected_preset_item = 0; | ||||
| 
 | ||||
| 	std::map<wxString, wxBitmap*> nonsys_presets; | ||||
| 	wxString selected = ""; | ||||
|     for (size_t i = this->m_presets.front().is_visible ? 0 : 1; i < this->m_presets.size(); ++ i) { | ||||
| 	if (!this->m_presets.front().is_visible) | ||||
| 		ui->Append("------- System presets -------", wxNullBitmap); | ||||
| 	for (size_t i = this->m_presets.front().is_visible ? 0 : 1; i < this->m_presets.size(); ++i) { | ||||
|         const Preset &preset = this->m_presets[i]; | ||||
|         if (! preset.is_visible || (! show_incompatible && ! preset.is_compatible && i != m_idx_selected)) | ||||
|             continue; | ||||
|         const wxBitmap *bmp = preset.is_compatible ? m_bitmap_compatible : m_bitmap_incompatible; | ||||
| //         ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()),
 | ||||
| //             (bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp);
 | ||||
| // 		if (i == m_idx_selected)
 | ||||
| //             ui->SetSelection(ui->GetCount() - 1);
 | ||||
| 		std::string   bitmap_key = "tab"; | ||||
| 		bitmap_key += preset.is_compatible ? ",cmpt" : ",ncmpt"; | ||||
| 		bitmap_key += (preset.is_system || preset.is_default) ? ",syst" : ",nsyst"; | ||||
| 		wxBitmap     *bmp = m_bitmap_cache->find(bitmap_key); | ||||
| 		if (bmp == nullptr) { | ||||
| 			// Create the bitmap with color bars.
 | ||||
| 			std::vector<wxBitmap> bmps; | ||||
| 			const wxBitmap* tmp_bmp = preset.is_compatible ? m_bitmap_compatible : m_bitmap_incompatible; | ||||
| 			bmps.emplace_back((tmp_bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *tmp_bmp); | ||||
| 			// Paint a lock at the system presets.
 | ||||
| 			bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmap_lock : m_bitmap_cache->mkclear(16, 16)); | ||||
| 			bmp = m_bitmap_cache->insert(bitmap_key, bmps); | ||||
| 		} | ||||
| 
 | ||||
| 		if (preset.is_default || preset.is_system){ | ||||
| 			ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), | ||||
| 				(bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp); | ||||
| 			if (i == m_idx_selected) | ||||
| 				ui->SetSelection(ui->GetCount() - 1); | ||||
| 				selected_preset_item = ui->GetCount() - 1; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			nonsys_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), preset.is_compatible); | ||||
| 			nonsys_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), bmp/*preset.is_compatible*/); | ||||
| 			if (i == m_idx_selected) | ||||
| 				selected = wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()); | ||||
| 		} | ||||
| 		if (preset.is_default) | ||||
| 			ui->Append("------------------------------------", wxNullBitmap); | ||||
| 			ui->Append("------- System presets -------", wxNullBitmap); | ||||
|     } | ||||
| 	if (!nonsys_presets.empty()) | ||||
| 	{ | ||||
| 		ui->Append("------------------------------------", wxNullBitmap); | ||||
| 		for (std::map<wxString, bool>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) { | ||||
| 			const wxBitmap *bmp = it->second ? m_bitmap_compatible : m_bitmap_incompatible; | ||||
| 			ui->Append(it->first, | ||||
| 				(bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp); | ||||
| 		ui->Append("-------  User presets  -------", wxNullBitmap); | ||||
| 		for (std::map<wxString, wxBitmap*>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) { | ||||
| 			ui->Append(it->first, *it->second); | ||||
| 			if (it->first == selected) | ||||
| 				ui->SetSelection(ui->GetCount() - 1); | ||||
| 				selected_preset_item = ui->GetCount() - 1; | ||||
| 		} | ||||
| 	} | ||||
| 	ui->SetSelection(selected_preset_item); | ||||
|     ui->Thaw(); | ||||
| 	return selected_preset_item; | ||||
| } | ||||
| 
 | ||||
| // Update a dirty floag of the current preset, update the labels of the UI component accordingly.
 | ||||
|  | @ -703,11 +741,13 @@ bool PresetCollection::update_dirty_ui(wxBitmapComboBox *ui) | |||
|     return was_dirty != is_dirty; | ||||
| } | ||||
| 
 | ||||
| std::vector<std::string> PresetCollection::dirty_options(const Preset *edited, const Preset *reference) | ||||
| std::vector<std::string> PresetCollection::dirty_options(const Preset *edited, const Preset *reference, const bool is_printer_type /*= false*/) | ||||
| { | ||||
|     std::vector<std::string> changed; | ||||
|     if (edited != nullptr && reference != nullptr) { | ||||
|         changed = reference->config.diff(edited->config); | ||||
| 	if (edited != nullptr && reference != nullptr) { | ||||
|         changed = is_printer_type  ?  | ||||
| 				reference->config.deep_diff(edited->config) : | ||||
| 				reference->config.diff(edited->config); | ||||
|         // The "compatible_printers" option key is handled differently from the others:
 | ||||
|         // It is not mandatory. If the key is missing, it means it is compatible with any printer.
 | ||||
|         // If the key exists and it is empty, it means it is compatible with no printer.
 | ||||
|  | @ -764,6 +804,11 @@ bool PresetCollection::select_preset_by_name(const std::string &name_w_suffix, b | |||
|         // If the first visible preset was not found, return the 0th element, which is the default preset.
 | ||||
|     } | ||||
| 
 | ||||
| 	// Temporary decision
 | ||||
| 	if (name_w_suffix == "------- System presets -------" || | ||||
| 		name_w_suffix == "-------  User presets  -------") | ||||
| 		return true; | ||||
| 
 | ||||
|     // 2) Select the new preset.
 | ||||
|     if (m_idx_selected != idx || force) { | ||||
|         this->select_preset(idx); | ||||
|  |  | |||
|  | @ -20,6 +20,10 @@ namespace Slic3r { | |||
| class AppConfig; | ||||
| class PresetBundle; | ||||
| 
 | ||||
| namespace GUI { | ||||
| 	class BitmapCache; | ||||
| } | ||||
| 
 | ||||
| enum ConfigFileType | ||||
| { | ||||
|     CONFIG_FILE_TYPE_UNKNOWN, | ||||
|  | @ -302,18 +306,18 @@ public: | |||
|     // Compare the content of get_selected_preset() with get_edited_preset() configs, return true if they differ.
 | ||||
|     bool                        current_is_dirty() const { return ! this->current_dirty_options().empty(); } | ||||
|     // Compare the content of get_selected_preset() with get_edited_preset() configs, return the list of keys where they differ.
 | ||||
|     std::vector<std::string>    current_dirty_options() const  | ||||
|         { return dirty_options(&this->get_edited_preset(), &this->get_selected_preset()); } | ||||
|     std::vector<std::string>    current_dirty_options(const bool is_printer_type = false) const | ||||
|         { return dirty_options(&this->get_edited_preset(), &this->get_selected_preset(), is_printer_type); } | ||||
|     // Compare the content of get_selected_preset() with get_edited_preset() configs, return the list of keys where they differ.
 | ||||
|     std::vector<std::string>    current_different_from_parent_options() const | ||||
|         { return dirty_options(&this->get_edited_preset(), this->get_selected_preset_parent()); } | ||||
|     std::vector<std::string>    current_different_from_parent_options(const bool is_printer_type = false) const | ||||
|         { return dirty_options(&this->get_edited_preset(), this->get_selected_preset_parent(), is_printer_type); } | ||||
|     // Compare the content of get_selected_preset() with get_selected_preset_parent() configs, return the list of keys where they equal.
 | ||||
| 	std::vector<std::string>    system_equal_options() const; | ||||
| 
 | ||||
|     // Update the choice UI from the list of presets.
 | ||||
|     // If show_incompatible, all presets are shown, otherwise only the compatible presets are shown.
 | ||||
|     // If an incompatible preset is selected, it is shown as well.
 | ||||
|     void            update_tab_ui(wxBitmapComboBox *ui, bool show_incompatible); | ||||
|     size_t          update_tab_ui(wxBitmapComboBox *ui, bool show_incompatible); | ||||
|     // Update the choice UI from the list of presets.
 | ||||
|     // Only the compatible presets are shown.
 | ||||
|     // If an incompatible preset is selected, it is shown as well.
 | ||||
|  | @ -358,7 +362,7 @@ private: | |||
| 
 | ||||
|     size_t update_compatible_with_printer_internal(const Preset &active_printer, bool unselect_if_incompatible); | ||||
| 
 | ||||
|     static std::vector<std::string> dirty_options(const Preset *edited, const Preset *reference); | ||||
|     static std::vector<std::string> dirty_options(const Preset *edited, const Preset *reference, const bool is_printer_type = false); | ||||
| 
 | ||||
|     // Type of this PresetCollection: TYPE_PRINT, TYPE_FILAMENT or TYPE_PRINTER.
 | ||||
|     Preset::Type            m_type; | ||||
|  | @ -384,6 +388,9 @@ private: | |||
|     // Path to the directory to store the config files into.
 | ||||
|     std::string             m_dir_path; | ||||
| 
 | ||||
| 	// Caching color bitmaps for the filament combo box.
 | ||||
| 	GUI::BitmapCache       *m_bitmap_cache = nullptr; | ||||
| 
 | ||||
|     // to access select_preset_by_name_strict()
 | ||||
|     friend class PresetBundle; | ||||
| }; | ||||
|  |  | |||
|  | @ -1011,6 +1011,10 @@ void PresetBundle::export_configbundle(const std::string &path) //, const Dynami | |||
| // an optional "(modified)" suffix will be removed from the filament name.
 | ||||
| void PresetBundle::set_filament_preset(size_t idx, const std::string &name) | ||||
| { | ||||
| 	if (name == "------- System presets -------" || | ||||
| 		name == "-------  User presets  -------") | ||||
| 		return; | ||||
| 
 | ||||
|     if (idx >= filament_presets.size()) | ||||
|         filament_presets.resize(idx + 1, filaments.default_preset().name); | ||||
|     filament_presets[idx] = Preset::remove_suffix_modified(name); | ||||
|  | @ -1059,9 +1063,11 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, wxBitma | |||
|     // and draw a red flag in front of the selected preset.
 | ||||
|     bool          wide_icons      = selected_preset != nullptr && ! selected_preset->is_compatible && m_bitmapIncompatible != nullptr; | ||||
|     assert(selected_preset != nullptr); | ||||
| 	std::map<wxString, wxBitmap> nonsys_presets; | ||||
| 	std::map<wxString, wxBitmap*> nonsys_presets; | ||||
| 	wxString selected_str = ""; | ||||
|     for (int i = this->filaments().front().is_visible ? 0 : 1; i < int(this->filaments().size()); ++ i) { | ||||
| 	if (!this->filaments().front().is_visible) | ||||
| 		ui->Append("------- System presets -------", wxNullBitmap); | ||||
| 	for (int i = this->filaments().front().is_visible ? 0 : 1; i < int(this->filaments().size()); ++i) { | ||||
|         const Preset &preset    = this->filaments.preset(i); | ||||
|         bool          selected  = this->filament_presets[idx_extruder] == preset.name; | ||||
| 		if (! preset.is_visible || (! preset.is_compatible && ! selected)) | ||||
|  | @ -1093,14 +1099,11 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, wxBitma | |||
|                 bmps.emplace_back(m_bitmapCache->mksolid(8,  16, rgb)); | ||||
|             } | ||||
|             // Paint a lock at the system presets.
 | ||||
|             bmps.emplace_back(m_bitmapCache->mkclear(4, 16)); | ||||
|             bmps.emplace_back((preset.is_system || preset.is_default) ?  | ||||
|                 (preset.is_dirty ? *m_bitmapLockOpen : *m_bitmapLock) : m_bitmapCache->mkclear(16, 16)); | ||||
|             bmps.emplace_back(m_bitmapCache->mkclear(2, 16)); | ||||
| 			bmps.emplace_back((preset.is_system || preset.is_default) ? *m_bitmapLock : m_bitmapCache->mkclear(16, 16)); | ||||
| //                 (preset.is_dirty ? *m_bitmapLockOpen : *m_bitmapLock) : m_bitmapCache->mkclear(16, 16));
 | ||||
|             bitmap = m_bitmapCache->insert(bitmap_key, bmps); | ||||
| 		} | ||||
| // 		ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), (bitmap == 0) ? wxNullBitmap : *bitmap);
 | ||||
| //         if (selected)
 | ||||
| //             ui->SetSelection(ui->GetCount() - 1);
 | ||||
| 
 | ||||
| 		if (preset.is_default || preset.is_system){ | ||||
| 			ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()),  | ||||
|  | @ -1111,19 +1114,19 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, wxBitma | |||
| 		else | ||||
| 		{ | ||||
| 			nonsys_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()),  | ||||
| 				(bitmap == 0) ? wxNullBitmap : *bitmap); | ||||
| 				(bitmap == 0) ? &wxNullBitmap : bitmap); | ||||
| 			if (selected) | ||||
| 				selected_str = wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()); | ||||
| 		} | ||||
| 		if (preset.is_default) | ||||
| 			ui->Append("------------------------------------", wxNullBitmap); | ||||
| 			ui->Append("------- System presets -------", wxNullBitmap); | ||||
|     } | ||||
| 
 | ||||
| 	if (!nonsys_presets.empty()) | ||||
| 	{ | ||||
| 		ui->Append("------------------------------------", wxNullBitmap); | ||||
| 		for (std::map<wxString, wxBitmap>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) { | ||||
| 			ui->Append(it->first, it->second); | ||||
| 		ui->Append("-------  User presets  -------", wxNullBitmap); | ||||
| 		for (std::map<wxString, wxBitmap*>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) { | ||||
| 			ui->Append(it->first, *it->second); | ||||
| 			if (it->first == selected_str) | ||||
| 				ui->SetSelection(ui->GetCount() - 1); | ||||
| 		} | ||||
|  |  | |||
|  | @ -8,6 +8,7 @@ | |||
| #include "slic3r/Utils/OctoPrint.hpp" | ||||
| #include "BonjourDialog.hpp" | ||||
| #include "WipeTowerDialog.hpp" | ||||
| #include "ButtonsDescription.hpp" | ||||
| 
 | ||||
| #include <wx/app.h> | ||||
| #include <wx/button.h> | ||||
|  | @ -23,6 +24,9 @@ | |||
| 
 | ||||
| #include <boost/algorithm/string/predicate.hpp> | ||||
| #include "wxExtensions.hpp" | ||||
| #include <wx/wupdlock.h> | ||||
| 
 | ||||
| #include <chrono> | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| namespace GUI { | ||||
|  | @ -88,9 +92,9 @@ void Tab::create_preset_tab(PresetBundle *preset_bundle) | |||
| 	if (wxMSW) m_btn_delete_preset->SetBackgroundColour(color); | ||||
| 
 | ||||
| 	m_show_incompatible_presets = false; | ||||
| 	m_bmp_show_incompatible_presets = new wxBitmap(from_u8(Slic3r::var("flag-red-icon.png")), wxBITMAP_TYPE_PNG); | ||||
| 	m_bmp_hide_incompatible_presets = new wxBitmap(from_u8(Slic3r::var("flag-green-icon.png")), wxBITMAP_TYPE_PNG); | ||||
| 	m_btn_hide_incompatible_presets = new wxBitmapButton(panel, wxID_ANY, *m_bmp_hide_incompatible_presets, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); | ||||
| 	m_bmp_show_incompatible_presets.LoadFile(from_u8(Slic3r::var("flag-red-icon.png")), wxBITMAP_TYPE_PNG); | ||||
| 	m_bmp_hide_incompatible_presets.LoadFile(from_u8(Slic3r::var("flag-green-icon.png")), wxBITMAP_TYPE_PNG); | ||||
| 	m_btn_hide_incompatible_presets = new wxBitmapButton(panel, wxID_ANY, m_bmp_hide_incompatible_presets, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); | ||||
| 	if (wxMSW) m_btn_hide_incompatible_presets->SetBackgroundColour(color); | ||||
| 
 | ||||
| 	m_btn_save_preset->SetToolTip(_(L("Save current ")) + m_title); | ||||
|  | @ -99,14 +103,44 @@ void Tab::create_preset_tab(PresetBundle *preset_bundle) | |||
| 
 | ||||
| 	m_undo_btn = new wxButton(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); | ||||
| 	m_undo_to_sys_btn = new wxButton(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); | ||||
| 	m_question_btn = new wxButton(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); | ||||
| 	if (wxMSW) { | ||||
| 		m_undo_btn->SetBackgroundColour(color); | ||||
| 		m_undo_to_sys_btn->SetBackgroundColour(color); | ||||
| 		m_question_btn->SetBackgroundColour(color); | ||||
| 	} | ||||
| 	m_undo_btn->SetBitmap(wxBitmap(from_u8(var("bullet_white.png")), wxBITMAP_TYPE_PNG)); | ||||
| 	m_undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent){ on_back_to_initial_value(); })); | ||||
| 	m_undo_to_sys_btn->SetBitmap(wxBitmap(from_u8(var("bullet_white.png")), wxBITMAP_TYPE_PNG)); | ||||
| 	m_undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent){ on_back_to_sys_value(); })); | ||||
| 
 | ||||
| 	m_question_btn->SetToolTip(_(L("Hover the cursor over buttons to find more information."))); | ||||
| 
 | ||||
| 	// Determine the theme color of OS (dark or light)
 | ||||
| 	auto luma = get_colour_approx_luma(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); | ||||
| 	// Bitmaps to be shown on the "Revert to system" aka "Lock to system" button next to each input field.
 | ||||
| 	m_bmp_value_lock  	  .LoadFile(from_u8(var("sys_lock.png")),     wxBITMAP_TYPE_PNG); | ||||
| 	m_bmp_value_unlock    .LoadFile(from_u8(var(luma >= 128 ? "sys_unlock.png" : "sys_unlock_grey.png")), wxBITMAP_TYPE_PNG); | ||||
| 	m_bmp_non_system = &m_bmp_white_bullet; | ||||
| 	// Bitmaps to be shown on the "Undo user changes" button next to each input field.
 | ||||
| 	m_bmp_value_revert    .LoadFile(from_u8(var(luma >= 128 ? "action_undo.png" : "action_undo_grey.png")), wxBITMAP_TYPE_PNG); | ||||
| 	m_bmp_white_bullet    .LoadFile(from_u8(var("bullet_white.png")), wxBITMAP_TYPE_PNG); | ||||
| 	m_bmp_question        .LoadFile(from_u8(var("question_mark_01.png")), wxBITMAP_TYPE_PNG); | ||||
| 
 | ||||
| 	fill_icon_descriptions(); | ||||
| 	set_tooltips_text(); | ||||
| 
 | ||||
| 	m_undo_btn->SetBitmap(m_bmp_white_bullet); | ||||
| 	m_undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent){ on_roll_back_value(); })); | ||||
| 	m_undo_to_sys_btn->SetBitmap(m_bmp_white_bullet); | ||||
| 	m_undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent){ on_roll_back_value(true); })); | ||||
| 	m_question_btn->SetBitmap(m_bmp_question); | ||||
| 	m_question_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) | ||||
| 	{ | ||||
| 		auto dlg = new ButtonsDescription(this, &m_icon_descriptions); | ||||
| 		dlg->ShowModal(); | ||||
| 	})); | ||||
| 
 | ||||
| 	// Colors for ui "decoration"
 | ||||
| 	m_sys_label_clr			= get_sys_label_clr(); | ||||
| 	m_modified_label_clr	= get_modified_label_clr(); | ||||
| 	m_default_text_clr		= get_default_label_clr(); | ||||
| 
 | ||||
| 	m_hsizer = new wxBoxSizer(wxHORIZONTAL); | ||||
| 	sizer->Add(m_hsizer, 0, wxBOTTOM, 3); | ||||
|  | @ -120,7 +154,8 @@ void Tab::create_preset_tab(PresetBundle *preset_bundle) | |||
| 	m_hsizer->AddSpacer(64); | ||||
| 	m_hsizer->Add(m_undo_to_sys_btn, 0, wxALIGN_CENTER_VERTICAL); | ||||
| 	m_hsizer->Add(m_undo_btn, 0, wxALIGN_CENTER_VERTICAL); | ||||
| // 	m_hsizer->AddSpacer(64);
 | ||||
| 	m_hsizer->AddSpacer(32); | ||||
| 	m_hsizer->Add(m_question_btn, 0, wxALIGN_CENTER_VERTICAL); | ||||
| // 	m_hsizer->Add(m_cc_presets_choice, 1, wxLEFT | wxRIGHT | wxTOP | wxALIGN_CENTER_VERTICAL, 3);
 | ||||
| 
 | ||||
| 	//Horizontal sizer to hold the tree and the selected page.
 | ||||
|  | @ -183,8 +218,16 @@ void Tab::create_preset_tab(PresetBundle *preset_bundle) | |||
| 		//! select_preset(m_presets_choice->GetStringSelection().ToStdString()); 
 | ||||
| 		//! we doing next:
 | ||||
| 		int selected_item = m_presets_choice->GetSelection(); | ||||
| 		if (m_selected_preset_item == selected_item) | ||||
| 			return; | ||||
| 		if (selected_item >= 0){ | ||||
| 			std::string selected_string = m_presets_choice->GetString(selected_item).ToUTF8().data(); | ||||
| 			if (selected_string == "------- System presets -------" || | ||||
| 				selected_string == "-------  User presets  -------"){ | ||||
| 				m_presets_choice->SetSelection(m_selected_preset_item); | ||||
| 				return; | ||||
| 			} | ||||
| 			m_selected_preset_item = selected_item; | ||||
| 			select_preset(selected_string); | ||||
| 		} | ||||
| 	})); | ||||
|  | @ -204,8 +247,9 @@ void Tab::create_preset_tab(PresetBundle *preset_bundle) | |||
| void Tab::load_initial_data() | ||||
| { | ||||
| 	m_config = &m_presets->get_edited_preset().config; | ||||
| 	m_nonsys_btn_icon = m_presets->get_selected_preset_parent() == nullptr ? | ||||
| 						"bullet_white.png" : "sys_unlock.png"; | ||||
| 	m_bmp_non_system = m_presets->get_selected_preset_parent() ? &m_bmp_value_unlock : &m_bmp_white_bullet; | ||||
| 	m_ttg_non_system = m_presets->get_selected_preset_parent() ? &m_ttg_value_unlock : &m_ttg_white_bullet_ns; | ||||
| 	m_tt_non_system = m_presets->get_selected_preset_parent() ? &m_tt_value_unlock : &m_ttg_white_bullet_ns; | ||||
| } | ||||
| 
 | ||||
| PageShp Tab::add_options_page(const wxString& title, const std::string& icon, bool is_extruder_pages/* = false*/) | ||||
|  | @ -234,140 +278,78 @@ PageShp Tab::add_options_page(const wxString& title, const std::string& icon, bo | |||
| 	return page; | ||||
| } | ||||
| 
 | ||||
| template<class T> | ||||
| void add_correct_opts_to_dirty_options(const std::string &opt_key, std::vector<std::string> *vec, TabPrinter *tab) | ||||
| { | ||||
| 	auto opt_init = static_cast<T*>(tab->m_presets->get_selected_preset().config.option(opt_key)); | ||||
| 	auto opt_cur = static_cast<T*>(tab->m_config->option(opt_key)); | ||||
| 	int opt_init_max_id = opt_init->values.size()-1; | ||||
| 	for (int i = 0; i < opt_cur->values.size(); i++) | ||||
| 	{ | ||||
| 		int init_id = i <= opt_init_max_id ? i : 0; | ||||
| 		if (opt_cur->values[i] != opt_init->values[init_id]) | ||||
| 			vec->emplace_back(opt_key + "#" + std::to_string(i)); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| template<class T> | ||||
| void add_correct_opts_to_sys_options(const std::string &opt_key, std::vector<std::string> *vec, TabPrinter *tab) | ||||
| { | ||||
| 	const Preset* sys_preset = tab->m_presets->get_selected_preset_parent(); | ||||
| 	if (sys_preset == nullptr) | ||||
| 		return; | ||||
| 	T *opt_cur = static_cast<T*>(tab->m_config->option(opt_key)); | ||||
| 	const T *opt_sys = static_cast<const T*>(sys_preset->config.option(opt_key)); | ||||
| 	int opt_max_id = opt_sys->values.size()-1; | ||||
| 	for (int i = 0; i < opt_cur->values.size(); i++) | ||||
| 	{ | ||||
| 		int init_id = i <= opt_max_id ? i : 0; | ||||
| 		if (opt_cur->values[i] == opt_sys->values[init_id]) | ||||
| 			vec->emplace_back(opt_key + "#" + std::to_string(i)); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Update UI according to changes
 | ||||
| void Tab::update_changed_ui() | ||||
| { | ||||
| 	auto dirty_options = m_presets->current_dirty_options(); | ||||
| 	if (m_postpone_update_ui)  | ||||
| 		return; | ||||
| 
 | ||||
| 	if (name() == "printer"){ | ||||
| 		// Update dirty_options in case changes of Extruder's options 
 | ||||
| 	const bool is_printer_type = (name() == "printer"); | ||||
| 	auto dirty_options = m_presets->current_dirty_options(is_printer_type); | ||||
| 	auto nonsys_options = m_presets->current_different_from_parent_options(is_printer_type); | ||||
| 	if (is_printer_type){ | ||||
| 		TabPrinter* tab = static_cast<TabPrinter*>(this); | ||||
| 		m_dirty_options.resize(0); | ||||
| 		for (auto opt_key : dirty_options) | ||||
| 		{ | ||||
| 			if (opt_key == "bed_shape"){ m_dirty_options.emplace_back(opt_key);		continue; } | ||||
| 			switch (m_config->option(opt_key)->type()) | ||||
| 			{ | ||||
| 			case coInts:	add_correct_opts_to_dirty_options<ConfigOptionInts		>(opt_key, &m_dirty_options, tab);	break; | ||||
| 			case coBools:	add_correct_opts_to_dirty_options<ConfigOptionBools		>(opt_key, &m_dirty_options, tab);	break; | ||||
| 			case coFloats:	add_correct_opts_to_dirty_options<ConfigOptionFloats	>(opt_key, &m_dirty_options, tab);	break; | ||||
| 			case coStrings:	add_correct_opts_to_dirty_options<ConfigOptionStrings	>(opt_key, &m_dirty_options, tab);	break; | ||||
| 			case coPercents:add_correct_opts_to_dirty_options<ConfigOptionPercents	>(opt_key, &m_dirty_options, tab);	break; | ||||
| 			case coPoints:	add_correct_opts_to_dirty_options<ConfigOptionPoints	>(opt_key, &m_dirty_options, tab);	break; | ||||
| 			default:		m_dirty_options.emplace_back(opt_key);		break; | ||||
| 			} | ||||
| 		} | ||||
| 		if (tab->m_initial_extruders_count != tab->m_extruders_count) | ||||
| 			m_dirty_options.emplace_back("extruders_count"); | ||||
| 
 | ||||
| 		m_sys_options.resize(0); | ||||
| 		const auto sys_preset = m_presets->get_selected_preset_parent(); | ||||
| 		if (sys_preset){ | ||||
| 			for (auto opt_key : m_config->keys()) | ||||
| 			{ | ||||
| 				if (opt_key == "bed_shape"){  | ||||
| 					if (*tab->m_config->option(opt_key) == *sys_preset->config.option(opt_key)) | ||||
| 						m_sys_options.emplace_back(opt_key);		 | ||||
| 					continue;  | ||||
| 				} | ||||
| 				switch (m_config->option(opt_key)->type()) | ||||
| 				{ | ||||
| 				case coInts:	add_correct_opts_to_sys_options<ConfigOptionInts	>(opt_key, &m_sys_options, tab);	break; | ||||
| 				case coBools:	add_correct_opts_to_sys_options<ConfigOptionBools	>(opt_key, &m_sys_options, tab);	break; | ||||
| 				case coFloats:	add_correct_opts_to_sys_options<ConfigOptionFloats	>(opt_key, &m_sys_options, tab);	break; | ||||
| 				case coStrings:	add_correct_opts_to_sys_options<ConfigOptionStrings	>(opt_key, &m_sys_options, tab);	break; | ||||
| 				case coPercents:add_correct_opts_to_sys_options<ConfigOptionPercents>(opt_key, &m_sys_options, tab);	break; | ||||
| 				case coPoints:	add_correct_opts_to_sys_options<ConfigOptionPoints	>(opt_key, &m_sys_options, tab);	break; | ||||
| 				default:{ | ||||
| 					const ConfigOption *opt_cur = tab->m_config->option(opt_key); | ||||
| 					const ConfigOption *opt_sys = sys_preset->config.option(opt_key); | ||||
| 					if (opt_cur != nullptr && opt_sys != nullptr && *opt_cur == *opt_sys) | ||||
| 						m_sys_options.emplace_back(opt_key);		 | ||||
| 					break; | ||||
| 				} | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			if (tab->m_sys_extruders_count == tab->m_extruders_count) | ||||
| 				m_sys_options.emplace_back("extruders_count"); | ||||
| 		} | ||||
| 	} | ||||
| 	else{ | ||||
| 		m_sys_options = m_presets->system_equal_options(); | ||||
| 		m_dirty_options = dirty_options; | ||||
| 			dirty_options.emplace_back("extruders_count"); | ||||
| 		if (tab->m_sys_extruders_count != tab->m_extruders_count) | ||||
| 			nonsys_options.emplace_back("extruders_count"); | ||||
| 	} | ||||
| 
 | ||||
| 	for (auto& it : m_options_list) | ||||
| 		it.second = m_opt_status_value; | ||||
| 
 | ||||
| 	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(); | ||||
| 	//update options "decoration"
 | ||||
| 	for (const auto opt_key : m_full_options_list) | ||||
| 	for (const auto opt : m_options_list) | ||||
| 	{ | ||||
| 		bool is_nonsys_value = false; | ||||
| 		bool is_modified_value = true; | ||||
| 		std::string sys_icon = "sys_lock.png"; | ||||
| 		std::string icon = "action_undo.png"; | ||||
| 		wxColour color = get_sys_label_clr(); | ||||
| 		if (find(m_sys_options.begin(), m_sys_options.end(), opt_key) == m_sys_options.end()) { | ||||
| 		const wxBitmap *sys_icon =	&m_bmp_value_lock; | ||||
| 		const wxBitmap *icon =		&m_bmp_value_revert; | ||||
| 
 | ||||
| 		const wxColour *color =		&m_sys_label_clr; | ||||
| 
 | ||||
| 		const wxString *sys_tt =	&m_tt_value_lock; | ||||
| 		const wxString *tt =		&m_tt_value_revert; | ||||
| 
 | ||||
| 		// value isn't equal to system value
 | ||||
| 		if ((opt.second & osSystemValue) == 0){ | ||||
| 			is_nonsys_value = true; | ||||
| 			sys_icon = m_nonsys_btn_icon; | ||||
| 			if(find(m_dirty_options.begin(), m_dirty_options.end(), opt_key) == m_dirty_options.end()) | ||||
| 				color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); | ||||
| 			sys_icon = m_bmp_non_system; | ||||
| 			sys_tt = m_tt_non_system; | ||||
| 			// value is equal to last saved
 | ||||
| 			if ((opt.second & osInitValue) != 0) | ||||
| 				color = &m_default_text_clr; | ||||
| 			// value is modified
 | ||||
| 			else | ||||
| 				color = get_modified_label_clr(); | ||||
| 				color = &m_modified_label_clr; | ||||
| 		} | ||||
| 		if (find(m_dirty_options.begin(), m_dirty_options.end(), opt_key) == m_dirty_options.end()) | ||||
| 		if ((opt.second & osInitValue) != 0) | ||||
| 		{ | ||||
| 			is_modified_value = false; | ||||
| 			icon = "bullet_white.png"; | ||||
| 			icon = &m_bmp_white_bullet; | ||||
| 			tt = &m_tt_white_bullet; | ||||
| 		} | ||||
| 		if (opt_key == "bed_shape" || opt_key == "compatible_printers") { | ||||
| 		if (opt.first == "bed_shape" || opt.first == "compatible_printers") { | ||||
| 			if (m_colored_Label != nullptr)	{ | ||||
| 				m_colored_Label->SetForegroundColour(color); | ||||
| 				m_colored_Label->SetForegroundColour(*color); | ||||
| 				m_colored_Label->Refresh(true); | ||||
| 			} | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		Field* field = get_field(opt_key); | ||||
| 		Field* field = get_field(opt.first); | ||||
| 		if (field == nullptr) continue; | ||||
| 		field->m_is_nonsys_value = is_nonsys_value; | ||||
| 		field->m_is_modified_value = is_modified_value; | ||||
| 		field->m_Undo_btn->SetBitmap(wxBitmap(from_u8(var(icon)), wxBITMAP_TYPE_PNG)); | ||||
| 		field->m_Undo_to_sys_btn->SetBitmap(wxBitmap(from_u8(var(sys_icon)), wxBITMAP_TYPE_PNG)); | ||||
| 		if (field->m_Label != nullptr){ | ||||
| 			field->m_Label->SetForegroundColour(color); | ||||
| 			field->m_Label->Refresh(true); | ||||
| 		} | ||||
| 		field->set_undo_bitmap(icon); | ||||
| 		field->set_undo_to_sys_bitmap(sys_icon); | ||||
| 		field->set_undo_tooltip(tt); | ||||
| 		field->set_undo_to_sys_tooltip(sys_tt); | ||||
| 		field->set_label_colour(color); | ||||
| 	} | ||||
| 	Thaw(); | ||||
| 
 | ||||
|  | @ -376,67 +358,53 @@ void Tab::update_changed_ui() | |||
| 	}); | ||||
| } | ||||
| 
 | ||||
| void Tab::init_options_list() | ||||
| { | ||||
| 	if (!m_options_list.empty()) | ||||
| 		m_options_list.clear(); | ||||
| 
 | ||||
| 	for (const auto opt_key : m_config->keys()) | ||||
| 		m_options_list.emplace(opt_key, m_opt_status_value); | ||||
| } | ||||
| 
 | ||||
| template<class T> | ||||
| void add_correct_opts_to_full_options_list(const std::string &opt_key, std::vector<std::string> *vec, TabPrinter *tab) | ||||
| void add_correct_opts_to_options_list(const std::string &opt_key, std::map<std::string, int>& map, TabPrinter *tab, const int& value) | ||||
| { | ||||
| 	T *opt_cur = static_cast<T*>(tab->m_config->option(opt_key)); | ||||
| 	for (int i = 0; i < opt_cur->values.size(); i++) | ||||
| 		vec->emplace_back(opt_key + "#" + std::to_string(i)); | ||||
| 		map.emplace(opt_key + "#" + std::to_string(i), value); | ||||
| } | ||||
| 
 | ||||
| void Tab::update_full_options_list() | ||||
| void TabPrinter::init_options_list() | ||||
| { | ||||
| 	if (!m_full_options_list.empty()) | ||||
| 		m_full_options_list.resize(0); | ||||
| 	if (!m_options_list.empty()) | ||||
| 		m_options_list.clear(); | ||||
| 
 | ||||
| 	if (m_name != "printer"){ | ||||
| 		m_full_options_list = m_config->keys(); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	TabPrinter* tab = static_cast<TabPrinter*>(this); | ||||
| 	for (const auto opt_key : m_config->keys()) | ||||
| 	{ | ||||
| 		if (opt_key == "bed_shape"){ | ||||
| 			m_full_options_list.emplace_back(opt_key); | ||||
| 			m_options_list.emplace(opt_key, m_opt_status_value); | ||||
| 			continue; | ||||
| 		} | ||||
| 		switch (m_config->option(opt_key)->type()) | ||||
| 		{ | ||||
| 		case coInts:	add_correct_opts_to_full_options_list<ConfigOptionInts		>(opt_key, &m_full_options_list, tab);	break; | ||||
| 		case coBools:	add_correct_opts_to_full_options_list<ConfigOptionBools		>(opt_key, &m_full_options_list, tab);	break; | ||||
| 		case coFloats:	add_correct_opts_to_full_options_list<ConfigOptionFloats	>(opt_key, &m_full_options_list, tab);	break; | ||||
| 		case coStrings:	add_correct_opts_to_full_options_list<ConfigOptionStrings	>(opt_key, &m_full_options_list, tab);	break; | ||||
| 		case coPercents:add_correct_opts_to_full_options_list<ConfigOptionPercents	>(opt_key, &m_full_options_list, tab);	break; | ||||
| 		case coPoints:	add_correct_opts_to_full_options_list<ConfigOptionPoints	>(opt_key, &m_full_options_list, tab);	break; | ||||
| 		default:		m_full_options_list.emplace_back(opt_key);		break; | ||||
| 		case coInts:	add_correct_opts_to_options_list<ConfigOptionInts		>(opt_key, m_options_list, this, m_opt_status_value);	break; | ||||
| 		case coBools:	add_correct_opts_to_options_list<ConfigOptionBools		>(opt_key, m_options_list, this, m_opt_status_value);	break; | ||||
| 		case coFloats:	add_correct_opts_to_options_list<ConfigOptionFloats		>(opt_key, m_options_list, this, m_opt_status_value);	break; | ||||
| 		case coStrings:	add_correct_opts_to_options_list<ConfigOptionStrings	>(opt_key, m_options_list, this, m_opt_status_value);	break; | ||||
| 		case coPercents:add_correct_opts_to_options_list<ConfigOptionPercents	>(opt_key, m_options_list, this, m_opt_status_value);	break; | ||||
| 		case coPoints:	add_correct_opts_to_options_list<ConfigOptionPoints		>(opt_key, m_options_list, this, m_opt_status_value);	break; | ||||
| 		default:		m_options_list.emplace(opt_key, m_opt_status_value);		break; | ||||
| 		} | ||||
| 	} | ||||
| 	m_full_options_list.emplace_back("extruders_count"); | ||||
| } | ||||
| 
 | ||||
| void Tab::update_sys_ui_after_sel_preset() | ||||
| { | ||||
| 	for (const auto opt_key : m_full_options_list){ | ||||
| 		Field* field = get_field(opt_key); | ||||
| 		if (field != nullptr){ | ||||
| 			field->m_Undo_to_sys_btn->SetBitmap(wxBitmap(from_u8(var(m_nonsys_btn_icon)), wxBITMAP_TYPE_PNG)); | ||||
| 			field->m_is_nonsys_value = true; | ||||
| 			if (field->m_Label != nullptr){ | ||||
| 				field->m_Label->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); | ||||
| 				field->m_Label->Refresh(true); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	m_sys_options.resize(0); | ||||
| 	m_options_list.emplace("extruders_count", m_opt_status_value); | ||||
| } | ||||
| 
 | ||||
| void Tab::get_sys_and_mod_flags(const std::string& opt_key, bool& sys_page, bool& modified_page) | ||||
| { | ||||
| 	if (sys_page && find(m_sys_options.begin(), m_sys_options.end(), opt_key) == m_sys_options.end()) | ||||
| 		sys_page = false; | ||||
| 	if (!modified_page && find(m_dirty_options.begin(), m_dirty_options.end(), opt_key) != m_dirty_options.end()) | ||||
| 		modified_page = true; | ||||
| 	auto opt = m_options_list.find(opt_key); | ||||
| 	if (sys_page) sys_page = (opt->second & osSystemValue) != 0; | ||||
| 	if (!modified_page) modified_page = (opt->second & osInitValue) == 0; | ||||
| } | ||||
| 
 | ||||
| void Tab::update_changed_tree_ui() | ||||
|  | @ -457,7 +425,7 @@ void Tab::update_changed_tree_ui() | |||
| 					get_sys_and_mod_flags(opt_key, sys_page, modified_page); | ||||
| 				} | ||||
| 			} | ||||
| 			if (title == _("Dependencies")){ | ||||
| 			if (title == _("Dependencies") && name() != "printer"){ | ||||
| 				get_sys_and_mod_flags("compatible_printers", sys_page, modified_page); | ||||
| 			} | ||||
| 			for (auto group : page->m_optgroups) | ||||
|  | @ -469,12 +437,13 @@ void Tab::update_changed_tree_ui() | |||
| 					get_sys_and_mod_flags(opt_key, sys_page, modified_page); | ||||
| 				} | ||||
| 			} | ||||
| 			if (sys_page) | ||||
| 				m_treectrl->SetItemTextColour(cur_item, get_sys_label_clr()); | ||||
| 			else if (modified_page) | ||||
| 				m_treectrl->SetItemTextColour(cur_item, get_modified_label_clr()); | ||||
| 			else | ||||
| 				m_treectrl->SetItemTextColour(cur_item, wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); | ||||
| 
 | ||||
| 			const wxColor *clr = sys_page		?	&m_sys_label_clr : | ||||
| 								 modified_page	?	&m_modified_label_clr :  | ||||
| 													&m_default_text_clr; | ||||
| 
 | ||||
| 			if (page->set_item_colour(clr)) | ||||
| 				m_treectrl->SetItemTextColour(cur_item, *clr); | ||||
| 
 | ||||
| 			page->m_is_nonsys_values = !sys_page; | ||||
| 			page->m_is_modified_values = modified_page; | ||||
|  | @ -493,80 +462,62 @@ void Tab::update_changed_tree_ui() | |||
| 
 | ||||
| void Tab::update_undo_buttons() | ||||
| { | ||||
| 	const std::string& undo_icon = !m_is_modified_values ? "bullet_white.png" : "action_undo.png"; | ||||
| 	const std::string& undo_to_sys_icon = m_is_nonsys_values ? m_nonsys_btn_icon : "sys_lock.png"; | ||||
| 	m_undo_btn->SetBitmap(m_is_modified_values ? m_bmp_value_revert : m_bmp_white_bullet); | ||||
| 	m_undo_to_sys_btn->SetBitmap(m_is_nonsys_values ? *m_bmp_non_system : m_bmp_value_lock); | ||||
| 
 | ||||
| 	m_undo_btn->SetBitmap(wxBitmap(from_u8(var(undo_icon)), wxBITMAP_TYPE_PNG)); | ||||
| 	m_undo_to_sys_btn->SetBitmap(wxBitmap(from_u8(var(undo_to_sys_icon)), wxBITMAP_TYPE_PNG)); | ||||
| 	m_undo_btn->SetToolTip(m_is_modified_values ? m_ttg_value_revert : m_ttg_white_bullet); | ||||
| 	m_undo_to_sys_btn->SetToolTip(m_is_nonsys_values ? *m_ttg_non_system : m_ttg_value_lock); | ||||
| } | ||||
| 
 | ||||
| void Tab::on_back_to_initial_value() | ||||
| void Tab::on_roll_back_value(const bool to_sys /*= true*/) | ||||
| { | ||||
| 	if (!m_is_modified_values) return; | ||||
| 	int os; | ||||
| 	if (to_sys)	{ | ||||
| 		if (!m_is_nonsys_values) return; | ||||
| 		os = osSystemValue; | ||||
| 	} | ||||
| 	else { | ||||
| 		if (!m_is_modified_values) return; | ||||
| 		os = osInitValue; | ||||
| 	} | ||||
| 
 | ||||
| 	m_postpone_update_ui = true; | ||||
| 
 | ||||
| 	auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection()); | ||||
| 	for (auto page : m_pages) | ||||
| 		if (page->title() == selection)	{ | ||||
| 			for (auto group : page->m_optgroups){ | ||||
| 				if (group->title == _("Capabilities")){ | ||||
| 					if (find(m_dirty_options.begin(), m_dirty_options.end(), "extruders_count") != m_dirty_options.end()) | ||||
| 						group->back_to_initial_value("extruders_count"); | ||||
| 					if ((m_options_list["extruders_count"] & os) == 0) | ||||
| 						to_sys ? group->back_to_sys_value("extruders_count") : group->back_to_initial_value("extruders_count"); | ||||
| 				} | ||||
| 				if (group->title == _("Size and coordinates")){ | ||||
| 					if (find(m_dirty_options.begin(), m_dirty_options.end(), "bed_shape") != m_dirty_options.end()) | ||||
| 						group->back_to_initial_value("bed_shape"); | ||||
| 				} | ||||
| 				if (group->title == _("Profile dependencies")){ | ||||
| 					if (find(m_dirty_options.begin(), m_dirty_options.end(), "compatible_printers") != m_dirty_options.end()) | ||||
| 						group->back_to_initial_value("compatible_printers"); | ||||
| 					if ((m_options_list["bed_shape"] & os) == 0){ | ||||
| 						to_sys ? group->back_to_sys_value("bed_shape") : group->back_to_initial_value("bed_shape"); | ||||
| 						load_key_value("bed_shape", true/*some value*/, true); | ||||
| 					} | ||||
| 
 | ||||
| 					bool is_empty = m_config->option<ConfigOptionStrings>("compatible_printers")->values.empty(); | ||||
| 					m_compatible_printers_checkbox->SetValue(is_empty); | ||||
| 					is_empty ? m_compatible_printers_btn->Disable() : m_compatible_printers_btn->Enable(); | ||||
| 				} | ||||
| 				if (group->title == _("Profile dependencies") && name() != "printer"){ | ||||
| 					if ((m_options_list["compatible_printers"] & os) == 0){ | ||||
| 						to_sys ? group->back_to_sys_value("compatible_printers") : group->back_to_initial_value("compatible_printers"); | ||||
| 						load_key_value("compatible_printers", true/*some value*/, true); | ||||
| 
 | ||||
| 						bool is_empty = m_config->option<ConfigOptionStrings>("compatible_printers")->values.empty(); | ||||
| 						m_compatible_printers_checkbox->SetValue(is_empty); | ||||
| 						is_empty ? m_compatible_printers_btn->Disable() : m_compatible_printers_btn->Enable(); | ||||
| 					} | ||||
| 				} | ||||
| 				for (t_opt_map::iterator it = group->m_opt_map.begin(); it != group->m_opt_map.end(); ++it) { | ||||
| 					const std::string& opt_key = it->first; | ||||
| 					if (find(m_dirty_options.begin(), m_dirty_options.end(), opt_key) != m_dirty_options.end()) | ||||
| 						group->back_to_initial_value(opt_key); | ||||
| 					if ((m_options_list[opt_key] & os) == 0) | ||||
| 						to_sys ? group->back_to_sys_value(opt_key) : group->back_to_initial_value(opt_key); | ||||
| 				} | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
| 	update_changed_ui(); | ||||
| } | ||||
| 
 | ||||
| void Tab::on_back_to_sys_value() | ||||
| { | ||||
| 	if (!m_is_nonsys_values) return; | ||||
| 
 | ||||
| 	auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection()); | ||||
| 	for (auto page : m_pages) | ||||
| 		if (page->title() == selection)	{ | ||||
| 			for (auto group : page->m_optgroups) { | ||||
| 				if (group->title == _("Capabilities")){ | ||||
| 					if (find(m_sys_options.begin(), m_sys_options.end(), "extruders_count") == m_sys_options.end()) | ||||
| 						group->back_to_sys_value("extruders_count"); | ||||
| 				} | ||||
| 				if (group->title == _("Size and coordinates")){ | ||||
| 					if (find(m_sys_options.begin(), m_sys_options.end(), "bed_shape") == m_sys_options.end()) | ||||
| 						group->back_to_sys_value("bed_shape"); | ||||
| 				} | ||||
| 				if (group->title == _("Profile dependencies")){ | ||||
| 					if (find(m_sys_options.begin(), m_sys_options.end(), "compatible_printers") == m_sys_options.end()) | ||||
| 						group->back_to_sys_value("compatible_printers"); | ||||
| 
 | ||||
| 					bool is_empty = m_config->option<ConfigOptionStrings>("compatible_printers")->values.empty(); | ||||
| 					m_compatible_printers_checkbox->SetValue(is_empty); | ||||
| 					is_empty ? m_compatible_printers_btn->Disable() : m_compatible_printers_btn->Enable(); | ||||
| 				} | ||||
| 				for (t_opt_map::iterator it = group->m_opt_map.begin(); it != group->m_opt_map.end(); ++it) { | ||||
| 					const std::string& opt_key = it->first; | ||||
| 					if (find(m_sys_options.begin(), m_sys_options.end(), opt_key) == m_sys_options.end()) | ||||
| 						group->back_to_sys_value(opt_key); | ||||
| 				} | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
| 	m_postpone_update_ui = false; | ||||
| 	update_changed_ui(); | ||||
| } | ||||
| 
 | ||||
|  | @ -581,7 +532,7 @@ void Tab::update_dirty(){ | |||
| 
 | ||||
| void Tab::update_tab_ui() | ||||
| { | ||||
| 	m_presets->update_tab_ui(m_presets_choice, m_show_incompatible_presets); | ||||
| 	m_selected_preset_item = m_presets->update_tab_ui(m_presets_choice, m_show_incompatible_presets); | ||||
| // 	update_tab_presets(m_cc_presets_choice, m_show_incompatible_presets);
 | ||||
| // 	update_presetsctrl(m_presetctrl, m_show_incompatible_presets);
 | ||||
| } | ||||
|  | @ -636,9 +587,11 @@ bool Tab::set_value(const t_config_option_key& opt_key, const boost::any& value) | |||
| 
 | ||||
| // To be called by custom widgets, load a value into a config,
 | ||||
| // update the preset selection boxes (the dirty flags)
 | ||||
| void Tab::load_key_value(const std::string& opt_key, const boost::any& value) | ||||
| // If value is saved before calling this function, put saved_value = true,
 | ||||
| // and value can be some random value because in this case it will not been used
 | ||||
| void Tab::load_key_value(const std::string& opt_key, const boost::any& value, bool saved_value /*= false*/) | ||||
| { | ||||
| 	change_opt_value(*m_config, opt_key, value); | ||||
| 	if (!saved_value) change_opt_value(*m_config, opt_key, value); | ||||
| 	// Mark the print & filament enabled if they are compatible with the currently selected preset.
 | ||||
| 	if (opt_key.compare("compatible_printers") == 0) { | ||||
| 		// Don't select another profile if this profile happens to become incompatible.
 | ||||
|  | @ -1354,6 +1307,7 @@ void TabFilament::reload_config(){ | |||
| 
 | ||||
| void TabFilament::update() | ||||
| { | ||||
| 	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)); | ||||
|  | @ -1367,6 +1321,7 @@ void TabFilament::update() | |||
| 
 | ||||
| 	for (auto el : { "min_fan_speed", "disable_fan_first_layers" }) | ||||
| 		get_field(el)->toggle(fan_always_on); | ||||
| 	Thaw(); | ||||
| } | ||||
| 
 | ||||
| void TabFilament::OnActivate() | ||||
|  | @ -1396,6 +1351,9 @@ void TabPrinter::build() | |||
| 	m_presets = &m_preset_bundle->printers; | ||||
| 	load_initial_data(); | ||||
| 
 | ||||
| 	// to avoid redundant memory allocation / deallocation during extruders count changing
 | ||||
| 	m_pages.reserve(30); | ||||
| 
 | ||||
| 	auto   *nozzle_diameter = dynamic_cast<const ConfigOptionFloats*>(m_config->option("nozzle_diameter")); | ||||
| 	m_initial_extruders_count = m_extruders_count = nozzle_diameter->values.size(); | ||||
| 	const Preset* parent_preset = m_presets->get_selected_preset_parent(); | ||||
|  | @ -1673,12 +1631,34 @@ void TabPrinter::extruders_count_changed(size_t extruders_count){ | |||
| } | ||||
| 
 | ||||
| void TabPrinter::build_extruder_pages(){ | ||||
| 	for (auto extruder_idx = m_extruder_pages.size(); extruder_idx < m_extruders_count; ++extruder_idx){ | ||||
| 	size_t		n_before_extruders = 2;			//	Count of pages before Extruder pages
 | ||||
| 	size_t		n_after_single_extruder_MM = 2; //	Count of pages after single_extruder_multi_material page
 | ||||
| 
 | ||||
| 	if (m_extruders_count_old == m_extruders_count || m_extruders_count <= 2) | ||||
| 	{ | ||||
| 		// if we have a single extruder MM setup, add a page with configuration options:
 | ||||
| 		for (int i = 0; i < m_pages.size(); ++i) // first make sure it's not there already
 | ||||
| 			if (m_pages[i]->title().find(_(L("Single extruder MM setup"))) != std::string::npos) { | ||||
| 				m_pages.erase(m_pages.begin() + i); | ||||
| 				break; | ||||
| 			} | ||||
| 		if (m_extruders_count > 1 && m_config->opt_bool("single_extruder_multi_material")) { | ||||
| 			// create a page, but pretend it's an extruder page, so we can add it to m_pages ourselves
 | ||||
| 			auto page = add_options_page(_(L("Single extruder MM setup")), "printer_empty.png", true); | ||||
| 			auto optgroup = page->new_optgroup(_(L("Single extruder multimaterial parameters"))); | ||||
| 			optgroup->append_single_option_line("cooling_tube_retraction"); | ||||
| 			optgroup->append_single_option_line("cooling_tube_length"); | ||||
| 			optgroup->append_single_option_line("parking_pos_retraction"); | ||||
| 			m_pages.insert(m_pages.end() - n_after_single_extruder_MM, page); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	for (auto extruder_idx = m_extruders_count_old; extruder_idx < m_extruders_count; ++extruder_idx){ | ||||
| 		//# build page
 | ||||
| 		char buf[MIN_BUF_LENGTH_FOR_L]; | ||||
| 		sprintf(buf, _CHB(L("Extruder %d")), extruder_idx + 1); | ||||
| 		auto page = add_options_page(from_u8(buf), "funnel.png", true); | ||||
| 		m_extruder_pages.push_back(page); | ||||
| 		m_pages.insert(m_pages.begin() + n_before_extruders + extruder_idx, page); | ||||
| 			 | ||||
| 			auto optgroup = page->new_optgroup(_(L("Size"))); | ||||
| 			optgroup->append_single_option_line("nozzle_diameter", extruder_idx); | ||||
|  | @ -1716,36 +1696,11 @@ void TabPrinter::build_extruder_pages(){ | |||
| 	} | ||||
|   | ||||
| 	// # remove extra pages
 | ||||
| 	if (m_extruders_count <= m_extruder_pages.size()) { | ||||
| 		m_extruder_pages.resize(m_extruders_count); | ||||
| 	} | ||||
| 	if (m_extruders_count < m_extruders_count_old) | ||||
| 		m_pages.erase(	m_pages.begin() + n_before_extruders + m_extruders_count,  | ||||
| 						m_pages.begin() + n_before_extruders + m_extruders_count_old); | ||||
| 
 | ||||
| 	// # rebuild page list
 | ||||
| 	PageShp page_note = m_pages.back(); | ||||
| 	m_pages.pop_back(); | ||||
| 	while (m_pages.back()->title().find(_(L("Extruder"))) != std::string::npos) | ||||
| 		m_pages.pop_back(); | ||||
| 	for (auto page_extruder : m_extruder_pages) | ||||
| 		m_pages.push_back(page_extruder); | ||||
| 	m_pages.push_back(page_note); | ||||
| 
 | ||||
|     { | ||||
|         // if we have a single extruder MM setup, add a page with configuration options:
 | ||||
|         for (int i=0;i<m_pages.size();++i) // first make sure it's not there already
 | ||||
|             if (m_pages[i]->title().find(_(L("Single extruder MM setup"))) != std::string::npos) { | ||||
|                 m_pages.erase(m_pages.begin()+i); | ||||
|                 break; | ||||
|             } | ||||
|         if ( m_extruder_pages.size()>1 && m_config->opt_bool("single_extruder_multi_material")) { | ||||
|             // create a page, but pretend it's an extruder page, so we can add it to m_pages ourselves
 | ||||
|             auto page = add_options_page(_(L("Single extruder MM setup")), "printer_empty.png",true); | ||||
|                 auto optgroup = page->new_optgroup(_(L("Single extruder multimaterial parameters"))); | ||||
|                 optgroup->append_single_option_line("cooling_tube_retraction"); | ||||
|                 optgroup->append_single_option_line("cooling_tube_length"); | ||||
|                 optgroup->append_single_option_line("parking_pos_retraction"); | ||||
|             m_pages.insert(m_pages.begin()+1,page); | ||||
|         } | ||||
|     } | ||||
| 	m_extruders_count_old = m_extruders_count; | ||||
| 
 | ||||
| 	rebuild_page_tree(); | ||||
| } | ||||
|  | @ -1853,8 +1808,9 @@ void Tab::load_current_preset() | |||
| 	on_preset_loaded(); | ||||
| 	// Reload preset pages with the new configuration values.
 | ||||
| 	reload_config(); | ||||
| 	const Preset* parent = m_presets->get_selected_preset_parent(); | ||||
| 	m_nonsys_btn_icon = parent == nullptr ? "bullet_white.png" : "sys_unlock.png"; | ||||
| 	m_bmp_non_system = m_presets->get_selected_preset_parent() ? &m_bmp_value_unlock : &m_bmp_white_bullet; | ||||
| 	m_ttg_non_system = m_presets->get_selected_preset_parent() ? &m_ttg_value_unlock : &m_ttg_white_bullet_ns; | ||||
| 	m_tt_non_system = m_presets->get_selected_preset_parent() ? &m_tt_value_unlock : &m_ttg_white_bullet_ns; | ||||
| 
 | ||||
| 	// use CallAfter because some field triggers schedule on_change calls using CallAfter,
 | ||||
| 	// and we don't want them to be called after this update_dirty() as they would mark the 
 | ||||
|  | @ -1875,8 +1831,8 @@ void Tab::load_current_preset() | |||
| 			static_cast<TabPrinter*>(this)->m_sys_extruders_count = parent_preset == nullptr ? 0 : | ||||
| 				static_cast<const ConfigOptionFloats*>(parent_preset->config.option("nozzle_diameter"))->values.size(); | ||||
| 		} | ||||
| 		update_sys_ui_after_sel_preset(); | ||||
| 		update_full_options_list(); | ||||
| 		m_opt_status_value = (m_presets->get_selected_preset_parent() ? osSystemValue : 0) | osInitValue; | ||||
| 		init_options_list(); | ||||
| 		update_changed_ui(); | ||||
| 	}); | ||||
| } | ||||
|  | @ -1888,11 +1844,13 @@ void Tab::rebuild_page_tree() | |||
| 	// get label of the currently selected item
 | ||||
| 	auto selected = m_treectrl->GetItemText(m_treectrl->GetSelection()); | ||||
| 	auto rootItem = m_treectrl->GetRootItem(); | ||||
| 	m_treectrl->DeleteChildren(rootItem); | ||||
| 
 | ||||
| 	auto have_selection = 0; | ||||
| 	m_treectrl->DeleteChildren(rootItem); | ||||
| 	for (auto p : m_pages) | ||||
| 	{ | ||||
| 		auto itemId = m_treectrl->AppendItem(rootItem, p->title(), p->iconID()); | ||||
| 		m_treectrl->SetItemTextColour(itemId, p->get_item_colour()); | ||||
| 		if (p->title() == selected) { | ||||
| 			m_disable_tree_sel_changed_event = 1; | ||||
| 			m_treectrl->SelectItem(itemId); | ||||
|  | @ -1900,7 +1858,7 @@ void Tab::rebuild_page_tree() | |||
| 			have_selection = 1; | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 
 | ||||
| 	if (!have_selection) { | ||||
| 		// this is triggered on first load, so we don't disable the sel change event
 | ||||
| 		m_treectrl->SelectItem(m_treectrl->GetFirstVisibleItem());//! (treectrl->GetFirstChild(rootItem));
 | ||||
|  | @ -2016,6 +1974,8 @@ bool Tab::may_discard_current_dirty_preset(PresetCollection* presets /*= nullptr | |||
| void Tab::OnTreeSelChange(wxTreeEvent& event) | ||||
| { | ||||
| 	if (m_disable_tree_sel_changed_event) return; | ||||
| 	wxWindowUpdateLocker noUpdates(this); | ||||
| 
 | ||||
| 	Page* page = nullptr; | ||||
| 	auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection()); | ||||
| 	for (auto p : m_pages) | ||||
|  | @ -2142,7 +2102,7 @@ void Tab::toggle_show_hide_incompatible() | |||
| void Tab::update_show_hide_incompatible_button() | ||||
| { | ||||
| 	m_btn_hide_incompatible_presets->SetBitmap(m_show_incompatible_presets ? | ||||
| 		*m_bmp_show_incompatible_presets : *m_bmp_hide_incompatible_presets); | ||||
| 		m_bmp_show_incompatible_presets : m_bmp_hide_incompatible_presets); | ||||
| 	m_btn_hide_incompatible_presets->SetToolTip(m_show_incompatible_presets ? | ||||
| 		"Both compatible an incompatible presets are shown. Click to hide presets not compatible with the current printer." : | ||||
| 		"Only compatible presets are shown. Click to show both the presets compatible and not compatible with the current printer."); | ||||
|  | @ -2402,6 +2362,75 @@ void Tab::update_tab_presets(wxComboCtrl* ui, bool show_incompatible) | |||
| 	ui->Thaw(); | ||||
| } | ||||
| 
 | ||||
| void Tab::fill_icon_descriptions() | ||||
| { | ||||
| 	m_icon_descriptions.push_back(t_icon_description(&m_bmp_value_lock, L("LOCKED LOCK;" | ||||
| 		"indicates that the settings are the same as the system values for the current option group"))); | ||||
| 
 | ||||
| 	m_icon_descriptions.push_back(t_icon_description(&m_bmp_value_unlock, L("UNLOCKED LOCK;" | ||||
| 		"indicates that some settings were changed and are not equal to the system values for " | ||||
| 		"the current option group.\n" | ||||
| 		"Click the UNLOCKED LOCK icon to reset all settings for current option group to " | ||||
| 		"the system values."))); | ||||
| 
 | ||||
| 	m_icon_descriptions.push_back(t_icon_description(&m_bmp_white_bullet, L("WHITE BULLET;" | ||||
| 		"for the left button: \tindicates a non-system preset,\n" | ||||
| 		"for the right button: \tindicates that the settings hasn't been modified."))); | ||||
| 
 | ||||
| 	m_icon_descriptions.push_back(t_icon_description(&m_bmp_value_revert, L("BACK ARROW;" | ||||
| 		"indicates that the settings were changed and are not equal to the last saved preset for " | ||||
| 		"the current option group.\n" | ||||
| 		"Click the BACK ARROW icon to reset all settings for the current option group to " | ||||
| 		"the last saved preset."))); | ||||
| } | ||||
| 
 | ||||
| void Tab::set_tooltips_text() | ||||
| { | ||||
| // 	m_undo_to_sys_btn->SetToolTip(_(L(	"LOCKED LOCK icon indicates that the settings are the same as the system values "
 | ||||
| // 										"for the current option group.\n"
 | ||||
| // 										"UNLOCKED LOCK icon indicates that some settings were changed and are not equal "
 | ||||
| // 										"to the system values for the current option group.\n"
 | ||||
| // 										"WHITE BULLET icon indicates a non system preset.\n\n"
 | ||||
| // 										"Click the UNLOCKED LOCK icon to reset all settings for current option group to "
 | ||||
| // 										"the system values.")));
 | ||||
| // 
 | ||||
| // 	m_undo_btn->SetToolTip(_(L(	"WHITE BULLET icon indicates that the settings are the same as in the last saved"
 | ||||
| // 								"preset  for the current option group.\n"
 | ||||
| // 								"BACK ARROW icon indicates that the settings were changed and are not equal to "
 | ||||
| // 								"the last saved preset for the current option group.\n\n"
 | ||||
| // 								"Click the BACK ARROW icon to reset all settings for the current option group to "
 | ||||
| // 								"the last saved preset.")));
 | ||||
| 
 | ||||
| 	// --- Tooltip text for reset buttons (for whole options group)
 | ||||
| 	// Text to be shown on the "Revert to system" aka "Lock to system" button next to each input field.
 | ||||
| 	m_ttg_value_lock =		_(L("LOCKED LOCK icon indicates that the settings are the same as the system values " | ||||
| 								"for the current option group")); | ||||
| 	m_ttg_value_unlock =	_(L("UNLOCKED LOCK icon indicates that some settings were changed and are not equal " | ||||
| 								"to the system values for the current option group.\n" | ||||
| 								"Click to reset all settings for current option group to the system values.")); | ||||
| 	m_ttg_white_bullet_ns =	_(L("WHITE BULLET icon indicates a non system preset.")); | ||||
| 	m_ttg_non_system =		&m_ttg_white_bullet_ns; | ||||
| 	// Text to be shown on the "Undo user changes" button next to each input field.
 | ||||
| 	m_ttg_white_bullet =	_(L("WHITE BULLET icon indicates that the settings are the same as in the last saved " | ||||
| 								"preset for the current option group.")); | ||||
| 	m_ttg_value_revert =	_(L("BACK ARROW icon indicates that the settings were changed and are not equal to " | ||||
| 								"the last saved preset for the current option group.\n" | ||||
| 								"Click to reset all settings for the current option group to the last saved preset.")); | ||||
| 
 | ||||
| 	// --- Tooltip text for reset buttons (for each option in group)
 | ||||
| 	// Text to be shown on the "Revert to system" aka "Lock to system" button next to each input field.
 | ||||
| 	m_tt_value_lock =		_(L("LOCKED LOCK icon indicates that the value is the same as the system value.")); | ||||
| 	m_tt_value_unlock =		_(L("UNLOCKED LOCK icon indicates that the value was changed and is not equal " | ||||
| 								"to the system value.\n" | ||||
| 								"Click to reset current value to the system value.")); | ||||
| 	// 	m_tt_white_bullet_ns=	_(L("WHITE BULLET icon indicates a non system preset."));
 | ||||
| 	m_tt_non_system =		&m_ttg_white_bullet_ns; | ||||
| 	// Text to be shown on the "Undo user changes" button next to each input field.
 | ||||
| 	m_tt_white_bullet =		_(L("WHITE BULLET icon indicates that the value is the same as in the last saved preset.")); | ||||
| 	m_tt_value_revert =		_(L("BACK ARROW icon indicates that the value was changed and is not equal to the last saved preset.\n" | ||||
| 								"Click to reset current value to the last saved preset.")); | ||||
| } | ||||
| 
 | ||||
| void Page::reload_config() | ||||
| { | ||||
| 	for (auto group : m_optgroups) | ||||
|  | @ -2460,10 +2489,6 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la | |||
| 		return static_cast<Tab*>(GetParent())->m_presets->get_selected_preset_parent() != nullptr; | ||||
| 	}; | ||||
| 
 | ||||
| 	optgroup->nonsys_btn_icon = [this](){ | ||||
| 		return static_cast<Tab*>(GetParent())->m_nonsys_btn_icon; | ||||
| 	}; | ||||
| 
 | ||||
| 	vsizer()->Add(optgroup->sizer, 0, wxEXPAND | wxALL, 10); | ||||
| 	m_optgroups.push_back(optgroup); | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,3 +1,6 @@ | |||
| #ifndef slic3r_Tab_hpp_ | ||||
| #define slic3r_Tab_hpp_ | ||||
| 
 | ||||
| //	 The "Expert" tab at the right of the main tabbed window.
 | ||||
| //	
 | ||||
| //	 This file implements following packages:
 | ||||
|  | @ -34,6 +37,9 @@ | |||
| namespace Slic3r { | ||||
| namespace GUI { | ||||
| 
 | ||||
| typedef std::pair<wxBitmap*, std::string>				t_icon_description; | ||||
| typedef std::vector<std::pair<wxBitmap*, std::string>>	t_icon_descriptions; | ||||
| 
 | ||||
| // Single Tab page containing a{ vsizer } of{ optgroups }
 | ||||
| // package Slic3r::GUI::Tab::Page;
 | ||||
| using ConfigOptionsGroupShp = std::shared_ptr<ConfigOptionsGroup>; | ||||
|  | @ -51,6 +57,7 @@ public: | |||
| 	{ | ||||
| 		Create(m_parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); | ||||
| 		m_vsizer = new wxBoxSizer(wxVERTICAL); | ||||
| 		m_item_color = &get_default_label_clr(); | ||||
| 		SetSizer(m_vsizer); | ||||
| 	} | ||||
| 	~Page(){} | ||||
|  | @ -71,6 +78,22 @@ public: | |||
| 	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); | ||||
| 	ConfigOptionsGroupShp	new_optgroup(const wxString& title, int noncommon_label_width = -1); | ||||
| 
 | ||||
| 	bool		set_item_colour(const wxColour *clr) { | ||||
| 		if (m_item_color != clr) { | ||||
| 			m_item_color = clr; | ||||
| 			return true; | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	const wxColour	get_item_colour() { | ||||
| 			return *m_item_color; | ||||
| 	} | ||||
| 
 | ||||
| protected: | ||||
| 	// Color of TreeCtrlItem. The wxColour will be updated only if the new wxColour pointer differs from the currently rendered one.
 | ||||
| 	const wxColour*		m_item_color; | ||||
| }; | ||||
| 
 | ||||
| // Slic3r::GUI::Tab;
 | ||||
|  | @ -85,8 +108,6 @@ protected: | |||
| 	wxBitmapComboBox*	m_presets_choice; | ||||
| 	wxBitmapButton*		m_btn_save_preset; | ||||
| 	wxBitmapButton*		m_btn_delete_preset; | ||||
| 	wxBitmap*			m_bmp_show_incompatible_presets; | ||||
| 	wxBitmap*			m_bmp_hide_incompatible_presets; | ||||
| 	wxBitmapButton*		m_btn_hide_incompatible_presets; | ||||
| 	wxBoxSizer*			m_hsizer; | ||||
| 	wxBoxSizer*			m_left_sizer; | ||||
|  | @ -96,10 +117,51 @@ protected: | |||
| 	wxButton*			m_compatible_printers_btn; | ||||
| 	wxButton*			m_undo_btn; | ||||
| 	wxButton*			m_undo_to_sys_btn; | ||||
| 	wxButton*			m_question_btn; | ||||
| 
 | ||||
| 	wxComboCtrl*		m_cc_presets_choice; | ||||
| 	wxDataViewTreeCtrl*	m_presetctrl; | ||||
| 	wxImageList*		m_preset_icons; | ||||
| 
 | ||||
| 	// Cached bitmaps.
 | ||||
| 	// A "flag" icon to be displayned next to the preset name in the Tab's combo box.
 | ||||
| 	wxBitmap			m_bmp_show_incompatible_presets; | ||||
| 	wxBitmap			m_bmp_hide_incompatible_presets; | ||||
| 	// Bitmaps to be shown on the "Revert to system" aka "Lock to system" button next to each input field.
 | ||||
| 	wxBitmap 			m_bmp_value_lock; | ||||
| 	wxBitmap 			m_bmp_value_unlock; | ||||
| 	wxBitmap 			m_bmp_white_bullet; | ||||
| 	// The following bitmap points to either m_bmp_value_unlock or m_bmp_white_bullet, depending on whether the current preset has a parent preset.
 | ||||
| 	wxBitmap 		   *m_bmp_non_system; | ||||
| 	// Bitmaps to be shown on the "Undo user changes" button next to each input field.
 | ||||
| 	wxBitmap 			m_bmp_value_revert; | ||||
| // 	wxBitmap 			m_bmp_value_unmodified;
 | ||||
| 	wxBitmap			m_bmp_question; | ||||
| 
 | ||||
| 	// Colors for ui "decoration"
 | ||||
| 	wxColour			m_sys_label_clr; | ||||
| 	wxColour			m_modified_label_clr; | ||||
| 	wxColour			m_default_text_clr; | ||||
| 
 | ||||
| 	// Tooltip text for reset buttons (for whole options group)
 | ||||
| 	wxString			m_ttg_value_lock; | ||||
| 	wxString			m_ttg_value_unlock; | ||||
| 	wxString			m_ttg_white_bullet_ns; | ||||
| 	// The following text points to either m_ttg_value_unlock or m_ttg_white_bullet_ns, depending on whether the current preset has a parent preset.
 | ||||
| 	wxString			*m_ttg_non_system; | ||||
| 	// Tooltip text to be shown on the "Undo user changes" button next to each input field.
 | ||||
| 	wxString			m_ttg_white_bullet; | ||||
| 	wxString			m_ttg_value_revert; | ||||
| 
 | ||||
| 	// Tooltip text for reset buttons (for each option in group)
 | ||||
| 	wxString			m_tt_value_lock; | ||||
| 	wxString			m_tt_value_unlock; | ||||
| 	// The following text points to either m_tt_value_unlock or m_ttg_white_bullet_ns, depending on whether the current preset has a parent preset.
 | ||||
| 	wxString			*m_tt_non_system; | ||||
| 	// Tooltip text to be shown on the "Undo user changes" button next to each input field.
 | ||||
| 	wxString			m_tt_white_bullet; | ||||
| 	wxString			m_tt_value_revert; | ||||
| 
 | ||||
| 	int					m_icon_count; | ||||
| 	std::map<std::string, size_t>	m_icon_index;		// Map from an icon file name to its index
 | ||||
| 	std::vector<PageShp>			m_pages; | ||||
|  | @ -108,9 +170,11 @@ protected: | |||
| 	bool				m_no_controller; | ||||
| 
 | ||||
| 	std::vector<std::string>	m_reload_dependent_tabs = {}; | ||||
| 	std::vector<std::string>	m_dirty_options = {}; | ||||
| 	std::vector<std::string>	m_sys_options = {}; | ||||
| 	std::vector<std::string>	m_full_options_list = {}; | ||||
| 	enum OptStatus { osSystemValue = 1, osInitValue = 2 }; | ||||
| 	std::map<std::string, int>	m_options_list; | ||||
| 	int							m_opt_status_value; | ||||
| 
 | ||||
| 	t_icon_descriptions	m_icon_descriptions = {}; | ||||
| 
 | ||||
| 	// The two following two event IDs are generated at Plater.pm by calling Wx::NewEventType.
 | ||||
| 	wxEventType			m_event_value_change = 0; | ||||
|  | @ -118,13 +182,15 @@ protected: | |||
| 
 | ||||
| 	bool				m_is_modified_values{ false }; | ||||
| 	bool				m_is_nonsys_values{ true }; | ||||
| 	bool				m_postpone_update_ui {false}; | ||||
| 
 | ||||
| 	size_t				m_selected_preset_item{ 0 }; | ||||
| 
 | ||||
| public: | ||||
| 	PresetBundle*		m_preset_bundle; | ||||
| 	bool				m_show_btn_incompatible_presets = false; | ||||
| 	PresetCollection*	m_presets; | ||||
| 	DynamicPrintConfig*	m_config; | ||||
| 	std::string			m_nonsys_btn_icon; | ||||
| 	ogStaticText*		m_parent_preset_description_line; | ||||
| 	wxStaticText*		m_colored_Label = nullptr; | ||||
| 
 | ||||
|  | @ -135,7 +201,9 @@ public: | |||
| 		Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL); | ||||
| 		get_tabs_list().push_back(this); | ||||
| 	} | ||||
| 	~Tab() { delete_tab_from_list(this); } | ||||
| 	~Tab(){ | ||||
| 		delete_tab_from_list(this); | ||||
| 	} | ||||
| 
 | ||||
| 	wxWindow*	parent() const { return m_parent; } | ||||
| 	wxString	title()	 const { return m_title; } | ||||
|  | @ -153,7 +221,7 @@ public: | |||
| 	wxSizer*	compatible_printers_widget(wxWindow* parent, wxCheckBox** checkbox, wxButton** btn); | ||||
| 
 | ||||
| 	void		update_presetsctrl(wxDataViewTreeCtrl* ui, bool show_incompatible); | ||||
| 	void		load_key_value(const std::string& opt_key, const boost::any& value); | ||||
| 	void		load_key_value(const std::string& opt_key, const boost::any& value, bool saved_value = false); | ||||
| 	void		reload_compatible_printers_widget(); | ||||
| 
 | ||||
| 	void		OnTreeSelChange(wxTreeEvent& event); | ||||
|  | @ -165,14 +233,11 @@ public: | |||
| 	void		update_show_hide_incompatible_button(); | ||||
| 	void		update_ui_from_settings(); | ||||
| 	void		update_changed_ui(); | ||||
| 	void		update_full_options_list(); | ||||
| 	void		update_sys_ui_after_sel_preset(); | ||||
| 	void		get_sys_and_mod_flags(const std::string& opt_key, bool& sys_page, bool& modified_page); | ||||
| 	void		update_changed_tree_ui(); | ||||
| 	void		update_undo_buttons(); | ||||
| 
 | ||||
| 	void		on_back_to_initial_value(); | ||||
| 	void		on_back_to_sys_value(); | ||||
| 	void		on_roll_back_value(const bool to_sys = false); | ||||
| 
 | ||||
| 	PageShp		add_options_page(const wxString& title, const std::string& icon, bool is_extruder_pages = false); | ||||
| 
 | ||||
|  | @ -180,6 +245,7 @@ public: | |||
| 	virtual void	on_preset_loaded(){} | ||||
| 	virtual void	build() = 0; | ||||
| 	virtual void	update() = 0; | ||||
| 	virtual void	init_options_list(); | ||||
| 	void			load_initial_data(); | ||||
| 	void			update_dirty(); | ||||
| 	void			update_tab_ui(); | ||||
|  | @ -189,12 +255,11 @@ public: | |||
| 	bool			set_value(const t_config_option_key& opt_key, const boost::any& value); | ||||
| 	wxSizer*		description_line_widget(wxWindow* parent, ogStaticText** StaticText); | ||||
| 	bool			current_preset_is_dirty(); | ||||
| 
 | ||||
| 	DynamicPrintConfig*	get_config() { return m_config; } | ||||
| 	PresetCollection*	get_presets() | ||||
| 	{ | ||||
| 		return m_presets; | ||||
| 	} | ||||
| 	PresetCollection*	get_presets() { return m_presets; } | ||||
| 	std::vector<std::string>	get_dependent_tabs() { return m_reload_dependent_tabs; } | ||||
| 	size_t				get_selected_preset_item() { return m_selected_preset_item; } | ||||
| 
 | ||||
| 	void			on_value_change(const std::string& opt_key, const boost::any& value); | ||||
| 
 | ||||
|  | @ -203,6 +268,8 @@ protected: | |||
| 	void			update_frequently_changed_parameters(); | ||||
|     void            update_wiping_button_visibility(); | ||||
| 	void			update_tab_presets(wxComboCtrl* ui, bool show_incompatible); | ||||
| 	void			fill_icon_descriptions(); | ||||
| 	void			set_tooltips_text(); | ||||
| }; | ||||
| 
 | ||||
| //Slic3r::GUI::Tab::Print;
 | ||||
|  | @ -248,9 +315,9 @@ public: | |||
| 	wxButton*	m_octoprint_host_test_btn; | ||||
| 
 | ||||
| 	size_t		m_extruders_count; | ||||
| 	size_t		m_extruders_count_old = 0; | ||||
| 	size_t		m_initial_extruders_count; | ||||
| 	size_t		m_sys_extruders_count; | ||||
| 	std::vector<PageShp>	m_extruder_pages; | ||||
| 
 | ||||
| 	TabPrinter() {} | ||||
| 	TabPrinter(wxNotebook* parent, bool no_controller) : Tab(parent, _(L("Printer Settings")), "printer", no_controller) {} | ||||
|  | @ -262,6 +329,7 @@ public: | |||
| 	void		extruders_count_changed(size_t extruders_count); | ||||
| 	void		build_extruder_pages(); | ||||
| 	void		on_preset_loaded() override; | ||||
| 	void		init_options_list() override; | ||||
| }; | ||||
| 
 | ||||
| class SavePresetWindow :public wxDialog | ||||
|  | @ -280,3 +348,5 @@ public: | |||
| 
 | ||||
| } // GUI
 | ||||
| } // Slic3r
 | ||||
| 
 | ||||
| #endif /* slic3r_Tab_hpp_ */ | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ void	TabIface::load_config(DynamicPrintConfig* config)	{ m_tab->load_config(*con | |||
| void	TabIface::load_key_value(char* opt_key, char* value){ m_tab->load_key_value(opt_key, static_cast<std::string>(value)); } | ||||
| bool	TabIface::current_preset_is_dirty()					{ return m_tab->current_preset_is_dirty();} | ||||
| void	TabIface::OnActivate()								{ return m_tab->OnActivate();} | ||||
| size_t	TabIface::get_selected_preset_item()				{ return m_tab->get_selected_preset_item(); } | ||||
| std::string					TabIface::title()				{ return m_tab->title().ToUTF8().data(); } | ||||
| DynamicPrintConfig*			TabIface::get_config()			{ return m_tab->get_config(); } | ||||
| PresetCollection*			TabIface::get_presets()			{ return m_tab!=nullptr ? m_tab->get_presets() : nullptr; } | ||||
|  |  | |||
|  | @ -1,3 +1,6 @@ | |||
| #ifndef slic3r_TabIface_hpp_ | ||||
| #define slic3r_TabIface_hpp_ | ||||
| 
 | ||||
| #include <vector> | ||||
| #include <string> | ||||
| 
 | ||||
|  | @ -27,9 +30,12 @@ public: | |||
| 	DynamicPrintConfig*			get_config(); | ||||
| 	PresetCollection*			get_presets(); | ||||
| 	std::vector<std::string>	get_dependent_tabs(); | ||||
| 	size_t						get_selected_preset_item(); | ||||
| 
 | ||||
| protected: | ||||
| 	GUI::Tab   *m_tab; | ||||
| }; | ||||
| }; // namespace GUI
 | ||||
| 
 | ||||
| }; // namespace Slic3r
 | ||||
| 
 | ||||
| #endif /* slic3r_TabIface_hpp_ */ | ||||
|  |  | |||
|  | @ -16,6 +16,7 @@ | |||
| 	bool		current_preset_is_dirty(); | ||||
| 	void		load_key_value(char* opt_key, char* value); | ||||
| 	void		OnActivate(); | ||||
| 	size_t		get_selected_preset_item(); | ||||
| 	std::string	title(); | ||||
| 	Ref<DynamicPrintConfig>		get_config(); | ||||
| 	Ref<PresetCollection>		get_presets(); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vojtech Kral
						Vojtech Kral