mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	Merge branch 'master' into tm_slice_index
This commit is contained in:
		
						commit
						0ffc0c3a84
					
				
					 20 changed files with 459 additions and 187 deletions
				
			
		
							
								
								
									
										
											BIN
										
									
								
								resources/icons/empty_icon.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								resources/icons/empty_icon.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 893 B | 
|  | @ -1375,6 +1375,7 @@ void PrintConfigDef::init_fff_params() | |||
|     def->sidetext = L("(minimum)"); | ||||
|     def->aliases = { "perimeter_offsets" }; | ||||
|     def->min = 0; | ||||
|     def->max = 10000; | ||||
|     def->default_value = new ConfigOptionInt(3); | ||||
| 
 | ||||
|     def = this->add("post_process", coStrings); | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ | |||
| #include "GUI_App.hpp" | ||||
| #include "I18N.hpp" | ||||
| #include "Field.hpp" | ||||
| #include "wxExtensions.hpp" | ||||
| 
 | ||||
| #include "libslic3r/PrintConfig.hpp" | ||||
| 
 | ||||
|  | @ -36,7 +37,9 @@ void Field::PostInitialize() | |||
| 	m_Undo_to_sys_btn	= new MyButton(m_parent, wxID_ANY, "", wxDefaultPosition,wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); | ||||
| 	if (wxMSW) { | ||||
| 		m_Undo_btn->SetBackgroundColour(color); | ||||
| 		m_Undo_btn->SetBackgroundStyle(wxBG_STYLE_PAINT); | ||||
| 		m_Undo_to_sys_btn->SetBackgroundColour(color); | ||||
| 		m_Undo_to_sys_btn->SetBackgroundStyle(wxBG_STYLE_PAINT); | ||||
| 	} | ||||
| 	m_Undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_initial_value(); })); | ||||
| 	m_Undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_sys_value(); })); | ||||
|  | @ -257,6 +260,12 @@ void TextCtrl::BUILD() { | |||
| 
 | ||||
|     const long style = m_opt.multiline ? wxTE_MULTILINE : wxTE_PROCESS_ENTER/*0*/; | ||||
| 	auto temp = new wxTextCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, style); | ||||
| 	temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); | ||||
| 
 | ||||
| 	if (! m_opt.multiline) | ||||
| 		// Only disable background refresh for single line input fields, as they are completely painted over by the edit control.
 | ||||
| 		// This does not apply to the multi-line edit field, where the last line and a narrow frame around the text is not cleared.
 | ||||
| 		temp->SetBackgroundStyle(wxBG_STYLE_PAINT); | ||||
| #ifdef __WXOSX__ | ||||
|     temp->OSXDisableAllSmartSubstitutions(); | ||||
| #endif // __WXOSX__
 | ||||
|  | @ -372,6 +381,8 @@ void CheckBox::BUILD() { | |||
|     					false; | ||||
| 
 | ||||
| 	auto temp = new wxCheckBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size);  | ||||
| 	temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); | ||||
| 	temp->SetBackgroundStyle(wxBG_STYLE_PAINT); | ||||
| 	temp->SetValue(check_value); | ||||
| 	if (m_opt.readonly) temp->Disable(); | ||||
| 
 | ||||
|  | @ -429,6 +440,8 @@ void SpinCtrl::BUILD() { | |||
| 
 | ||||
| 	auto temp = new wxSpinCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, | ||||
| 		0|wxTE_PROCESS_ENTER, min_val, max_val, default_value); | ||||
| 	temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); | ||||
| 	temp->SetBackgroundStyle(wxBG_STYLE_PAINT); | ||||
| 
 | ||||
| #ifndef __WXOSX__ | ||||
|     // #ys_FIXME_KILL_FOCUS 
 | ||||
|  | @ -493,15 +506,31 @@ void SpinCtrl::propagate_value() | |||
| } | ||||
| 
 | ||||
| void Choice::BUILD() { | ||||
| 	auto size = wxSize(wxDefaultSize); | ||||
|     wxSize size(15 * wxGetApp().em_unit(), -1); | ||||
| 	if (m_opt.height >= 0) size.SetHeight(m_opt.height); | ||||
| 	if (m_opt.width >= 0) size.SetWidth(m_opt.width); | ||||
| 
 | ||||
| 	wxComboBox* temp;	 | ||||
| 	if (!m_opt.gui_type.empty() && m_opt.gui_type.compare("select_open") != 0) | ||||
| 		temp = new wxComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size); | ||||
| 	else | ||||
| 		temp = new wxComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, NULL, wxCB_READONLY); | ||||
| 	wxBitmapComboBox* temp;	 | ||||
|     if (!m_opt.gui_type.empty() && m_opt.gui_type.compare("select_open") != 0) { | ||||
|         m_is_editable = true; | ||||
|         temp = new wxBitmapComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size); | ||||
|     } | ||||
|     else { | ||||
| #ifdef __WXOSX__ | ||||
|         /* wxBitmapComboBox with wxCB_READONLY style return NULL for GetTextCtrl(),
 | ||||
|          * so ToolTip doesn't shown. | ||||
|          * Next workaround helps to solve this problem | ||||
|          */ | ||||
|         temp = new wxBitmapComboBox(); | ||||
|         temp->SetTextCtrlStyle(wxTE_READONLY); | ||||
|         temp->Create(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr); | ||||
| #else | ||||
|         temp = new wxBitmapComboBox(m_parent, wxID_ANY, wxString(""), wxDefaultPosition, size, 0, nullptr, wxCB_READONLY); | ||||
| #endif //__WXOSX__
 | ||||
|     } | ||||
| 
 | ||||
| 	temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); | ||||
| 	temp->SetBackgroundStyle(wxBG_STYLE_PAINT); | ||||
| 
 | ||||
| 	// recast as a wxWindow to fit the calling convention
 | ||||
| 	window = dynamic_cast<wxWindow*>(temp); | ||||
|  | @ -511,19 +540,19 @@ void Choice::BUILD() { | |||
| 	else{ | ||||
| 		for (auto el : m_opt.enum_labels.empty() ? m_opt.enum_values : m_opt.enum_labels) { | ||||
| 			const wxString& str = _(el);//m_opt_id == "support" ? _(el) : el;
 | ||||
| 			temp->Append(str); | ||||
|             temp->Append(str, create_scaled_bitmap("empty_icon.png")); | ||||
| 		} | ||||
| 		set_selection(); | ||||
| 	} | ||||
| // 	temp->Bind(wxEVT_TEXT, ([this](wxCommandEvent e) { on_change_field(); }), temp->GetId());
 | ||||
|  	temp->Bind(wxEVT_COMBOBOX, ([this](wxCommandEvent e) { on_change_field(); }), temp->GetId()); | ||||
| 
 | ||||
|     if (temp->GetWindowStyle() != wxCB_READONLY) { | ||||
|     if (m_is_editable) { | ||||
|         temp->Bind(wxEVT_KILL_FOCUS, ([this](wxEvent& e) { | ||||
|             e.Skip(); | ||||
|             if (m_opt.type == coStrings) return; | ||||
|             double old_val = !m_value.empty() ? boost::any_cast<double>(m_value) : -99999; | ||||
|             if (is_defined_input_value<wxComboBox>(window, m_opt.type)) { | ||||
|             if (is_defined_input_value<wxBitmapComboBox>(window, m_opt.type)) { | ||||
|                 if (fabs(old_val - boost::any_cast<double>(get_value())) <= 0.0001) | ||||
|                     return; | ||||
|                 else | ||||
|  | @ -540,6 +569,8 @@ void Choice::BUILD() { | |||
| void Choice::set_selection() | ||||
| { | ||||
| 	wxString text_value = wxString(""); | ||||
| 
 | ||||
|     wxBitmapComboBox* field = dynamic_cast<wxBitmapComboBox*>(window); | ||||
| 	switch (m_opt.type) { | ||||
| 	case coFloat: | ||||
| 	case coPercent:	{ | ||||
|  | @ -554,13 +585,13 @@ void Choice::set_selection() | |||
| 		} | ||||
| //		if (m_opt.type == coPercent) text_value += "%";
 | ||||
| 		idx == m_opt.enum_values.size() ? | ||||
| 			dynamic_cast<wxComboBox*>(window)->SetValue(text_value) : | ||||
| 			dynamic_cast<wxComboBox*>(window)->SetSelection(idx); | ||||
| 			field->SetValue(text_value) : | ||||
| 			field->SetSelection(idx); | ||||
| 		break; | ||||
| 	} | ||||
| 	case coEnum:{ | ||||
| 		int id_value = static_cast<const ConfigOptionEnum<SeamPosition>*>(m_opt.default_value)->value; //!!
 | ||||
| 		dynamic_cast<wxComboBox*>(window)->SetSelection(id_value); | ||||
|         field->SetSelection(id_value); | ||||
| 		break; | ||||
| 	} | ||||
| 	case coInt:{ | ||||
|  | @ -574,8 +605,8 @@ void Choice::set_selection() | |||
| 			++idx; | ||||
| 		} | ||||
| 		idx == m_opt.enum_values.size() ? | ||||
| 			dynamic_cast<wxComboBox*>(window)->SetValue(text_value) : | ||||
| 			dynamic_cast<wxComboBox*>(window)->SetSelection(idx); | ||||
| 			field->SetValue(text_value) : | ||||
| 			field->SetSelection(idx); | ||||
| 		break; | ||||
| 	} | ||||
| 	case coStrings:{ | ||||
|  | @ -589,8 +620,8 @@ void Choice::set_selection() | |||
| 			++idx; | ||||
| 		} | ||||
| 		idx == m_opt.enum_values.size() ? | ||||
| 			dynamic_cast<wxComboBox*>(window)->SetValue(text_value) : | ||||
| 			dynamic_cast<wxComboBox*>(window)->SetSelection(idx); | ||||
| 			field->SetValue(text_value) : | ||||
| 			field->SetSelection(idx); | ||||
| 		break; | ||||
| 	} | ||||
| 	} | ||||
|  | @ -608,9 +639,10 @@ void Choice::set_value(const std::string& value, bool change_event)  //! Redunda | |||
| 		++idx; | ||||
| 	} | ||||
| 
 | ||||
|     wxBitmapComboBox* field = dynamic_cast<wxBitmapComboBox*>(window); | ||||
| 	idx == m_opt.enum_values.size() ?  | ||||
| 		dynamic_cast<wxComboBox*>(window)->SetValue(value) : | ||||
| 		dynamic_cast<wxComboBox*>(window)->SetSelection(idx); | ||||
| 		field->SetValue(value) : | ||||
| 		field->SetSelection(idx); | ||||
| 	 | ||||
| 	m_disable_change_event = false; | ||||
| } | ||||
|  | @ -619,6 +651,8 @@ void Choice::set_value(const boost::any& value, bool change_event) | |||
| { | ||||
| 	m_disable_change_event = !change_event; | ||||
| 
 | ||||
|     wxBitmapComboBox* field = dynamic_cast<wxBitmapComboBox*>(window); | ||||
| 
 | ||||
| 	switch (m_opt.type) { | ||||
| 	case coInt: | ||||
| 	case coFloat: | ||||
|  | @ -640,11 +674,11 @@ void Choice::set_value(const boost::any& value, bool change_event) | |||
|         if (idx == m_opt.enum_values.size()) { | ||||
|             // For editable Combobox under OSX is needed to set selection to -1 explicitly,
 | ||||
|             // otherwise selection doesn't be changed
 | ||||
|             dynamic_cast<wxComboBox*>(window)->SetSelection(-1); | ||||
|             dynamic_cast<wxComboBox*>(window)->SetValue(text_value); | ||||
|             field->SetSelection(-1); | ||||
|             field->SetValue(text_value); | ||||
|         } | ||||
|         else | ||||
| 			dynamic_cast<wxComboBox*>(window)->SetSelection(idx); | ||||
| 			field->SetSelection(idx); | ||||
| 		break; | ||||
| 	} | ||||
| 	case coEnum: { | ||||
|  | @ -674,7 +708,7 @@ void Choice::set_value(const boost::any& value, bool change_event) | |||
| 			else | ||||
| 				val = 0; | ||||
| 		} | ||||
| 		dynamic_cast<wxComboBox*>(window)->SetSelection(val); | ||||
| 		field->SetSelection(val); | ||||
| 		break; | ||||
| 	} | ||||
| 	default: | ||||
|  | @ -693,7 +727,7 @@ void Choice::set_values(const std::vector<std::string>& values) | |||
| 
 | ||||
| // 	# it looks that Clear() also clears the text field in recent wxWidgets versions,
 | ||||
| // 	# but we want to preserve it
 | ||||
| 	auto ww = dynamic_cast<wxComboBox*>(window); | ||||
| 	auto ww = dynamic_cast<wxBitmapComboBox*>(window); | ||||
| 	auto value = ww->GetValue(); | ||||
| 	ww->Clear(); | ||||
| 	ww->Append(""); | ||||
|  | @ -706,8 +740,9 @@ void Choice::set_values(const std::vector<std::string>& values) | |||
| 
 | ||||
| boost::any& Choice::get_value() | ||||
| { | ||||
| // 	boost::any m_value;
 | ||||
| 	wxString ret_str = static_cast<wxComboBox*>(window)->GetValue();	 | ||||
|     wxBitmapComboBox* field = dynamic_cast<wxBitmapComboBox*>(window); | ||||
| 
 | ||||
| 	wxString ret_str = field->GetValue();	 | ||||
| 
 | ||||
| 	// options from right panel
 | ||||
| 	std::vector <std::string> right_panel_options{ "support", "scale_unit" }; | ||||
|  | @ -717,7 +752,7 @@ boost::any& Choice::get_value() | |||
| 
 | ||||
| 	if (m_opt.type == coEnum) | ||||
| 	{ | ||||
| 		int ret_enum = static_cast<wxComboBox*>(window)->GetSelection();  | ||||
| 		int ret_enum = field->GetSelection();  | ||||
| 		if (m_opt_id == "top_fill_pattern" || m_opt_id == "bottom_fill_pattern") | ||||
| 		{ | ||||
| 			if (!m_opt.enum_values.empty()) { | ||||
|  | @ -746,8 +781,9 @@ boost::any& Choice::get_value() | |||
|             m_value = static_cast<SLAPillarConnectionMode>(ret_enum); | ||||
| 	} | ||||
|     else if (m_opt.gui_type == "f_enum_open") { | ||||
|         const int ret_enum = static_cast<wxComboBox*>(window)->GetSelection(); | ||||
|         if (ret_enum < 0 || m_opt.enum_values.empty() || m_opt.type == coStrings) | ||||
|         const int ret_enum = field->GetSelection(); | ||||
|         if (ret_enum < 0 || m_opt.enum_values.empty() || m_opt.type == coStrings || | ||||
|             ret_str != m_opt.enum_values[ret_enum] && ret_str != m_opt.enum_labels[ret_enum] ) | ||||
| 			// modifies ret_string!
 | ||||
|             get_value_by_opt_type(ret_str); | ||||
|         else  | ||||
|  | @ -774,6 +810,7 @@ void ColourPicker::BUILD() | |||
| 	} | ||||
| 
 | ||||
| 	auto temp = new wxColourPickerCtrl(m_parent, wxID_ANY, clr, wxDefaultPosition, size); | ||||
| 	temp->SetBackgroundStyle(wxBG_STYLE_PAINT); | ||||
| 
 | ||||
| 	// 	// recast as a wxWindow to fit the calling convention
 | ||||
| 	window = dynamic_cast<wxWindow*>(temp); | ||||
|  | @ -808,10 +845,21 @@ void PointCtrl::BUILD() | |||
| 
 | ||||
| 	x_textctrl = new wxTextCtrl(m_parent, wxID_ANY, X, wxDefaultPosition, field_size, wxTE_PROCESS_ENTER); | ||||
| 	y_textctrl = new wxTextCtrl(m_parent, wxID_ANY, Y, wxDefaultPosition, field_size, wxTE_PROCESS_ENTER); | ||||
| 	x_textctrl->SetFont(Slic3r::GUI::wxGetApp().normal_font()); | ||||
| 	x_textctrl->SetBackgroundStyle(wxBG_STYLE_PAINT); | ||||
| 	y_textctrl->SetFont(Slic3r::GUI::wxGetApp().normal_font()); | ||||
| 	y_textctrl->SetBackgroundStyle(wxBG_STYLE_PAINT); | ||||
| 
 | ||||
| 	temp->Add(new wxStaticText(m_parent, wxID_ANY, "x : "), 0, wxALIGN_CENTER_VERTICAL, 0); | ||||
| 	auto static_text_x = new wxStaticText(m_parent, wxID_ANY, "x : "); | ||||
| 	auto static_text_y = new wxStaticText(m_parent, wxID_ANY, "   y : "); | ||||
| 	static_text_x->SetFont(Slic3r::GUI::wxGetApp().normal_font()); | ||||
| 	static_text_x->SetBackgroundStyle(wxBG_STYLE_PAINT); | ||||
| 	static_text_y->SetFont(Slic3r::GUI::wxGetApp().normal_font()); | ||||
| 	static_text_y->SetBackgroundStyle(wxBG_STYLE_PAINT); | ||||
| 
 | ||||
| 	temp->Add(static_text_x, 0, wxALIGN_CENTER_VERTICAL, 0); | ||||
| 	temp->Add(x_textctrl); | ||||
| 	temp->Add(new wxStaticText(m_parent, wxID_ANY, "   y : "), 0, wxALIGN_CENTER_VERTICAL, 0); | ||||
| 	temp->Add(static_text_y, 0, wxALIGN_CENTER_VERTICAL, 0); | ||||
| 	temp->Add(y_textctrl); | ||||
| 
 | ||||
| // 	x_textctrl->Bind(wxEVT_TEXT, ([this](wxCommandEvent e) { on_change_field(); }), x_textctrl->GetId());
 | ||||
|  | @ -880,6 +928,8 @@ void StaticText::BUILD() | |||
| 
 | ||||
|     const wxString legend(static_cast<const ConfigOptionString*>(m_opt.default_value)->value); | ||||
|     auto temp = new wxStaticText(m_parent, wxID_ANY, legend, wxDefaultPosition, size, wxST_ELLIPSIZE_MIDDLE); | ||||
| 	temp->SetFont(Slic3r::GUI::wxGetApp().normal_font()); | ||||
| 	temp->SetBackgroundStyle(wxBG_STYLE_PAINT); | ||||
|     temp->SetFont(wxGetApp().bold_font()); | ||||
| 
 | ||||
| 	// 	// recast as a wxWindow to fit the calling convention
 | ||||
|  | @ -903,10 +953,14 @@ void SliderCtrl::BUILD() | |||
| 	m_slider = new wxSlider(m_parent, wxID_ANY, def_val * m_scale, | ||||
| 							min * m_scale, max * m_scale, | ||||
| 							wxDefaultPosition, size); | ||||
| 	m_slider->SetFont(Slic3r::GUI::wxGetApp().normal_font()); | ||||
| 	m_slider->SetBackgroundStyle(wxBG_STYLE_PAINT); | ||||
|  	wxSize field_size(40, -1); | ||||
| 
 | ||||
| 	m_textctrl = new wxTextCtrl(m_parent, wxID_ANY, wxString::Format("%d", m_slider->GetValue()/m_scale),  | ||||
| 								wxDefaultPosition, field_size); | ||||
| 	m_textctrl->SetFont(Slic3r::GUI::wxGetApp().normal_font()); | ||||
| 	m_textctrl->SetBackgroundStyle(wxBG_STYLE_PAINT); | ||||
| 
 | ||||
| 	temp->Add(m_slider, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL, 0); | ||||
| 	temp->Add(m_textctrl, 0, wxALIGN_CENTER_VERTICAL, 0); | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ | |||
| #include <boost/any.hpp> | ||||
| 
 | ||||
| #include <wx/spinctrl.h> | ||||
| #include <wx/bmpcbox.h> | ||||
| #include <wx/clrpicker.h> | ||||
| 
 | ||||
| #include "libslic3r/libslic3r.h" | ||||
|  | @ -351,14 +352,19 @@ public: | |||
| 	wxWindow*		window{ nullptr }; | ||||
| 	void			BUILD() override; | ||||
| 
 | ||||
|     /* Under OSX: wxBitmapComboBox->GetWindowStyle() returns some weard value, 
 | ||||
|      * so let use a flag, which has TRUE value for a control without wxCB_READONLY style | ||||
|      */ | ||||
|     bool            m_is_editable { false }; | ||||
| 
 | ||||
| 	void			set_selection(); | ||||
| 	void			set_value(const std::string& value, bool change_event = false); | ||||
| 	void			set_value(const boost::any& value, bool change_event = false); | ||||
| 	void			set_values(const std::vector<std::string> &values); | ||||
| 	boost::any&		get_value() override; | ||||
| 
 | ||||
| 	void			enable() override { dynamic_cast<wxComboBox*>(window)->Enable(); }; | ||||
| 	void			disable() override{ dynamic_cast<wxComboBox*>(window)->Disable(); }; | ||||
| 	void			enable() override { dynamic_cast<wxBitmapComboBox*>(window)->Enable(); }; | ||||
| 	void			disable() override{ dynamic_cast<wxBitmapComboBox*>(window)->Disable(); }; | ||||
| 	wxWindow*		getWindow() override { return window; } | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -34,6 +34,7 @@ | |||
| #include <wx/settings.h> | ||||
| #include <wx/tooltip.h> | ||||
| #include <wx/debug.h> | ||||
| #include <wx/fontutil.h> | ||||
| 
 | ||||
| // Print now includes tbb, and tbb includes Windows. This breaks compilation of wxWidgets if included before wx.
 | ||||
| #include "libslic3r/Print.hpp" | ||||
|  | @ -1659,13 +1660,69 @@ void GLCanvas3D::WarningTexture::activate(WarningTexture::Warning warning, bool | |||
|     _generate(text, canvas, red_colored); // GUI::GLTexture::reset() is called at the beginning of generate(...)
 | ||||
| } | ||||
| 
 | ||||
| bool GLCanvas3D::WarningTexture::_generate(const std::string& msg, const GLCanvas3D& canvas, const bool red_colored/* = false*/) | ||||
| 
 | ||||
| #ifdef __WXMSW__ | ||||
| static bool is_font_cleartype(const wxFont &font) | ||||
| { | ||||
|     // Native font description: on MSW, it is a version number plus the content of LOGFONT, separated by semicolon.
 | ||||
|     wxString font_desc = font.GetNativeFontInfoDesc(); | ||||
|     // Find the quality field.
 | ||||
|     wxString sep(";"); | ||||
|     size_t startpos = 0; | ||||
|     for (size_t i = 0; i < 12; ++ i) | ||||
|         startpos = font_desc.find(sep, startpos + 1); | ||||
|     ++ startpos; | ||||
|     size_t endpos = font_desc.find(sep, startpos); | ||||
|     int quality = wxAtoi(font_desc(startpos, endpos - startpos)); | ||||
|     return quality == CLEARTYPE_QUALITY; | ||||
| } | ||||
| 
 | ||||
| // ClearType produces renders, which are difficult to convert into an alpha blended OpenGL texture.
 | ||||
| // Therefore it is better to disable it, though Vojtech found out, that the font returned with ClearType
 | ||||
| // disabled is signifcantly thicker than the default ClearType font.
 | ||||
| // This function modifies the font provided.
 | ||||
| static void msw_disable_cleartype(wxFont &font) | ||||
| { | ||||
|     // Native font description: on MSW, it is a version number plus the content of LOGFONT, separated by semicolon.
 | ||||
|     wxString font_desc = font.GetNativeFontInfoDesc(); | ||||
|     // Find the quality field.
 | ||||
|     wxString sep(";"); | ||||
|     size_t startpos_weight = 0; | ||||
|     for (size_t i = 0; i < 5; ++ i) | ||||
|         startpos_weight = font_desc.find(sep, startpos_weight + 1); | ||||
|     ++ startpos_weight; | ||||
|     size_t endpos_weight = font_desc.find(sep, startpos_weight); | ||||
|     // Parse the weight field.
 | ||||
|     unsigned int weight = atoi(font_desc(startpos_weight, endpos_weight - startpos_weight)); | ||||
|     size_t startpos = endpos_weight; | ||||
|     for (size_t i = 0; i < 6; ++ i) | ||||
|         startpos = font_desc.find(sep, startpos + 1); | ||||
|     ++ startpos; | ||||
|     size_t endpos = font_desc.find(sep, startpos); | ||||
|     int quality = wxAtoi(font_desc(startpos, endpos - startpos)); | ||||
|     if (quality == CLEARTYPE_QUALITY) { | ||||
|         // Replace the weight with a smaller value to compensate the weight of non ClearType font.
 | ||||
|         wxString sweight    = std::to_string(weight * 2 / 4); | ||||
|         size_t   len_weight = endpos_weight - startpos_weight; | ||||
|         wxString squality   = std::to_string(ANTIALIASED_QUALITY); | ||||
|         font_desc.replace(startpos_weight, len_weight, sweight); | ||||
|         font_desc.replace(startpos + sweight.size() - len_weight, endpos - startpos, squality); | ||||
|         font.SetNativeFontInfo(font_desc); | ||||
|         wxString font_desc2 = font.GetNativeFontInfoDesc(); | ||||
|     } | ||||
|     wxString font_desc2 = font.GetNativeFontInfoDesc(); | ||||
| } | ||||
| #endif /* __WXMSW__ */ | ||||
| 
 | ||||
| bool GLCanvas3D::WarningTexture::_generate(const std::string& msg_utf8, const GLCanvas3D& canvas, const bool red_colored/* = false*/) | ||||
| { | ||||
|     reset(); | ||||
| 
 | ||||
|     if (msg.empty()) | ||||
|     if (msg_utf8.empty()) | ||||
|         return false; | ||||
| 
 | ||||
|     wxString msg = GUI::from_u8(msg_utf8); | ||||
| 
 | ||||
|     wxMemoryDC memDC; | ||||
|     // select default font
 | ||||
|     const float scale = canvas.get_canvas_size().get_scale_factor(); | ||||
|  | @ -1676,46 +1733,47 @@ bool GLCanvas3D::WarningTexture::_generate(const std::string& msg, const GLCanva | |||
| 
 | ||||
|     // calculates texture size
 | ||||
|     wxCoord w, h; | ||||
| //     memDC.GetTextExtent(msg, &w, &h);
 | ||||
|     memDC.GetMultiLineTextExtent(msg, &w, &h); | ||||
| 
 | ||||
|     int pow_of_two_size = next_highest_power_of_2(std::max<unsigned int>(w, h)); | ||||
| 
 | ||||
|     m_original_width = (int)w; | ||||
|     m_original_height = (int)h; | ||||
|     m_width = pow_of_two_size; | ||||
|     m_height = pow_of_two_size; | ||||
|     m_width = (int)next_highest_power_of_2((uint32_t)w); | ||||
| 	m_height = (int)next_highest_power_of_2((uint32_t)h); | ||||
| 
 | ||||
|     // generates bitmap
 | ||||
|     wxBitmap bitmap(m_width, m_height); | ||||
| 
 | ||||
|     memDC.SelectObject(bitmap); | ||||
|     memDC.SetBackground(wxBrush(wxColour(Background_Color[0], Background_Color[1], Background_Color[2]))); | ||||
|     memDC.SetBackground(wxBrush(*wxBLACK)); | ||||
|     memDC.Clear(); | ||||
| 
 | ||||
|     // draw message
 | ||||
|     memDC.SetTextForeground(red_colored ? wxColour(255,72,65/*204,204*/) : *wxWHITE); | ||||
| //     memDC.DrawText(msg, 0, 0);
 | ||||
|     memDC.DrawLabel(msg, wxRect(0,0, m_original_width, m_original_height), wxALIGN_CENTER); | ||||
|     memDC.SetTextForeground(*wxRED); | ||||
| 	memDC.DrawLabel(msg, wxRect(0,0, m_original_width, m_original_height), wxALIGN_CENTER); | ||||
| 
 | ||||
|     memDC.SelectObject(wxNullBitmap); | ||||
| 
 | ||||
|     // Convert the bitmap into a linear data ready to be loaded into the GPU.
 | ||||
|     wxImage image = bitmap.ConvertToImage(); | ||||
|     image.SetMaskColour(Background_Color[0], Background_Color[1], Background_Color[2]); | ||||
| 
 | ||||
|     // prepare buffer
 | ||||
|     std::vector<unsigned char> data(4 * m_width * m_height, 0); | ||||
|     const unsigned char *src = image.GetData(); | ||||
|     for (int h = 0; h < m_height; ++h) | ||||
|     { | ||||
|         int hh = h * m_width; | ||||
|         unsigned char* px_ptr = data.data() + 4 * hh; | ||||
|         unsigned char* dst = data.data() + 4 * h * m_width; | ||||
|         for (int w = 0; w < m_width; ++w) | ||||
|         { | ||||
|             *px_ptr++ = image.GetRed(w, h); | ||||
|             *px_ptr++ = image.GetGreen(w, h); | ||||
|             *px_ptr++ = image.GetBlue(w, h); | ||||
|             *px_ptr++ = image.IsTransparent(w, h) ? 0 : Opacity; | ||||
|             *dst++ = 255; | ||||
|             if (red_colored) { | ||||
|                 *dst++ = 72; // 204
 | ||||
|                 *dst++ = 65; // 204
 | ||||
|             } else { | ||||
|                 *dst++ = 255; | ||||
|                 *dst++ = 255; | ||||
|             } | ||||
| 			*dst++ = (unsigned char)std::min<int>(255, *src); | ||||
|             src += 3; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -1839,7 +1897,15 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c | |||
|     const int scaled_border = Px_Border * scale; | ||||
| 
 | ||||
|     // select default font
 | ||||
|     const wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale_gl); | ||||
|     wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Scale(scale_gl); | ||||
| #ifdef __WXMSW__ | ||||
|     // Disabling ClearType works, but the font returned is very different (much thicker) from the default.
 | ||||
| //    msw_disable_cleartype(font);
 | ||||
|     bool cleartype = is_font_cleartype(font); | ||||
| #else | ||||
|     bool cleartype = false; | ||||
| #endif /* __WXMSW__ */ | ||||
| 
 | ||||
|     memDC.SetFont(font); | ||||
|     mask_memDC.SetFont(font); | ||||
| 
 | ||||
|  | @ -1863,10 +1929,8 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c | |||
|     if (items_count > 1) | ||||
|         m_original_height += (items_count - 1) * scaled_square_contour; | ||||
| 
 | ||||
|     int pow_of_two_size = (int)next_highest_power_of_2(std::max<uint32_t>(m_original_width, m_original_height)); | ||||
| 
 | ||||
|     m_width = pow_of_two_size; | ||||
|     m_height = pow_of_two_size; | ||||
| 	m_width = (int)next_highest_power_of_2((uint32_t)m_original_width); | ||||
| 	m_height = (int)next_highest_power_of_2((uint32_t)m_original_height); | ||||
| 
 | ||||
|     // generates bitmap
 | ||||
|     wxBitmap bitmap(m_width, m_height); | ||||
|  | @ -1883,16 +1947,13 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c | |||
| 
 | ||||
|     // draw title
 | ||||
|     memDC.SetTextForeground(*wxWHITE); | ||||
|     mask_memDC.SetTextForeground(*wxWHITE); | ||||
| 	mask_memDC.SetTextForeground(*wxRED); | ||||
| 
 | ||||
|     int title_x = scaled_border; | ||||
|     int title_y = scaled_border; | ||||
|     memDC.DrawText(title, title_x, title_y); | ||||
|     mask_memDC.DrawText(title, title_x, title_y); | ||||
| 
 | ||||
|     mask_memDC.SetPen(wxPen(*wxWHITE)); | ||||
|     mask_memDC.SetBrush(wxBrush(*wxWHITE)); | ||||
| 
 | ||||
|     // draw icons contours as background
 | ||||
|     int squares_contour_x = scaled_border; | ||||
|     int squares_contour_y = scaled_border + title_height + scaled_title_offset; | ||||
|  | @ -1907,7 +1968,6 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c | |||
|     memDC.SetPen(pen); | ||||
|     memDC.SetBrush(brush); | ||||
|     memDC.DrawRectangle(wxRect(squares_contour_x, squares_contour_y, squares_contour_width, squares_contour_height)); | ||||
|     mask_memDC.DrawRectangle(wxRect(squares_contour_x, squares_contour_y, squares_contour_width, squares_contour_height)); | ||||
| 
 | ||||
|     // draw items (colored icon + text)
 | ||||
|     int icon_x = squares_contour_x + scaled_square_contour; | ||||
|  | @ -1943,7 +2003,6 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c | |||
|         memDC.DrawRectangle(wxRect(icon_x_inner, icon_y + 1, px_inner_square, px_inner_square)); | ||||
| 
 | ||||
|         // draw text
 | ||||
|         memDC.DrawText(GUI::from_u8(item.text), text_x, icon_y + text_y_offset); | ||||
|         mask_memDC.DrawText(GUI::from_u8(item.text), text_x, icon_y + text_y_offset); | ||||
| 
 | ||||
|         // update y
 | ||||
|  | @ -1959,17 +2018,34 @@ bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, c | |||
| 
 | ||||
|     // prepare buffer
 | ||||
|     std::vector<unsigned char> data(4 * m_width * m_height, 0); | ||||
|     for (int h = 0; h < m_height; ++h) | ||||
| 	const unsigned char *src_image = image.GetData(); | ||||
|     const unsigned char *src_mask  = mask_image.GetData(); | ||||
| 	for (int h = 0; h < m_height; ++h) | ||||
|     { | ||||
|         int hh = h * m_width; | ||||
|         unsigned char* px_ptr = data.data() + 4 * hh; | ||||
|         for (int w = 0; w < m_width; ++w) | ||||
|         { | ||||
|             unsigned char alpha = (mask_image.GetRed(w, h) + mask_image.GetGreen(w, h) + mask_image.GetBlue(w, h)) / 3; | ||||
|             *px_ptr++ = image.GetRed(w, h); | ||||
|             *px_ptr++ = image.GetGreen(w, h); | ||||
|             *px_ptr++ = image.GetBlue(w, h); | ||||
|             *px_ptr++ = (alpha == 0) ? 128 : 255; | ||||
| 			if (w >= squares_contour_x && w < squares_contour_x + squares_contour_width && | ||||
| 				h >= squares_contour_y && h < squares_contour_y + squares_contour_height) { | ||||
| 				// Color palette, use the color verbatim.
 | ||||
| 				*px_ptr++ = *src_image++; | ||||
| 				*px_ptr++ = *src_image++; | ||||
| 				*px_ptr++ = *src_image++; | ||||
| 				*px_ptr++ = 255; | ||||
| 			} else { | ||||
| 				// Text or background
 | ||||
| 				unsigned char alpha = *src_mask; | ||||
| 				// Compensate the white color for the 50% opacity reduction at the character edges.
 | ||||
|                 //unsigned char color = (unsigned char)floor(alpha * 255.f / (128.f + 0.5f * alpha));
 | ||||
|                 unsigned char color = alpha; | ||||
| 				*px_ptr++ = color; | ||||
| 				*px_ptr++ = color; // *src_mask ++;
 | ||||
| 				*px_ptr++ = color; // *src_mask ++;
 | ||||
| 				*px_ptr++ = 128 + (alpha / 2); // (alpha > 0) ? 255 : 128;
 | ||||
| 				src_image += 3; | ||||
| 			} | ||||
|             src_mask += 3; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -17,6 +17,7 @@ | |||
| #include <wx/dir.h> | ||||
| #include <wx/wupdlock.h> | ||||
| #include <wx/filefn.h> | ||||
| #include <wx/sysopt.h> | ||||
| 
 | ||||
| #include "libslic3r/Utils.hpp" | ||||
| #include "libslic3r/Model.hpp" | ||||
|  | @ -93,6 +94,12 @@ bool GUI_App::OnInit() | |||
|     SetAppName("Slic3rPE-beta"); | ||||
|     SetAppDisplayName("Slic3r Prusa Edition"); | ||||
| 
 | ||||
| // Enable this to get the default Win32 COMCTRL32 behavior of static boxes.
 | ||||
| //    wxSystemOptions::SetOption("msw.staticbox.optimized-paint", 0);
 | ||||
| // Enable this to disable Windows Vista themes for all wxNotebooks. The themes seem to lead to terrible
 | ||||
| // performance when working on high resolution multi-display setups.
 | ||||
| //    wxSystemOptions::SetOption("msw.notebook.themed-background", 0);
 | ||||
| 
 | ||||
| //     Slic3r::debugf "wxWidgets version %s, Wx version %s\n", wxVERSION_STRING, wxVERSION;
 | ||||
| 
 | ||||
|     // Set the Slic3r data directory at the Slic3r XS module.
 | ||||
|  | @ -246,6 +253,7 @@ void GUI_App::init_fonts() | |||
| { | ||||
|     m_small_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); | ||||
|     m_bold_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT).Bold(); | ||||
|     m_normal_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); | ||||
| 
 | ||||
| #ifdef __WXMAC__ | ||||
|     m_small_font.SetPointSize(11); | ||||
|  | @ -493,7 +501,7 @@ Tab* GUI_App::get_tab(Preset::Type type) | |||
| { | ||||
|     for (Tab* tab: tabs_list) | ||||
|         if (tab->type() == type) | ||||
|             return tab; | ||||
|             return tab->complited() ? tab : nullptr; // To avoid actions with no-completed Tab
 | ||||
|     return nullptr; | ||||
| } | ||||
| 
 | ||||
|  | @ -522,7 +530,7 @@ void GUI_App::update_mode() | |||
|     sidebar().update_mode(); | ||||
| 
 | ||||
|     for (auto tab : tabs_list) | ||||
|         tab->update_visibility(); | ||||
|         tab->update_mode(); | ||||
| 
 | ||||
|     plater()->update_object_menu(); | ||||
| } | ||||
|  | @ -738,6 +746,13 @@ wxNotebook* GUI_App::tab_panel() const | |||
|     return mainframe->m_tabpanel; | ||||
| } | ||||
| 
 | ||||
| int GUI_App::extruders_cnt() const | ||||
| { | ||||
|     const Preset& preset = preset_bundle->printers.get_selected_preset(); | ||||
|     return preset.printer_technology() == ptSLA ? 1 : | ||||
|            preset.config.option<ConfigOptionFloats>("nozzle_diameter")->values.size(); | ||||
| } | ||||
| 
 | ||||
| void GUI_App::window_pos_save(wxTopLevelWindow* window, const std::string &name) | ||||
| { | ||||
|     if (name.empty()) { return; } | ||||
|  |  | |||
|  | @ -78,6 +78,7 @@ class GUI_App : public wxApp | |||
| 
 | ||||
|     wxFont		    m_small_font; | ||||
|     wxFont		    m_bold_font; | ||||
| 	wxFont			m_normal_font; | ||||
| 
 | ||||
|     size_t          m_em_unit; // width of a "m"-symbol in pixels for current system font 
 | ||||
|                                // Note: for 100% Scale m_em_unit = 10 -> it's a good enough coefficient for a size setting of controls
 | ||||
|  | @ -106,6 +107,7 @@ public: | |||
| 
 | ||||
|     const wxFont&   small_font()            { return m_small_font; } | ||||
|     const wxFont&   bold_font()             { return m_bold_font; } | ||||
|     const wxFont&   normal_font()           { return m_normal_font; } | ||||
|     size_t          em_unit() const         { return m_em_unit; } | ||||
|     void            set_em_unit(const size_t em_unit)    { m_em_unit = em_unit; } | ||||
| 
 | ||||
|  | @ -158,6 +160,7 @@ public: | |||
|     Plater*         plater_{ nullptr }; | ||||
| 
 | ||||
|     wxNotebook*     tab_panel() const ; | ||||
|     int             extruders_cnt() const; | ||||
| 
 | ||||
|     std::vector<Tab *>      tabs_list; | ||||
| 
 | ||||
|  |  | |||
|  | @ -52,8 +52,7 @@ static DynamicPrintConfig& printer_config() | |||
| 
 | ||||
| static int extruders_count() | ||||
| { | ||||
|     return printer_technology() == ptSLA ? 1 : | ||||
|         printer_config().option<ConfigOptionFloats>("nozzle_diameter")->values.size(); | ||||
|     return wxGetApp().extruders_cnt(); | ||||
| } | ||||
| 
 | ||||
| ObjectList::ObjectList(wxWindow* parent) : | ||||
|  | @ -96,7 +95,7 @@ ObjectList::ObjectList(wxWindow* parent) : | |||
| #endif //__WXMSW__        
 | ||||
|     }); | ||||
| 
 | ||||
| //     Bind(wxEVT_CHAR, [this](wxKeyEvent& event) { key_event(event); }); // doesn't work on OSX
 | ||||
|     Bind(wxEVT_CHAR, [this](wxKeyEvent& event) { key_event(event); }); // doesn't work on OSX
 | ||||
| 
 | ||||
| #ifdef __WXMSW__ | ||||
|     GetMainWindow()->Bind(wxEVT_MOTION, [this](wxMouseEvent& event) { | ||||
|  | @ -443,8 +442,6 @@ void ObjectList::OnContextMenu(wxDataViewEvent&) | |||
|         if (is_windows10()) | ||||
|             fix_through_netfabb(); | ||||
|     } | ||||
|     else if (title == _("Extruder")) | ||||
|         show_extruder_selection_menu(); | ||||
| 
 | ||||
| #ifndef __WXMSW__ | ||||
|     GetMainWindow()->SetToolTip(""); // hide tooltip
 | ||||
|  | @ -458,7 +455,7 @@ void ObjectList::show_context_menu() | |||
|         if (selected_instances_of_same_object()) | ||||
|             wxGetApp().plater()->PopupMenu(&m_menu_instance); | ||||
|         else | ||||
|             show_extruder_selection_menu(); | ||||
|             show_multi_selection_menu(); | ||||
| 
 | ||||
|         return; | ||||
|     } | ||||
|  | @ -990,10 +987,14 @@ wxMenuItem* ObjectList::append_menu_item_instance_to_object(wxMenu* menu) | |||
|         [this](wxCommandEvent&) { split_instances(); }, "", menu); | ||||
| } | ||||
| 
 | ||||
| void ObjectList::append_menu_item_rename(wxMenu* menu) | ||||
| void ObjectList::append_menu_items_osx(wxMenu* menu) | ||||
| { | ||||
|     append_menu_item(menu, wxID_ANY, _(L("Delete item")), "", | ||||
|         [this](wxCommandEvent&) { remove(); }, "", menu); | ||||
|      | ||||
|     append_menu_item(menu, wxID_ANY, _(L("Rename")), "", | ||||
|         [this](wxCommandEvent&) { rename_item(); }, "", menu); | ||||
|      | ||||
|     menu->AppendSeparator(); | ||||
| } | ||||
| 
 | ||||
|  | @ -1016,7 +1017,7 @@ void ObjectList::append_menu_item_export_stl(wxMenu* menu) const | |||
| void ObjectList::create_object_popupmenu(wxMenu *menu) | ||||
| { | ||||
| #ifdef __WXOSX__   | ||||
|     append_menu_item_rename(menu); | ||||
|     append_menu_items_osx(menu); | ||||
| #endif // __WXOSX__
 | ||||
| 
 | ||||
|     append_menu_item_export_stl(menu); | ||||
|  | @ -1037,7 +1038,7 @@ void ObjectList::create_object_popupmenu(wxMenu *menu) | |||
| void ObjectList::create_sla_object_popupmenu(wxMenu *menu) | ||||
| { | ||||
| #ifdef __WXOSX__   | ||||
|     append_menu_item_rename(menu); | ||||
|     append_menu_items_osx(menu); | ||||
| #endif // __WXOSX__
 | ||||
| 
 | ||||
|     append_menu_item_export_stl(menu); | ||||
|  | @ -1049,7 +1050,7 @@ void ObjectList::create_sla_object_popupmenu(wxMenu *menu) | |||
| void ObjectList::create_part_popupmenu(wxMenu *menu) | ||||
| { | ||||
| #ifdef __WXOSX__   | ||||
|     append_menu_item_rename(menu); | ||||
|     append_menu_items_osx(menu); | ||||
| #endif // __WXOSX__
 | ||||
| 
 | ||||
|     append_menu_item_fix_through_netfabb(menu); | ||||
|  | @ -1857,8 +1858,11 @@ void ObjectList::remove() | |||
|     { | ||||
|         if (m_objects_model->GetParent(item) == wxDataViewItem(0)) | ||||
|             delete_from_model_and_list(itObject, m_objects_model->GetIdByItem(item), -1); | ||||
|         else | ||||
|         else { | ||||
|             if (sels.size() == 1) | ||||
|                 select_item(m_objects_model->GetParent(item)); | ||||
|             del_subobject_item(item); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -2358,7 +2362,7 @@ void ObjectList::OnEditingDone(wxDataViewEvent &event) | |||
|                          _(L("the following characters are not allowed:")) + " <>:/\\|?*\""); | ||||
| } | ||||
| 
 | ||||
| void ObjectList::show_extruder_selection_menu() | ||||
| void ObjectList::show_multi_selection_menu() | ||||
| { | ||||
|     wxDataViewItemArray sels; | ||||
|     GetSelections(sels); | ||||
|  | @ -2369,9 +2373,17 @@ void ObjectList::show_extruder_selection_menu() | |||
|             return; | ||||
| 
 | ||||
|     wxMenu* menu = new wxMenu(); | ||||
|     append_menu_item(menu, wxID_ANY, _(L("Set extruder for selected items")), | ||||
|         _(L("Select extruder number for selected objects and/or parts")), | ||||
|         [this](wxCommandEvent&) { extruder_selection(); }, "", menu); | ||||
| 
 | ||||
| #ifdef __WXOSX__ | ||||
|     append_menu_item(menu, wxID_ANY, _(L("Delete items")), "", | ||||
|         [this](wxCommandEvent&) { remove(); }, "", menu); | ||||
| #endif //__WXOSX__
 | ||||
| 
 | ||||
|     if (extruders_count() > 1) | ||||
|         append_menu_item(menu, wxID_ANY, _(L("Set extruder for selected items")), | ||||
|             _(L("Select extruder number for selected objects and/or parts")), | ||||
|             [this](wxCommandEvent&) { extruder_selection(); }, "", menu); | ||||
| 
 | ||||
|     PopupMenu(menu); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -184,7 +184,7 @@ public: | |||
|     wxMenuItem*         append_menu_item_settings(wxMenu* menu); | ||||
|     wxMenuItem*         append_menu_item_change_type(wxMenu* menu); | ||||
|     wxMenuItem*         append_menu_item_instance_to_object(wxMenu* menu); | ||||
|     void                append_menu_item_rename(wxMenu* menu); | ||||
|     void                append_menu_items_osx(wxMenu* menu); | ||||
|     void                append_menu_item_fix_through_netfabb(wxMenu* menu); | ||||
|     void                append_menu_item_export_stl(wxMenu* menu) const ; | ||||
|     void                create_object_popupmenu(wxMenu *menu); | ||||
|  | @ -283,7 +283,7 @@ private: | |||
|     void ItemValueChanged(wxDataViewEvent &event); | ||||
|     void OnEditingDone(wxDataViewEvent &event); | ||||
| 
 | ||||
|     void show_extruder_selection_menu(); | ||||
|     void show_multi_selection_menu(); | ||||
|     void extruder_selection(); | ||||
|     void set_extruder_for_selected_items(const int extruder) const ; | ||||
| 
 | ||||
|  |  | |||
|  | @ -174,7 +174,9 @@ Preview::Preview(wxWindow* parent, Bed3D& bed, Camera& camera, GLToolbar& view_t | |||
|     , m_loaded(false) | ||||
|     , m_enabled(false) | ||||
|     , m_schedule_background_process(schedule_background_process_func) | ||||
| #ifdef __linux__ | ||||
|     , m_volumes_cleanup_required(false) | ||||
| #endif // __linux__
 | ||||
| { | ||||
|     if (init(parent, bed, camera, view_toolbar)) | ||||
|     { | ||||
|  | @ -354,31 +356,28 @@ void Preview::load_print(bool keep_z_range) | |||
| 
 | ||||
| void Preview::reload_print(bool keep_volumes) | ||||
| { | ||||
| #ifndef __linux__ | ||||
|     if (m_volumes_cleanup_required || !keep_volumes) | ||||
|     { | ||||
|         m_canvas->reset_volumes(); | ||||
|         m_canvas->reset_legend_texture(); | ||||
|         m_loaded = false; | ||||
|         m_volumes_cleanup_required = false; | ||||
|     } | ||||
| #endif // __linux__
 | ||||
| 
 | ||||
| #ifdef __linux__ | ||||
|     // We are getting mysterious crashes on Linux in gtk due to OpenGL context activation GH #1874 #1955.
 | ||||
|     // So we are applying a workaround here: a delayed release of OpenGL vertex buffers.
 | ||||
|     if (!IsShown()) | ||||
|     { | ||||
|         m_volumes_cleanup_required = !keep_volumes; | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
| #endif /* __linux __ */ | ||||
|     if ( | ||||
| #ifdef __linux__ | ||||
|     if (m_volumes_cleanup_required || !keep_volumes) | ||||
|         m_volumes_cleanup_required ||  | ||||
| #endif /* __linux__ */ | ||||
|         !keep_volumes) | ||||
|     { | ||||
|         m_canvas->reset_volumes(); | ||||
|         m_canvas->reset_legend_texture(); | ||||
|         m_loaded = false; | ||||
| #ifdef __linux__ | ||||
|         m_volumes_cleanup_required = false; | ||||
| #endif /* __linux__ */ | ||||
|     } | ||||
| #endif // __linux__
 | ||||
| 
 | ||||
|     load_print(); | ||||
| } | ||||
|  |  | |||
|  | @ -84,7 +84,11 @@ class Preview : public wxPanel | |||
|     BackgroundSlicingProcess* m_process; | ||||
|     GCodePreviewData* m_gcode_preview_data; | ||||
| 
 | ||||
| #ifdef __linux__ | ||||
|     // We are getting mysterious crashes on Linux in gtk due to OpenGL context activation GH #1874 #1955.
 | ||||
|     // So we are applying a workaround here.
 | ||||
|     bool m_volumes_cleanup_required; | ||||
| #endif /* __linux__ */ | ||||
| 
 | ||||
|     // Calling this function object forces Plater::schedule_background_process.
 | ||||
|     std::function<void()> m_schedule_background_process; | ||||
|  |  | |||
|  | @ -96,6 +96,12 @@ wxFrame(NULL, wxID_ANY, SLIC3R_BUILD, wxDefaultPosition, wxDefaultSize, wxDEFAUL | |||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // Weird things happen as the Paint messages are floating around the windows being destructed.
 | ||||
|         // Avoid the Paint messages by hiding the main window.
 | ||||
|         // Also the application closes much faster without these unnecessary screen refreshes.
 | ||||
|         // In addition, there were some crashes due to the Paint events sent to already destructed windows.
 | ||||
|         this->Show(false); | ||||
| 
 | ||||
|         // Save the slic3r.ini.Usually the ini file is saved from "on idle" callback,
 | ||||
|         // but in rare cases it may not have been called yet.
 | ||||
|         wxGetApp().app_config->save(); | ||||
|  | @ -127,7 +133,9 @@ wxFrame(NULL, wxID_ANY, SLIC3R_BUILD, wxDefaultPosition, wxDefaultSize, wxDEFAUL | |||
| 
 | ||||
| void MainFrame::init_tabpanel() | ||||
| { | ||||
|     m_tabpanel = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL); | ||||
|     // wxNB_NOPAGETHEME: Disable Windows Vista theme for the Notebook background. The theme performance is terrible on Windows 10
 | ||||
|     // with multiple high resolution displays connected.
 | ||||
|     m_tabpanel = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME); | ||||
| 
 | ||||
|     m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, [this](wxEvent&) { | ||||
|         auto panel = m_tabpanel->GetCurrentPage(); | ||||
|  |  | |||
|  | @ -23,18 +23,18 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co | |||
|     // is the normal type.
 | ||||
|     if (opt.gui_type.compare("select") == 0) { | ||||
|     } else if (opt.gui_type.compare("select_open") == 0) { | ||||
| 		m_fields.emplace(id, std::move(Choice::Create<Choice>(parent(), opt, id))); | ||||
| 		m_fields.emplace(id, std::move(Choice::Create<Choice>(this->ctrl_parent(), opt, id))); | ||||
|     } else if (opt.gui_type.compare("color") == 0) { | ||||
| 		m_fields.emplace(id, std::move(ColourPicker::Create<ColourPicker>(parent(), opt, id))); | ||||
| 		m_fields.emplace(id, std::move(ColourPicker::Create<ColourPicker>(this->ctrl_parent(), opt, id))); | ||||
|     } else if (opt.gui_type.compare("f_enum_open") == 0 ||  | ||||
|                 opt.gui_type.compare("i_enum_open") == 0 || | ||||
|                 opt.gui_type.compare("i_enum_closed") == 0) { | ||||
| 		m_fields.emplace(id, std::move(Choice::Create<Choice>(parent(), opt, id))); | ||||
| 		m_fields.emplace(id, std::move(Choice::Create<Choice>(this->ctrl_parent(), opt, id))); | ||||
|     } else if (opt.gui_type.compare("slider") == 0) { | ||||
| 		m_fields.emplace(id, std::move(SliderCtrl::Create<SliderCtrl>(parent(), opt, id))); | ||||
| 		m_fields.emplace(id, std::move(SliderCtrl::Create<SliderCtrl>(this->ctrl_parent(), opt, id))); | ||||
|     } else if (opt.gui_type.compare("i_spin") == 0) { // Spinctrl
 | ||||
|     } else if (opt.gui_type.compare("legend") == 0) { // StaticText
 | ||||
| 		m_fields.emplace(id, std::move(StaticText::Create<StaticText>(parent(), opt, id))); | ||||
| 		m_fields.emplace(id, std::move(StaticText::Create<StaticText>(this->ctrl_parent(), opt, id))); | ||||
|     } else {  | ||||
|         switch (opt.type) { | ||||
|             case coFloatOrPercent: | ||||
|  | @ -44,21 +44,21 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co | |||
| 			case coPercents: | ||||
| 			case coString: | ||||
| 			case coStrings: | ||||
| 				m_fields.emplace(id, std::move(TextCtrl::Create<TextCtrl>(parent(), opt, id))); | ||||
| 				m_fields.emplace(id, std::move(TextCtrl::Create<TextCtrl>(this->ctrl_parent(), opt, id))); | ||||
|                 break; | ||||
| 			case coBool: | ||||
| 			case coBools: | ||||
| 				m_fields.emplace(id, std::move(CheckBox::Create<CheckBox>(parent(), opt, id))); | ||||
| 				m_fields.emplace(id, std::move(CheckBox::Create<CheckBox>(this->ctrl_parent(), opt, id))); | ||||
| 				break; | ||||
| 			case coInt: | ||||
| 			case coInts: | ||||
| 				m_fields.emplace(id, std::move(SpinCtrl::Create<SpinCtrl>(parent(), opt, id))); | ||||
| 				m_fields.emplace(id, std::move(SpinCtrl::Create<SpinCtrl>(this->ctrl_parent(), opt, id))); | ||||
| 				break; | ||||
|             case coEnum: | ||||
| 				m_fields.emplace(id, std::move(Choice::Create<Choice>(parent(), opt, id))); | ||||
| 				m_fields.emplace(id, std::move(Choice::Create<Choice>(this->ctrl_parent(), opt, id))); | ||||
| 				break; | ||||
|             case coPoints: | ||||
| 				m_fields.emplace(id, std::move(PointCtrl::Create<PointCtrl>(parent(), opt, id))); | ||||
| 				m_fields.emplace(id, std::move(PointCtrl::Create<PointCtrl>(this->ctrl_parent(), opt, id))); | ||||
| 				break; | ||||
|             case coNone:   break; | ||||
|             default: | ||||
|  | @ -119,7 +119,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText**	full_Label/* = n | |||
|             return; | ||||
|         } | ||||
|         if (line.widget != nullptr) { | ||||
|             sizer->Add(line.widget(m_parent), 0, wxEXPAND | wxALL, wxOSX ? 0 : 15); | ||||
|             sizer->Add(line.widget(this->ctrl_parent()), 0, wxEXPAND | wxALL, wxOSX ? 0 : 15); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|  | @ -138,7 +138,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText**	full_Label/* = n | |||
| 		option_set.front().opt.sidetext.size() == 0 && option_set.front().side_widget == nullptr &&  | ||||
| 		line.get_extra_widgets().size() == 0) { | ||||
| 		wxSizer* tmp_sizer; | ||||
| #ifdef __WXGTK__ | ||||
| #if 0//#ifdef __WXGTK__
 | ||||
| 		tmp_sizer = new wxBoxSizer(wxVERTICAL); | ||||
|         m_panel->SetSizer(tmp_sizer); | ||||
|         m_panel->Layout(); | ||||
|  | @ -160,14 +160,14 @@ void OptionsGroup::append_line(const Line& line, wxStaticText**	full_Label/* = n | |||
| 	} | ||||
| 
 | ||||
|     auto grid_sizer = m_grid_sizer; | ||||
| #ifdef __WXGTK__ | ||||
| #if 0//#ifdef __WXGTK__
 | ||||
|         m_panel->SetSizer(m_grid_sizer); | ||||
|         m_panel->Layout(); | ||||
| #endif /* __WXGTK__ */ | ||||
| 
 | ||||
| 	// if we have an extra column, build it
 | ||||
| 	if (extra_column) | ||||
| 		grid_sizer->Add(extra_column(parent(), line), 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3); | ||||
| 		grid_sizer->Add(extra_column(this->ctrl_parent(), line), 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 3); | ||||
| 
 | ||||
|     // Build a label if we have it
 | ||||
| 	wxStaticText* label=nullptr; | ||||
|  | @ -179,18 +179,21 @@ void OptionsGroup::append_line(const Line& line, wxStaticText**	full_Label/* = n | |||
| 		// Text is properly aligned only when Ellipsize is checked.
 | ||||
| 		label_style |= staticbox ? 0 : wxST_ELLIPSIZE_END; | ||||
| #endif /* __WXGTK__ */ | ||||
| 		label = new wxStaticText(parent(), wxID_ANY, line.label + (line.label.IsEmpty() ? "" : ": "),  | ||||
| 		label = new wxStaticText(this->ctrl_parent(), wxID_ANY, line.label + (line.label.IsEmpty() ? "" : ": "),  | ||||
| 							wxDefaultPosition, wxSize(label_width, -1), label_style); | ||||
| 		label->SetBackgroundStyle(wxBG_STYLE_PAINT); | ||||
|         label->SetFont(label_font); | ||||
|         label->Wrap(label_width); // avoid a Linux/GTK bug
 | ||||
|         if (!line.near_label_widget) | ||||
|             grid_sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, line.label.IsEmpty() ? 0 : 5); | ||||
|         else if (line.near_label_widget && line.label.IsEmpty()) | ||||
|             grid_sizer->Add(line.near_label_widget(this->ctrl_parent()), 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 7); | ||||
|         else { | ||||
|             // If we're here, we have some widget near the label
 | ||||
|             // so we need a horizontal sizer to arrange these things
 | ||||
|             auto sizer = new wxBoxSizer(wxHORIZONTAL); | ||||
|             grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM | wxTOP | wxLEFT), staticbox ? 0 : 1); | ||||
|             sizer->Add(line.near_label_widget(parent()), 0, wxRIGHT, 7); | ||||
|             sizer->Add(line.near_label_widget(this->ctrl_parent()), 0, wxRIGHT, 7); | ||||
|             sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, 5); | ||||
|         } | ||||
| 		if (line.label_tooltip.compare("") != 0) | ||||
|  | @ -201,7 +204,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText**	full_Label/* = n | |||
|         *full_Label = label; // Initiate the pointer to the control of the full label, if we need this one.
 | ||||
|     // If there's a widget, build it and add the result to the sizer.
 | ||||
| 	if (line.widget != nullptr) { | ||||
| 		auto wgt = line.widget(parent()); | ||||
| 		auto wgt = line.widget(this->ctrl_parent()); | ||||
| 		// If widget doesn't have label, don't use border
 | ||||
| 		grid_sizer->Add(wgt, 0, wxEXPAND | wxBOTTOM | wxTOP, (wxOSX || line.label.IsEmpty()) ? 0 : 5); | ||||
| 		return; | ||||
|  | @ -237,7 +240,8 @@ void OptionsGroup::append_line(const Line& line, wxStaticText**	full_Label/* = n | |||
| 			wxString str_label = (option.label == "Top" || option.label == "Bottom") ? | ||||
| 								_CTX(option.label, "Layers") : | ||||
| 								_(option.label); | ||||
| 			label = new wxStaticText(parent(), wxID_ANY, str_label + ": ", wxDefaultPosition, wxDefaultSize); | ||||
| 			label = new wxStaticText(this->ctrl_parent(), wxID_ANY, str_label + ": ", wxDefaultPosition, wxDefaultSize); | ||||
| 			label->SetBackgroundStyle(wxBG_STYLE_PAINT); | ||||
| 			label->SetFont(label_font); | ||||
| 			sizer_tmp->Add(label, 0, /*wxALIGN_RIGHT |*/ wxALIGN_CENTER_VERTICAL, 0); | ||||
| 		} | ||||
|  | @ -262,8 +266,9 @@ void OptionsGroup::append_line(const Line& line, wxStaticText**	full_Label/* = n | |||
| 		 | ||||
| 		// add sidetext if any
 | ||||
| 		if (option.sidetext != "") { | ||||
| 			auto sidetext = new wxStaticText(	parent(), wxID_ANY, _(option.sidetext), wxDefaultPosition,  | ||||
| 			auto sidetext = new wxStaticText(	this->ctrl_parent(), wxID_ANY, _(option.sidetext), wxDefaultPosition,  | ||||
| 												wxSize(sidetext_width, -1)/*wxDefaultSize*/, wxALIGN_LEFT); | ||||
| 			sidetext->SetBackgroundStyle(wxBG_STYLE_PAINT); | ||||
| 			sidetext->SetFont(sidetext_font); | ||||
| 			sizer_tmp->Add(sidetext, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4); | ||||
| 			field->set_side_text_ptr(sidetext); | ||||
|  | @ -271,7 +276,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText**	full_Label/* = n | |||
| 
 | ||||
| 		// add side widget if any
 | ||||
| 		if (opt.side_widget != nullptr) { | ||||
| 			sizer_tmp->Add(opt.side_widget(parent())/*!.target<wxWindow>()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 1);	//! requires verification
 | ||||
| 			sizer_tmp->Add(opt.side_widget(this->ctrl_parent())/*!.target<wxWindow>()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 1);	//! requires verification
 | ||||
| 		} | ||||
| 
 | ||||
| 		if (opt.opt_id != option_set.back().opt_id) //! istead of (opt != option_set.back())
 | ||||
|  | @ -287,11 +292,11 @@ void OptionsGroup::append_line(const Line& line, wxStaticText**	full_Label/* = n | |||
|             // extra widget for non-staticbox option group (like for the frequently used parameters on the sidebar) should be wxALIGN_RIGHT
 | ||||
|             const auto v_sizer = new wxBoxSizer(wxVERTICAL); | ||||
|             sizer->Add(v_sizer, 1, wxEXPAND); | ||||
|             v_sizer->Add(extra_widget(parent()), 0, wxALIGN_RIGHT); | ||||
|             v_sizer->Add(extra_widget(this->ctrl_parent()), 0, wxALIGN_RIGHT); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
| 		sizer->Add(extra_widget(parent())/*!.target<wxWindow>()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4);		//! requires verification
 | ||||
| 		sizer->Add(extra_widget(this->ctrl_parent())/*!.target<wxWindow>()*/, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, 4);		//! requires verification
 | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -438,7 +443,7 @@ void ConfigOptionsGroup::Hide() | |||
| void ConfigOptionsGroup::Show(const bool show) | ||||
| { | ||||
|     sizer->ShowItems(show); | ||||
| #ifdef __WXGTK__ | ||||
| #if 0//#ifdef __WXGTK__
 | ||||
|     m_panel->Show(show); | ||||
|     m_grid_sizer->Show(show); | ||||
| #endif /* __WXGTK__ */ | ||||
|  |  | |||
|  | @ -100,18 +100,22 @@ public: | |||
|     /// Accessor function is because users are not allowed to change the parent
 | ||||
|     /// but defining it as const means a lot of const_casts to deal with wx functions.
 | ||||
|     inline wxWindow* parent() const {  | ||||
| #ifdef __WXGTK__ | ||||
| #if 0//#ifdef __WXGTK__
 | ||||
| 		return m_panel; | ||||
| #else | ||||
| 		return m_parent; | ||||
| #endif /* __WXGTK__ */ | ||||
|     } | ||||
| #ifdef __WXGTK__ | ||||
| #if 0//#ifdef __WXGTK__
 | ||||
|     wxWindow* get_parent() const { | ||||
|         return m_parent; | ||||
|     } | ||||
| #endif /* __WXGTK__ */ | ||||
| 
 | ||||
|     wxWindow* ctrl_parent() const { | ||||
|     	return this->stb ? (wxWindow*)this->stb : this->parent(); | ||||
|     } | ||||
| 
 | ||||
| 	void		append_line(const Line& line, wxStaticText** full_Label = nullptr); | ||||
|     Line		create_single_option_line(const Option& option) const; | ||||
|     void		append_single_option_line(const Option& option) { append_line(create_single_option_line(option)); } | ||||
|  | @ -161,8 +165,10 @@ public: | |||
| 					staticbox(title!=""), extra_column(extra_clmn) { | ||||
|         if (staticbox) { | ||||
|             stb = new wxStaticBox(_parent, wxID_ANY, title); | ||||
|             stb->SetBackgroundStyle(wxBG_STYLE_PAINT); | ||||
|             stb->SetFont(wxGetApp().bold_font()); | ||||
|         } | ||||
|         } else | ||||
|         	stb = nullptr; | ||||
|         sizer = (staticbox ? new wxStaticBoxSizer(stb, wxVERTICAL) : new wxBoxSizer(wxVERTICAL)); | ||||
|         auto num_columns = 1U; | ||||
|         if (label_width != 0) num_columns++; | ||||
|  | @ -170,7 +176,7 @@ public: | |||
|         m_grid_sizer = new wxFlexGridSizer(0, num_columns, 1,0); | ||||
|         static_cast<wxFlexGridSizer*>(m_grid_sizer)->SetFlexibleDirection(wxBOTH/*wxHORIZONTAL*/); | ||||
|         static_cast<wxFlexGridSizer*>(m_grid_sizer)->AddGrowableCol(label_width == 0 ? 0 : !extra_column ? 1 : 2 ); | ||||
| #ifdef __WXGTK__ | ||||
| #if 0//#ifdef __WXGTK__
 | ||||
|         m_panel = new wxPanel( _parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); | ||||
|         sizer->Fit(m_panel); | ||||
|         sizer->Add(m_panel, 0, wxEXPAND | wxALL, wxOSX||!staticbox ? 0: 5); | ||||
|  | @ -198,7 +204,7 @@ protected: | |||
| 	// This panel is needed for correct showing of the ToolTips for Button, StaticText and CheckBox
 | ||||
| 	// Tooltips on GTK doesn't work inside wxStaticBoxSizer unless you insert a panel 
 | ||||
| 	// inside it before you insert the other controls.
 | ||||
| #ifdef __WXGTK__ | ||||
| #if 0//#ifdef__WXGTK__
 | ||||
| 	wxPanel*				m_panel {nullptr}; | ||||
| #endif /* __WXGTK__ */ | ||||
| 
 | ||||
|  |  | |||
|  | @ -276,9 +276,45 @@ wxBitmapComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(15 * | |||
|             dialog->Destroy(); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     edit_btn = new wxButton(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER); | ||||
| #ifdef __WINDOWS__ | ||||
|     edit_btn->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); | ||||
| #endif | ||||
|     edit_btn->SetBitmap(create_scaled_bitmap("cog.png")); | ||||
|     edit_btn->SetToolTip(_(L("Click to edit preset"))); | ||||
| 
 | ||||
|     edit_btn->Bind(wxEVT_BUTTON, ([preset_type, this](wxCommandEvent) | ||||
|     { | ||||
|         Tab* tab = wxGetApp().get_tab(preset_type); | ||||
|         if (!tab) | ||||
|             return; | ||||
| 
 | ||||
|         int page_id = wxGetApp().tab_panel()->FindPage(tab); | ||||
|         if (page_id == wxNOT_FOUND) | ||||
|             return; | ||||
| 
 | ||||
|         wxGetApp().tab_panel()->ChangeSelection(page_id); | ||||
| 
 | ||||
|         /* In a case of a multi-material printing, for editing another Filament Preset 
 | ||||
|          * it's needed to select this preset for the "Filament settings" Tab  | ||||
|          */ | ||||
|         if (preset_type == Preset::TYPE_FILAMENT && wxGetApp().extruders_cnt() > 1)  | ||||
|         { | ||||
|             const std::string& selected_preset = GetString(GetSelection()).ToUTF8().data(); | ||||
| 
 | ||||
|             // Call select_preset() only if there is new preset and not just modified 
 | ||||
|             if ( !boost::algorithm::ends_with(selected_preset, Preset::suffix_modified()) ) | ||||
|                 tab->select_preset(selected_preset); | ||||
|         } | ||||
|     })); | ||||
| } | ||||
| 
 | ||||
| PresetComboBox::~PresetComboBox() {} | ||||
| PresetComboBox::~PresetComboBox() | ||||
| { | ||||
|     if (edit_btn) | ||||
|         edit_btn->Destroy(); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void PresetComboBox::set_label_marker(int item) | ||||
|  | @ -612,13 +648,18 @@ Sidebar::Sidebar(Plater *parent) | |||
|         text->SetFont(wxGetApp().small_font()); | ||||
|         *combo = new PresetComboBox(p->presets_panel, preset_type); | ||||
| 
 | ||||
|         auto combo_and_btn_sizer = new wxBoxSizer(wxHORIZONTAL); | ||||
|         combo_and_btn_sizer->Add(*combo, 1, wxEXPAND); | ||||
|         if ((*combo)->edit_btn) | ||||
|             combo_and_btn_sizer->Add((*combo)->edit_btn, 0, wxLEFT|wxRIGHT, int(0.3*wxGetApp().em_unit())); | ||||
| 
 | ||||
|         auto *sizer_presets = this->p->sizer_presets; | ||||
|         auto *sizer_filaments = this->p->sizer_filaments; | ||||
|         sizer_presets->Add(text, 0, wxALIGN_LEFT | wxEXPAND | wxRIGHT, 4); | ||||
|         if (! filament) { | ||||
|             sizer_presets->Add(*combo, 0, wxEXPAND | wxBOTTOM, 1); | ||||
|             sizer_presets->Add(combo_and_btn_sizer, 0, wxEXPAND | wxBOTTOM, 1); | ||||
|         } else { | ||||
|             sizer_filaments->Add(*combo, 0, wxEXPAND | wxBOTTOM, 1); | ||||
|             sizer_filaments->Add(combo_and_btn_sizer, 0, wxEXPAND | wxBOTTOM, 1); | ||||
|             (*combo)->set_extruder_idx(0); | ||||
|             sizer_presets->Add(sizer_filaments, 1, wxEXPAND); | ||||
|         } | ||||
|  | @ -715,8 +756,12 @@ void Sidebar::init_filament_combo(PresetComboBox **combo, const int extr_idx) { | |||
| 
 | ||||
|     (*combo)->set_extruder_idx(extr_idx); | ||||
| 
 | ||||
|     auto combo_and_btn_sizer = new wxBoxSizer(wxHORIZONTAL); | ||||
|     combo_and_btn_sizer->Add(*combo, 1, wxEXPAND); | ||||
|     combo_and_btn_sizer->Add((*combo)->edit_btn, 0, wxLEFT | wxRIGHT, int(0.3*wxGetApp().em_unit())); | ||||
| 
 | ||||
|     auto /***/sizer_filaments = this->p->sizer_filaments; | ||||
|     sizer_filaments->Add(*combo, 1, wxEXPAND | wxBOTTOM, 1); | ||||
|     sizer_filaments->Add(combo_and_btn_sizer, 1, wxEXPAND | wxBOTTOM, 1); | ||||
| } | ||||
| 
 | ||||
| void Sidebar::remove_unused_filament_combos(const int current_extruder_count) | ||||
|  |  | |||
|  | @ -46,6 +46,8 @@ public: | |||
|     PresetComboBox(wxWindow *parent, Preset::Type preset_type); | ||||
|     ~PresetComboBox(); | ||||
| 
 | ||||
|     wxButton* edit_btn { nullptr }; | ||||
| 
 | ||||
|     void set_label_marker(int item); | ||||
|     void set_extruder_idx(const int extr_idx)   { extruder_idx = extr_idx; } | ||||
|     int  get_extruder_idx() const               { return extruder_idx; } | ||||
|  |  | |||
|  | @ -201,6 +201,7 @@ public: | |||
|     static const std::vector<std::string>&  sla_print_options(); | ||||
| 
 | ||||
| 	static void                             update_suffix_modified(); | ||||
|     static const std::string&               suffix_modified(); | ||||
|     static void                             normalize(DynamicPrintConfig &config); | ||||
|     // Report configuration fields, which are misplaced into a wrong group, remove them from the config.
 | ||||
|     static std::string                      remove_invalid_keys(DynamicPrintConfig &config, const DynamicPrintConfig &default_config); | ||||
|  | @ -210,7 +211,6 @@ protected: | |||
|     friend class        PresetBundle; | ||||
|     // Resize the extruder specific vectors ()
 | ||||
|     static void         set_num_extruders(DynamicPrintConfig &config, unsigned int n); | ||||
|     static const std::string& suffix_modified(); | ||||
|     static std::string  remove_suffix_modified(const std::string &name); | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1308,19 +1308,23 @@ void PresetBundle::update_compatible(bool select_other_if_incompatible) | |||
|                     { return std::find(prefered_filament_profiles.begin(), prefered_filament_profiles.end(), profile_name) != prefered_filament_profiles.end(); }); | ||||
|         if (select_other_if_incompatible) { | ||||
|             // Verify validity of the current filament presets.
 | ||||
|             this->filament_presets.front() = this->filaments.get_edited_preset().name; | ||||
|             for (size_t idx = 1; idx < this->filament_presets.size(); ++ idx) { | ||||
|                 std::string &filament_name = this->filament_presets[idx]; | ||||
|                 Preset      *preset        = this->filaments.find_preset(filament_name, false); | ||||
|                 if (preset == nullptr || ! preset->is_compatible) { | ||||
|                     // Pick a compatible profile. If there are prefered_filament_profiles, use them.
 | ||||
|                     if (prefered_filament_profiles.empty()) | ||||
|                         filament_name = this->filaments.first_compatible().name; | ||||
|                     else { | ||||
|                         const std::string &preferred = (idx < prefered_filament_profiles.size()) ?  | ||||
|                             prefered_filament_profiles[idx] : prefered_filament_profiles.front(); | ||||
|                         filament_name = this->filaments.first_compatible( | ||||
|                             [&preferred](const std::string& profile_name) { return profile_name == preferred; }).name; | ||||
|             if (this->filament_presets.size() == 1) | ||||
|                 this->filament_presets.front() = this->filaments.get_edited_preset().name; | ||||
|             else | ||||
|             { | ||||
|                 for (size_t idx = 0; idx < this->filament_presets.size(); ++idx) { | ||||
|                     std::string &filament_name = this->filament_presets[idx]; | ||||
|                     Preset      *preset = this->filaments.find_preset(filament_name, false); | ||||
|                     if (preset == nullptr || !preset->is_compatible) { | ||||
|                         // Pick a compatible profile. If there are prefered_filament_profiles, use them.
 | ||||
|                         if (prefered_filament_profiles.empty()) | ||||
|                             filament_name = this->filaments.first_compatible().name; | ||||
|                         else { | ||||
|                             const std::string &preferred = (idx < prefered_filament_profiles.size()) ? | ||||
|                                 prefered_filament_profiles[idx] : prefered_filament_profiles.front(); | ||||
|                             filament_name = this->filaments.first_compatible( | ||||
|                                 [&preferred](const std::string& profile_name) { return profile_name == preferred; }).name; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  |  | |||
|  | @ -58,6 +58,13 @@ Tab::Tab(wxNotebook* parent, const wxString& title, const char* name) : | |||
| 	wxGetApp().tabs_list.push_back(this); | ||||
| 
 | ||||
|     m_em_unit = wxGetApp().em_unit(); | ||||
| 
 | ||||
| 	Bind(wxEVT_SIZE, ([this](wxSizeEvent &evt) { | ||||
| 		for (auto page : m_pages) | ||||
| 			if (! page.get()->IsShown()) | ||||
| 				page->layout_valid = false; | ||||
| 		evt.Skip(); | ||||
| 	})); | ||||
| } | ||||
| 
 | ||||
| void Tab::set_type() | ||||
|  | @ -74,7 +81,7 @@ void Tab::set_type() | |||
| void Tab::create_preset_tab() | ||||
| { | ||||
| #ifdef __WINDOWS__ | ||||
| //     SetDoubleBuffered(true);
 | ||||
|     SetDoubleBuffered(true); | ||||
| #endif //__WINDOWS__
 | ||||
| 
 | ||||
|     m_preset_bundle = wxGetApp().preset_bundle; | ||||
|  | @ -261,6 +268,7 @@ void Tab::create_preset_tab() | |||
| 	// Initialize the DynamicPrintConfig by default keys/values.
 | ||||
| 	build(); | ||||
| 	rebuild_page_tree(); | ||||
|     m_complited = true; | ||||
| } | ||||
| 
 | ||||
| void Tab::load_initial_data() | ||||
|  | @ -293,6 +301,11 @@ Slic3r::GUI::PageShp Tab::add_options_page(const wxString& title, const std::str | |||
| 	auto panel = this; | ||||
| #endif | ||||
| 	PageShp page(new Page(panel, title, icon_idx)); | ||||
| //	page->SetBackgroundStyle(wxBG_STYLE_SYSTEM);
 | ||||
| #ifdef __WINDOWS__ | ||||
| //	page->SetDoubleBuffered(true);
 | ||||
| #endif //__WINDOWS__
 | ||||
| 
 | ||||
| 	page->SetScrollbars(1, 20, 1, 2); | ||||
| 	page->Hide(); | ||||
| 	m_hsizer->Add(page.get(), 1, wxEXPAND | wxLEFT, 5); | ||||
|  | @ -318,7 +331,7 @@ void Tab::OnActivate() | |||
| 
 | ||||
| void Tab::update_labels_colour() | ||||
| { | ||||
| 	Freeze(); | ||||
| //	Freeze();
 | ||||
| 	//update options "decoration"
 | ||||
| 	for (const auto opt : m_options_list) | ||||
| 	{ | ||||
|  | @ -345,7 +358,7 @@ void Tab::update_labels_colour() | |||
| 		if (field == nullptr) continue; | ||||
| 		field->set_label_colour_force(color); | ||||
| 	} | ||||
| 	Thaw(); | ||||
| //	Thaw();
 | ||||
| 
 | ||||
| 	auto cur_item = m_treectrl->GetFirstVisibleItem(); | ||||
| 	while (cur_item) { | ||||
|  | @ -389,7 +402,7 @@ void Tab::update_changed_ui() | |||
| 	for (auto opt_key : dirty_options)	m_options_list[opt_key] &= ~osInitValue; | ||||
| 	for (auto opt_key : nonsys_options)	m_options_list[opt_key] &= ~osSystemValue; | ||||
| 
 | ||||
| 	Freeze(); | ||||
| //	Freeze();
 | ||||
| 	//update options "decoration"
 | ||||
| 	for (const auto opt : m_options_list) | ||||
| 	{ | ||||
|  | @ -439,7 +452,7 @@ void Tab::update_changed_ui() | |||
| 		field->set_undo_to_sys_tooltip(sys_tt); | ||||
| 		field->set_label_colour(color); | ||||
| 	} | ||||
| 	Thaw(); | ||||
| //	Thaw();
 | ||||
| 
 | ||||
| 	wxTheApp->CallAfter([this]() { | ||||
| 		update_changed_tree_ui(); | ||||
|  | @ -686,31 +699,34 @@ void Tab::load_config(const DynamicPrintConfig& config) | |||
| // Reload current $self->{config} (aka $self->{presets}->edited_preset->config) into the UI fields.
 | ||||
| void Tab::reload_config() | ||||
| { | ||||
| 	Freeze(); | ||||
| //	Freeze();
 | ||||
| 	for (auto page : m_pages) | ||||
| 		page->reload_config(); | ||||
|  	Thaw(); | ||||
| // 	Thaw();
 | ||||
| } | ||||
| 
 | ||||
| void Tab::update_mode() | ||||
| { | ||||
|     m_mode = wxGetApp().get_mode(); | ||||
| 
 | ||||
|     // update mode for ModeSizer
 | ||||
|     m_mode_sizer->SetMode(m_mode); | ||||
| 
 | ||||
|     update_visibility(); | ||||
| } | ||||
| 
 | ||||
| void Tab::update_visibility() | ||||
| { | ||||
|     const ConfigOptionMode mode = wxGetApp().get_mode(); | ||||
|     Freeze(); | ||||
|     Freeze(); // There is needed Freeze/Thaw to avoid a flashing after Show/Layout
 | ||||
| 
 | ||||
| 	for (auto page : m_pages) | ||||
|         page->update_visibility(mode); | ||||
|         page->update_visibility(m_mode); | ||||
|     update_page_tree_visibility(); | ||||
| 
 | ||||
|     // update mode for ModeSizer
 | ||||
|     m_mode_sizer->SetMode(mode); | ||||
| 
 | ||||
|     Layout(); | ||||
| 	Thaw(); | ||||
| 
 | ||||
|     // to update tree items color
 | ||||
| //    wxTheApp->CallAfter([this]() {
 | ||||
|         update_changed_tree_ui(); | ||||
| //     });
 | ||||
|     update_changed_tree_ui(); | ||||
| } | ||||
| 
 | ||||
| Field* Tab::get_field(const t_config_option_key& opt_key, int opt_index/* = -1*/) const | ||||
|  | @ -1180,7 +1196,7 @@ void TabPrint::update() | |||
| //         return;                      // ! TODO Let delete this part of code after a common aplication testing
 | ||||
| 
 | ||||
|     m_update_cnt++; | ||||
| 	Freeze(); | ||||
| //	Freeze();
 | ||||
| 
 | ||||
| 	double fill_density = m_config->option<ConfigOptionPercent>("fill_density")->value; | ||||
| 
 | ||||
|  | @ -1391,7 +1407,7 @@ void TabPrint::update() | |||
| 	m_recommended_thin_wall_thickness_description_line->SetText( | ||||
| 		from_u8(PresetHints::recommended_thin_wall_thickness(*m_preset_bundle))); | ||||
| 
 | ||||
| 	Thaw(); | ||||
| //	Thaw();
 | ||||
|     m_update_cnt--; | ||||
| 
 | ||||
|     if (m_update_cnt==0) | ||||
|  | @ -1486,6 +1502,7 @@ void TabFilament::build() | |||
|         line = optgroup->create_single_option_line("filament_ramming_parameters");// { _(L("Ramming")), "" };
 | ||||
|         line.widget = [this](wxWindow* parent) { | ||||
| 			auto ramming_dialog_btn = new wxButton(parent, wxID_ANY, _(L("Ramming settings"))+dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); | ||||
| 			ramming_dialog_btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); | ||||
|             auto sizer = new wxBoxSizer(wxHORIZONTAL); | ||||
| 			sizer->Add(ramming_dialog_btn); | ||||
|              | ||||
|  | @ -1566,7 +1583,7 @@ void TabFilament::update() | |||
|         return; // ys_FIXME
 | ||||
| 
 | ||||
|     m_update_cnt++; | ||||
| 	Freeze(); | ||||
| //	Freeze();
 | ||||
| 	wxString text = from_u8(PresetHints::cooling_description(m_presets->get_edited_preset())); | ||||
| 	m_cooling_description_line->SetText(text); | ||||
| 	text = from_u8(PresetHints::maximum_volumetric_flow_description(*m_preset_bundle)); | ||||
|  | @ -1580,7 +1597,7 @@ void TabFilament::update() | |||
| 
 | ||||
| 	for (auto el : { "min_fan_speed", "disable_fan_first_layers" }) | ||||
| 		get_field(el)->toggle(fan_always_on); | ||||
|     Thaw(); | ||||
| //    Thaw();
 | ||||
|     m_update_cnt--; | ||||
| 
 | ||||
|     if (m_update_cnt == 0) | ||||
|  | @ -1621,6 +1638,7 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) | |||
| 
 | ||||
| 	auto printhost_browse = [=](wxWindow* parent) { | ||||
| 		auto btn = m_printhost_browse_btn = new wxButton(parent, wxID_ANY, _(L(" Browse "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT); | ||||
| 		btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); | ||||
|         btn->SetBitmap(create_scaled_bitmap("zoom.png")); | ||||
| 		auto sizer = new wxBoxSizer(wxHORIZONTAL); | ||||
| 		sizer->Add(btn); | ||||
|  | @ -1639,6 +1657,7 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) | |||
| 	auto print_host_test = [this](wxWindow* parent) { | ||||
| 		auto btn = m_print_host_test_btn = new wxButton(parent, wxID_ANY, _(L("Test")),  | ||||
| 			wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); | ||||
| 		btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); | ||||
|         btn->SetBitmap(create_scaled_bitmap("wrench.png")); | ||||
| 		auto sizer = new wxBoxSizer(wxHORIZONTAL); | ||||
| 		sizer->Add(btn); | ||||
|  | @ -1676,6 +1695,7 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) | |||
| 		auto printhost_cafile_browse = [this, optgroup] (wxWindow* parent) { | ||||
| 			auto btn = new wxButton(parent, wxID_ANY, _(L(" Browse "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT); | ||||
| // 			btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("zoom.png")), wxBITMAP_TYPE_PNG));
 | ||||
| 			btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); | ||||
| 			btn->SetBitmap(create_scaled_bitmap("zoom.png")); | ||||
| 			auto sizer = new wxBoxSizer(wxHORIZONTAL); | ||||
| 			sizer->Add(btn); | ||||
|  | @ -1714,6 +1734,7 @@ void TabPrinter::build_printhost(ConfigOptionsGroup *optgroup) | |||
| \tOn this system, Slic3r uses HTTPS certificates from the system Certificate Store or Keychain.\n\ | ||||
| \tTo use a custom CA file, please import your CA file into Certificate Store / Keychain.")), | ||||
| 				ca_file_hint)); | ||||
| 			txt->SetFont(Slic3r::GUI::wxGetApp().normal_font()); | ||||
| 			auto sizer = new wxBoxSizer(wxHORIZONTAL); | ||||
| 			sizer->Add(txt); | ||||
| 			return sizer; | ||||
|  | @ -1954,7 +1975,7 @@ void TabPrinter::build_sla() | |||
|     Line line = optgroup->create_single_option_line("bed_shape");//{ _(L("Bed shape")), "" };
 | ||||
|     line.widget = [this](wxWindow* parent) { | ||||
|         auto btn = new wxButton(parent, wxID_ANY, _(L(" Set ")) + dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); | ||||
|         //			btn->SetFont(Slic3r::GUI::small_font);
 | ||||
|         btn->SetFont(wxGetApp().small_font()); | ||||
| //         btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("printer_empty.png")), wxBITMAP_TYPE_PNG));
 | ||||
|         btn->SetBitmap(create_scaled_bitmap("printer_empty.png")); | ||||
| 
 | ||||
|  | @ -2246,7 +2267,7 @@ void TabPrinter::update_pages() | |||
|     else  | ||||
|         m_pages_sla.empty() ? build_sla() : m_pages.swap(m_pages_sla); | ||||
| 
 | ||||
|     rebuild_page_tree(true); | ||||
|     rebuild_page_tree(); | ||||
| } | ||||
| 
 | ||||
| void TabPrinter::update() | ||||
|  | @ -2261,7 +2282,7 @@ void TabPrinter::update() | |||
| 
 | ||||
| void TabPrinter::update_fff() | ||||
| { | ||||
| 	Freeze(); | ||||
| //	Freeze();
 | ||||
| 
 | ||||
| 	bool en; | ||||
| 	auto serial_speed = get_field("serial_speed"); | ||||
|  | @ -2360,7 +2381,7 @@ void TabPrinter::update_fff() | |||
| 			(have_multiple_extruders && toolchange_retraction); | ||||
| 	} | ||||
| 
 | ||||
| 	Thaw(); | ||||
| //	Thaw();
 | ||||
| } | ||||
| 
 | ||||
| void TabPrinter::update_sla() | ||||
|  | @ -2452,10 +2473,8 @@ void Tab::load_current_preset() | |||
| } | ||||
| 
 | ||||
| //Regerenerate content of the page tree.
 | ||||
| void Tab::rebuild_page_tree(bool tree_sel_change_event /*= false*/) | ||||
| void Tab::rebuild_page_tree() | ||||
| { | ||||
| // 	Freeze();
 | ||||
| 
 | ||||
| 	// get label of the currently selected item
 | ||||
|     const auto sel_item = m_treectrl->GetSelection(); | ||||
| 	const auto selected = sel_item ? m_treectrl->GetItemText(sel_item) : ""; | ||||
|  | @ -2468,10 +2487,7 @@ void Tab::rebuild_page_tree(bool tree_sel_change_event /*= false*/) | |||
| 		auto itemId = m_treectrl->AppendItem(rootItem, p->title(), p->iconID()); | ||||
| 		m_treectrl->SetItemTextColour(itemId, p->get_item_colour()); | ||||
| 		if (p->title() == selected) { | ||||
| // 			if (!(p->title() == _(L("Machine limits")) || p->title() == _(L("Single extruder MM setup")))) // These Pages have to be updated inside OnTreeSelChange
 | ||||
| // 				m_disable_tree_sel_changed_event = !tree_sel_change_event;
 | ||||
| 			m_treectrl->SelectItem(itemId); | ||||
| 			m_disable_tree_sel_changed_event = false; | ||||
| 			have_selection = 1; | ||||
| 		} | ||||
| 	} | ||||
|  | @ -2696,7 +2712,7 @@ void Tab::OnTreeSelChange(wxTreeEvent& event) | |||
| #ifdef __linux__	 | ||||
| 	std::unique_ptr<wxWindowUpdateLocker> no_updates(new wxWindowUpdateLocker(this)); | ||||
| #else | ||||
| 	wxWindowUpdateLocker noUpdates(this); | ||||
| //	wxWindowUpdateLocker noUpdates(this);
 | ||||
| #endif | ||||
| 
 | ||||
|     if (m_pages.empty()) | ||||
|  | @ -2716,17 +2732,22 @@ void Tab::OnTreeSelChange(wxTreeEvent& event) | |||
| 	if (page == nullptr) return; | ||||
| 
 | ||||
| 	for (auto& el : m_pages) | ||||
| 		el.get()->Hide(); | ||||
| //		if (el.get()->IsShown()) {
 | ||||
| 			el.get()->Hide(); | ||||
| //			break;
 | ||||
| //		}
 | ||||
| 
 | ||||
| #ifdef __linux__ | ||||
|     no_updates.reset(nullptr); | ||||
| #endif | ||||
| 
 | ||||
| 	page->Show(); | ||||
| 	m_hsizer->Layout(); | ||||
| 	Refresh(); | ||||
| 	#ifdef __linux__ | ||||
| 	    no_updates.reset(nullptr); | ||||
| 	#endif | ||||
| 
 | ||||
| 	update_undo_buttons(); | ||||
| 	page->Show(); | ||||
| //	if (! page->layout_valid) {
 | ||||
| 		page->layout_valid = true; | ||||
| 		m_hsizer->Layout(); | ||||
| 		Refresh(); | ||||
| //	}
 | ||||
| } | ||||
| 
 | ||||
| void Tab::OnKeyDown(wxKeyEvent& event) | ||||
|  | @ -2866,7 +2887,9 @@ void Tab::update_ui_from_settings() | |||
| wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &deps) | ||||
| { | ||||
| 	deps.checkbox = new wxCheckBox(parent, wxID_ANY, _(L("All"))); | ||||
| 	deps.checkbox->SetFont(Slic3r::GUI::wxGetApp().normal_font()); | ||||
| 	deps.btn = new wxButton(parent, wxID_ANY, _(L(" Set "))+dots, wxDefaultPosition, wxDefaultSize, wxBU_LEFT | wxBU_EXACTFIT); | ||||
| 	deps.btn->SetFont(Slic3r::GUI::wxGetApp().normal_font()); | ||||
| 
 | ||||
| // 	deps.btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("printer_empty.png")), wxBITMAP_TYPE_PNG));
 | ||||
|     deps.btn->SetBitmap(create_scaled_bitmap("printer_empty.png")); | ||||
|  | @ -3062,6 +3085,7 @@ ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_la | |||
|         }                                | ||||
| //         auto bmp = new wxStaticBitmap(parent, wxID_ANY, bmp_name.empty() ? wxNullBitmap : wxBitmap(from_u8(var(bmp_name)), wxBITMAP_TYPE_PNG));
 | ||||
|         auto bmp = new wxStaticBitmap(parent, wxID_ANY, bmp_name.empty() ? wxNullBitmap : create_scaled_bitmap(bmp_name)); | ||||
|         bmp->SetBackgroundStyle(wxBG_STYLE_PAINT); | ||||
|         return bmp; | ||||
|     }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -65,6 +65,9 @@ public: | |||
| 	bool				m_is_modified_values{ false }; | ||||
| 	bool				m_is_nonsys_values{ true }; | ||||
| 
 | ||||
|     // Delayed layout after resizing the main window.
 | ||||
|     bool 				layout_valid = false; | ||||
| 
 | ||||
| public: | ||||
| 	std::vector <ConfigOptionsGroupShp> m_optgroups; | ||||
| 	DynamicPrintConfig* m_config; | ||||
|  | @ -204,6 +207,9 @@ protected: | |||
|     void                set_type(); | ||||
| 
 | ||||
|     int                 m_em_unit; | ||||
|     // To avoid actions with no-completed Tab
 | ||||
|     bool                m_complited { false }; | ||||
|     ConfigOptionMode    m_mode = comSimple; | ||||
| 
 | ||||
| public: | ||||
| 	PresetBundle*		m_preset_bundle; | ||||
|  | @ -226,11 +232,12 @@ public: | |||
| 	wxString	title()	 const { return m_title; } | ||||
| 	std::string	name()	 const { return m_name; } | ||||
|     Preset::Type type()  const { return m_type; } | ||||
|     bool complited()     const { return m_complited; } | ||||
|     virtual bool supports_printer_technology(const PrinterTechnology tech) = 0; | ||||
| 
 | ||||
| 	void		create_preset_tab(); | ||||
| 	void		load_current_preset(); | ||||
| 	void        rebuild_page_tree(bool tree_sel_change_event = false); | ||||
| 	void        rebuild_page_tree(); | ||||
| 	void        update_page_tree_visibility(); | ||||
| 	void		select_preset(std::string preset_name = ""); | ||||
| 	bool		may_discard_current_dirty_preset(PresetCollection* presets = nullptr, const std::string& new_printer_name = ""); | ||||
|  | @ -264,6 +271,7 @@ public: | |||
| 	void			update_tab_ui(); | ||||
| 	void			load_config(const DynamicPrintConfig& config); | ||||
| 	virtual void	reload_config(); | ||||
|     void            update_mode(); | ||||
|     void            update_visibility(); | ||||
| 	Field*			get_field(const t_config_option_key& opt_key, int opt_index = -1) const; | ||||
| 	bool			set_value(const t_config_option_key& opt_key, const boost::any& value); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 tamasmeszaros
						tamasmeszaros