mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	Merge branch 'master' of https://github.com/Prusa3d/Slic3r
This commit is contained in:
		
						commit
						4a1f0eb05f
					
				
					 13 changed files with 287 additions and 140 deletions
				
			
		|  | @ -66,12 +66,8 @@ void Field::PostInitialize() | |||
| 	BUILD(); | ||||
| } | ||||
| 
 | ||||
| void Field::on_kill_focus(wxEvent& event) | ||||
| void Field::on_kill_focus() | ||||
| { | ||||
|     // Without this, there will be nasty focus bugs on Windows.
 | ||||
|     // Also, docs for wxEvent::Skip() say "In general, it is recommended to skip all 
 | ||||
|     // non-command events to allow the default handling to take place."
 | ||||
| 	event.Skip(); | ||||
| 	// call the registered function if it is available
 | ||||
|     if (m_on_kill_focus!=nullptr)  | ||||
|         m_on_kill_focus(m_opt_id); | ||||
|  | @ -250,11 +246,23 @@ void TextCtrl::BUILD() { | |||
| 		break;  | ||||
| 	} | ||||
| 
 | ||||
|     const long style = m_opt.multiline ? wxTE_MULTILINE : 0; | ||||
|     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->SetToolTip(get_tooltip_text(text_value)); | ||||
| 
 | ||||
|     if (style == wxTE_PROCESS_ENTER) { | ||||
|         temp->Bind(wxEVT_TEXT_ENTER, ([this, temp](wxEvent& e) | ||||
|         { | ||||
| #if !defined(__WXGTK__) | ||||
|             e.Skip(); | ||||
|             temp->GetToolTip()->Enable(true); | ||||
| #endif // __WXGTK__
 | ||||
|             propagate_value(); | ||||
|             bEnterPressed = true; | ||||
|         }), temp->GetId()); | ||||
|     } | ||||
| 
 | ||||
|     temp->Bind(wxEVT_SET_FOCUS, ([this](wxEvent& e) { on_set_focus(e); }), temp->GetId()); | ||||
|      | ||||
| 	temp->Bind(wxEVT_LEFT_DOWN, ([temp](wxEvent& event) | ||||
|  | @ -272,14 +280,15 @@ void TextCtrl::BUILD() { | |||
| 
 | ||||
| 	temp->Bind(wxEVT_KILL_FOCUS, ([this, temp](wxEvent& e) | ||||
| 	{ | ||||
| #if !defined(__WXGTK__) | ||||
| 		e.Skip(); | ||||
| #if !defined(__WXGTK__) | ||||
| 		temp->GetToolTip()->Enable(true); | ||||
| #endif // __WXGTK__
 | ||||
|         if (is_defined_input_value<wxTextCtrl>(window, m_opt.type)) | ||||
|             on_change_field(); | ||||
|         else | ||||
|             on_kill_focus(e); | ||||
|         if (bEnterPressed) { | ||||
|             bEnterPressed = false; | ||||
|             return; | ||||
|         } | ||||
|         propagate_value(); | ||||
| 	}), temp->GetId()); | ||||
|     /*
 | ||||
|         temp->Bind(wxEVT_TEXT, ([this](wxCommandEvent& evt) | ||||
|  | @ -311,6 +320,14 @@ void TextCtrl::BUILD() { | |||
|     window = dynamic_cast<wxWindow*>(temp); | ||||
| }	 | ||||
| 
 | ||||
| void TextCtrl::propagate_value() | ||||
| { | ||||
|     if (is_defined_input_value<wxTextCtrl>(window, m_opt.type)) | ||||
|         on_change_field(); | ||||
|     else | ||||
|         on_kill_focus(); | ||||
| } | ||||
| 
 | ||||
| boost::any& TextCtrl::get_value() | ||||
| { | ||||
| 	wxString ret_str = static_cast<wxTextCtrl*>(window)->GetValue(); | ||||
|  | @ -398,7 +415,7 @@ void SpinCtrl::BUILD() { | |||
| 	const int max_val = m_opt.max < 2147483647 ? m_opt.max : 2147483647; | ||||
| 
 | ||||
| 	auto temp = new wxSpinCtrl(m_parent, wxID_ANY, text_value, wxDefaultPosition, size, | ||||
| 		0, min_val, max_val, default_value); | ||||
| 		0|wxTE_PROCESS_ENTER, min_val, max_val, default_value); | ||||
| 
 | ||||
| #ifndef __WXOSX__ | ||||
|     // #ys_FIXME_KILL_FOCUS 
 | ||||
|  | @ -407,15 +424,23 @@ void SpinCtrl::BUILD() { | |||
|     // and on TEXT event under OSX
 | ||||
| 	temp->Bind(wxEVT_KILL_FOCUS, ([this](wxEvent& e) | ||||
| 	{ | ||||
|         if (tmp_value < 0) | ||||
| 	        on_kill_focus(e); | ||||
|         else { | ||||
|             e.Skip(); | ||||
|             on_change_field(); | ||||
|         e.Skip(); | ||||
|         if (bEnterPressed) { | ||||
|             bEnterPressed = false; | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         propagate_value(); | ||||
| 	}), temp->GetId()); | ||||
| 
 | ||||
| 	temp->Bind(wxEVT_SPINCTRL, ([this](wxCommandEvent e) {  on_change_field();  }), temp->GetId()); | ||||
|     temp->Bind(wxEVT_SPINCTRL, ([this](wxCommandEvent e) {  on_change_field();  }), temp->GetId());  | ||||
|      | ||||
|     temp->Bind(wxEVT_TEXT_ENTER, ([this](wxCommandEvent e) | ||||
|     { | ||||
|         e.Skip(); | ||||
|         propagate_value(); | ||||
|         bEnterPressed = true; | ||||
|     }), temp->GetId()); | ||||
| #endif | ||||
| 
 | ||||
| 	temp->Bind(wxEVT_TEXT, ([this](wxCommandEvent e) | ||||
|  | @ -430,12 +455,7 @@ void SpinCtrl::BUILD() { | |||
| 			tmp_value = std::stoi(value); | ||||
|         else tmp_value = -9999; | ||||
| #ifdef __WXOSX__ | ||||
|         if (tmp_value < 0) { | ||||
|             if (m_on_kill_focus != nullptr) | ||||
|                 m_on_kill_focus(m_opt_id); | ||||
|         } | ||||
|         else  | ||||
|             on_change_field(); | ||||
|         propagate_value(); | ||||
| #endif | ||||
| 	}), temp->GetId()); | ||||
| 	 | ||||
|  | @ -445,6 +465,14 @@ void SpinCtrl::BUILD() { | |||
| 	window = dynamic_cast<wxWindow*>(temp); | ||||
| } | ||||
| 
 | ||||
| void SpinCtrl::propagate_value() | ||||
| { | ||||
|     if (tmp_value < 0) | ||||
|         on_kill_focus(); | ||||
|     else | ||||
|         on_change_field(); | ||||
| } | ||||
| 
 | ||||
| void Choice::BUILD() { | ||||
| 	auto size = wxSize(wxDefaultSize); | ||||
| 	if (m_opt.height >= 0) size.SetHeight(m_opt.height); | ||||
|  | @ -483,7 +511,7 @@ void Choice::BUILD() { | |||
|                     on_change_field(); | ||||
|             } | ||||
|             else | ||||
|                 on_kill_focus(e); | ||||
|                 on_kill_focus(); | ||||
|         }), temp->GetId()); | ||||
|     } | ||||
| 
 | ||||
|  | @ -755,8 +783,8 @@ void PointCtrl::BUILD() | |||
| 	val = default_pt(1); | ||||
| 	wxString Y = val - int(val) == 0 ? wxString::Format(_T("%i"), int(val)) : wxNumberFormatter::ToString(val, 2, wxNumberFormatter::Style_None); | ||||
| 
 | ||||
| 	x_textctrl = new wxTextCtrl(m_parent, wxID_ANY, X, wxDefaultPosition, field_size); | ||||
| 	y_textctrl = new wxTextCtrl(m_parent, wxID_ANY, Y, wxDefaultPosition, field_size); | ||||
| 	x_textctrl = new wxTextCtrl(m_parent, wxID_ANY, X, wxDefaultPosition, field_size, wxEVT_TEXT_ENTER); | ||||
| 	y_textctrl = new wxTextCtrl(m_parent, wxID_ANY, Y, wxDefaultPosition, field_size, wxEVT_TEXT_ENTER); | ||||
| 
 | ||||
| 	temp->Add(new wxStaticText(m_parent, wxID_ANY, "x : "), 0, wxALIGN_CENTER_VERTICAL, 0); | ||||
| 	temp->Add(x_textctrl); | ||||
|  | @ -766,8 +794,11 @@ void PointCtrl::BUILD() | |||
| // 	x_textctrl->Bind(wxEVT_TEXT, ([this](wxCommandEvent e) { on_change_field(); }), x_textctrl->GetId());
 | ||||
| // 	y_textctrl->Bind(wxEVT_TEXT, ([this](wxCommandEvent e) { on_change_field(); }), y_textctrl->GetId());
 | ||||
| 
 | ||||
|     x_textctrl->Bind(wxEVT_KILL_FOCUS, ([this](wxEvent& e) { OnKillFocus(e, x_textctrl); }), x_textctrl->GetId()); | ||||
|     y_textctrl->Bind(wxEVT_KILL_FOCUS, ([this](wxEvent& e) { OnKillFocus(e, x_textctrl); }), y_textctrl->GetId()); | ||||
|     x_textctrl->Bind(wxEVT_TEXT_ENTER, ([this](wxCommandEvent e) { propagate_value(x_textctrl); }), x_textctrl->GetId()); | ||||
| 	y_textctrl->Bind(wxEVT_TEXT_ENTER, ([this](wxCommandEvent e) { propagate_value(y_textctrl); }), y_textctrl->GetId()); | ||||
| 
 | ||||
|     x_textctrl->Bind(wxEVT_KILL_FOCUS, ([this](wxEvent& e) { e.Skip(); propagate_value(x_textctrl); }), x_textctrl->GetId()); | ||||
|     y_textctrl->Bind(wxEVT_KILL_FOCUS, ([this](wxEvent& e) { e.Skip(); propagate_value(y_textctrl); }), y_textctrl->GetId()); | ||||
| 
 | ||||
| 	// 	// recast as a wxWindow to fit the calling convention
 | ||||
| 	sizer = dynamic_cast<wxSizer*>(temp); | ||||
|  | @ -776,14 +807,12 @@ void PointCtrl::BUILD() | |||
| 	y_textctrl->SetToolTip(get_tooltip_text(X+", "+Y)); | ||||
| } | ||||
| 
 | ||||
| void PointCtrl::OnKillFocus(wxEvent& e, wxTextCtrl* win) | ||||
| void PointCtrl::propagate_value(wxTextCtrl* win) | ||||
| { | ||||
|     e.Skip(); | ||||
|     if (!win->GetValue().empty()) { | ||||
|     if (!win->GetValue().empty())  | ||||
|         on_change_field(); | ||||
|     } | ||||
|     else | ||||
|         on_kill_focus(e); | ||||
|         on_kill_focus(); | ||||
| } | ||||
| 
 | ||||
| void PointCtrl::set_value(const Vec2d& value, bool change_event) | ||||
|  |  | |||
|  | @ -74,7 +74,7 @@ protected: | |||
|     /// Call the attached on_kill_focus method. 
 | ||||
| 	//! It's important to use wxEvent instead of wxFocusEvent,
 | ||||
| 	//! in another case we can't unfocused control at all
 | ||||
| 	void			on_kill_focus(wxEvent& event); | ||||
| 	void			on_kill_focus(); | ||||
|     /// Call the attached on_change method. 
 | ||||
|     void			on_set_focus(wxEvent& event); | ||||
|     /// Call the attached on_change method. 
 | ||||
|  | @ -226,6 +226,8 @@ protected: | |||
| 
 | ||||
| 	// current value
 | ||||
| 	boost::any			m_value; | ||||
| 
 | ||||
|     bool    bEnterPressed = false; | ||||
|      | ||||
| 	friend class OptionsGroup; | ||||
| }; | ||||
|  | @ -252,6 +254,8 @@ public: | |||
| 	~TextCtrl() {} | ||||
| 
 | ||||
|     void BUILD(); | ||||
|     // Propagate value from field to the OptionGroupe and Config after kill_focus/ENTER
 | ||||
|     void propagate_value(); | ||||
|     wxWindow* window {nullptr}; | ||||
| 
 | ||||
|     virtual void	set_value(const std::string& value, bool change_event = false) { | ||||
|  | @ -310,6 +314,8 @@ public: | |||
| 
 | ||||
| 	wxWindow*		window{ nullptr }; | ||||
| 	void			BUILD() override; | ||||
|     /// Propagate value from field to the OptionGroupe and Config after kill_focus/ENTER
 | ||||
|     void	        propagate_value() ; | ||||
| 
 | ||||
| 	void			set_value(const std::string& value, bool change_event = false) { | ||||
| 		m_disable_change_event = !change_event; | ||||
|  | @ -393,8 +399,8 @@ public: | |||
| 	wxTextCtrl*		y_textctrl{ nullptr }; | ||||
| 
 | ||||
| 	void			BUILD()  override; | ||||
| 
 | ||||
|     void            OnKillFocus(wxEvent& e, wxTextCtrl* win); | ||||
|     // Propagate value from field to the OptionGroupe and Config after kill_focus/ENTER
 | ||||
|     void            propagate_value(wxTextCtrl* win); | ||||
| 	void			set_value(const Vec2d& value, bool change_event = false); | ||||
| 	void			set_value(const boost::any& value, bool change_event = false); | ||||
| 	boost::any&		get_value() override; | ||||
|  |  | |||
|  | @ -2039,11 +2039,17 @@ void GLCanvas3D::Selection::render_sidebar_hints(const std::string& sidebar_fiel | |||
|     const Vec3d& center = get_bounding_box().center(); | ||||
| 
 | ||||
|     if (is_single_full_instance()) | ||||
|     { | ||||
|         ::glTranslated(center(0), center(1), center(2)); | ||||
|         if (boost::starts_with(sidebar_field, "scale")) | ||||
|         { | ||||
|             Transform3d orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); | ||||
|             ::glMultMatrixd(orient_matrix.data()); | ||||
|         } | ||||
|     } | ||||
|     else if (is_single_volume() || is_single_modifier()) | ||||
|     { | ||||
|         const GLVolume* volume = (*m_volumes)[*m_list.begin()]; | ||||
|         Transform3d orient_matrix = volume->get_instance_transformation().get_matrix(true, false, true, true); | ||||
|         Transform3d orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); | ||||
|         const Vec3d& offset = get_bounding_box().center(); | ||||
| 
 | ||||
|         ::glTranslated(offset(0), offset(1), offset(2)); | ||||
|  | @ -2054,8 +2060,7 @@ void GLCanvas3D::Selection::render_sidebar_hints(const std::string& sidebar_fiel | |||
|         ::glTranslated(center(0), center(1), center(2)); | ||||
|         if (requires_local_axes()) | ||||
|         { | ||||
|             const GLVolume* volume = (*m_volumes)[*m_list.begin()]; | ||||
|             Transform3d orient_matrix = volume->get_instance_transformation().get_matrix(true, false, true, true); | ||||
|             Transform3d orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_matrix(true, false, true, true); | ||||
|             ::glMultMatrixd(orient_matrix.data()); | ||||
|         } | ||||
|     } | ||||
|  | @ -2513,7 +2518,9 @@ void GLCanvas3D::Selection::_render_sidebar_rotation_hints(const std::string& si | |||
| 
 | ||||
| void GLCanvas3D::Selection::_render_sidebar_scale_hints(const std::string& sidebar_field) const | ||||
| { | ||||
|     if (boost::ends_with(sidebar_field, "x") || requires_uniform_scale()) | ||||
|     bool uniform_scale = requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling(); | ||||
| 
 | ||||
|     if (boost::ends_with(sidebar_field, "x") || uniform_scale) | ||||
|     { | ||||
|         ::glPushMatrix(); | ||||
|         ::glRotated(-90.0, 0.0, 0.0, 1.0); | ||||
|  | @ -2521,14 +2528,14 @@ void GLCanvas3D::Selection::_render_sidebar_scale_hints(const std::string& sideb | |||
|         ::glPopMatrix(); | ||||
|     } | ||||
| 
 | ||||
|     if (boost::ends_with(sidebar_field, "y") || requires_uniform_scale()) | ||||
|     if (boost::ends_with(sidebar_field, "y") || uniform_scale) | ||||
|     { | ||||
|         ::glPushMatrix(); | ||||
|         _render_sidebar_scale_hint(Y); | ||||
|         ::glPopMatrix(); | ||||
|     } | ||||
| 
 | ||||
|     if (boost::ends_with(sidebar_field, "z") || requires_uniform_scale()) | ||||
|     if (boost::ends_with(sidebar_field, "z") || uniform_scale) | ||||
|     { | ||||
|         ::glPushMatrix(); | ||||
|         ::glRotated(90.0, 1.0, 0.0, 0.0); | ||||
|  | @ -2559,7 +2566,7 @@ void GLCanvas3D::Selection::_render_sidebar_rotation_hint(Axis axis) const | |||
| 
 | ||||
| void GLCanvas3D::Selection::_render_sidebar_scale_hint(Axis axis) const | ||||
| { | ||||
|     m_arrow.set_color((requires_uniform_scale() ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis]), 3); | ||||
|     m_arrow.set_color(((requires_uniform_scale() || wxGetApp().obj_manipul()->get_uniform_scaling()) ? UNIFORM_SCALE_COLOR : AXES_COLOR[axis]), 3); | ||||
| 
 | ||||
|     ::glTranslated(0.0, 5.0, 0.0); | ||||
|     m_arrow.render(); | ||||
|  |  | |||
|  | @ -633,8 +633,10 @@ void ObjectList::get_settings_choice(const wxString& category_name) | |||
| 
 | ||||
| 
 | ||||
|     // Add settings item for object
 | ||||
|     const auto item = GetSelection(); | ||||
|     auto item = GetSelection(); | ||||
|     if (item) { | ||||
|         if (m_objects_model->GetItemType(item) == itInstance) | ||||
|             item = m_objects_model->GetTopParent(item); | ||||
|         const auto settings_item = m_objects_model->IsSettingsItem(item) ? item : m_objects_model->GetSettingsItem(item); | ||||
|         select_item(settings_item ? settings_item : | ||||
|             m_objects_model->AddSettingsChild(item)); | ||||
|  | @ -849,7 +851,7 @@ void ObjectList::load_part( ModelObject* model_object, | |||
|                 new_volume->set_type(static_cast<ModelVolume::Type>(type)); | ||||
|                 new_volume->name = boost::filesystem::path(input_file).filename().string(); | ||||
| 
 | ||||
|                 part_names.Add(new_volume->name); | ||||
|                 part_names.Add(from_u8(new_volume->name)); | ||||
| 
 | ||||
|                 // set a default extruder value, since user can't add it manually
 | ||||
|                 new_volume->config.set_key_value("extruder", new ConfigOptionInt(0)); | ||||
|  | @ -903,7 +905,8 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const int | |||
|     m_parts_changed = true; | ||||
|     parts_changed(obj_idx); | ||||
| 
 | ||||
|     select_item(m_objects_model->AddVolumeChild(GetSelection(), name, type)); | ||||
|     const auto object_item = m_objects_model->GetTopParent(GetSelection()); | ||||
|     select_item(m_objects_model->AddVolumeChild(object_item, from_u8(name), type)); | ||||
| #ifndef __WXOSX__ //#ifdef __WXMSW__ // #ys_FIXME
 | ||||
|     selection_changed(); | ||||
| #endif //no __WXOSX__ //__WXMSW__
 | ||||
|  | @ -1031,7 +1034,7 @@ void ObjectList::split() | |||
|         parent = item; | ||||
| 
 | ||||
|     for (auto id = 0; id < model_object->volumes.size(); id++) { | ||||
|         const auto vol_item = m_objects_model->AddVolumeChild(parent, model_object->volumes[id]->name, | ||||
|         const auto vol_item = m_objects_model->AddVolumeChild(parent, from_u8(model_object->volumes[id]->name), | ||||
|                                             model_object->volumes[id]->is_modifier() ?  | ||||
|                                                 ModelVolume::PARAMETER_MODIFIER : ModelVolume::MODEL_PART, | ||||
|                                             model_object->volumes[id]->config.has("extruder") ? | ||||
|  | @ -1156,6 +1159,10 @@ void ObjectList::part_selection_changed() | |||
|                 else if (m_objects_model->GetItemType(item) == itInstance) { | ||||
|                     og_name = _(L("Instance manipulation")); | ||||
|                     update_and_show_manipulations = true; | ||||
| 
 | ||||
|                     // fill m_config by object's values
 | ||||
|                     const int obj_idx_ = m_objects_model->GetObjectIdByItem(item); | ||||
|                     m_config = &(*m_objects)[obj_idx_]->config; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|  | @ -1188,7 +1195,7 @@ void ObjectList::part_selection_changed() | |||
| void ObjectList::add_object_to_list(size_t obj_idx) | ||||
| { | ||||
|     auto model_object = (*m_objects)[obj_idx]; | ||||
|     wxString item_name = model_object->name; | ||||
|     wxString item_name = from_u8(model_object->name); | ||||
|     const auto item = m_objects_model->Add(item_name, | ||||
|                       !model_object->config.has("extruder") ? 0 : | ||||
|                       model_object->config.option<ConfigOptionInt>("extruder")->value); | ||||
|  | @ -1207,8 +1214,8 @@ void ObjectList::add_object_to_list(size_t obj_idx) | |||
|     if (model_object->volumes.size() > 1) { | ||||
|         for (auto id = 0; id < model_object->volumes.size(); id++) { | ||||
|             auto vol_item = m_objects_model->AddVolumeChild(item, | ||||
|                 model_object->volumes[id]->name, | ||||
|                 model_object->volumes[id]->type()/*ModelVolume::MODEL_PART*/, | ||||
|                 from_u8(model_object->volumes[id]->name), | ||||
|                 model_object->volumes[id]->type(), | ||||
|                 !model_object->volumes[id]->config.has("extruder") ? 0 : | ||||
|                 model_object->volumes[id]->config.option<ConfigOptionInt>("extruder")->value, | ||||
|                 false); | ||||
|  |  | |||
|  | @ -19,7 +19,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : | |||
|     OG_Settings(parent, true) | ||||
| { | ||||
|     m_og->set_name(_(L("Object Manipulation"))); | ||||
|     m_og->label_width = 100; | ||||
|     m_og->label_width = 125; | ||||
|     m_og->set_grid_vgap(5); | ||||
|      | ||||
|     m_og->m_on_change = [this](const std::string& opt_key, const boost::any& value) { | ||||
|  | @ -150,7 +150,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : | |||
|     m_og->append_line(line); | ||||
| 
 | ||||
| 
 | ||||
|     auto add_og_to_object_settings = [](const std::string& option_name, const std::string& sidetext) | ||||
|     auto add_og_to_object_settings = [this](const std::string& option_name, const std::string& sidetext) | ||||
|     { | ||||
|         Line line = { _(option_name), "" }; | ||||
|         ConfigOptionDef def; | ||||
|  | @ -164,6 +164,27 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) : | |||
|             def.max = 360; | ||||
|         } | ||||
| 
 | ||||
|         // Add "uniform scaling" button in front of "Scale" option 
 | ||||
|         else if (option_name == "Scale") { | ||||
|             line.near_label_widget = [this](wxWindow* parent) { | ||||
|                 auto btn = new PrusaLockButton(parent, wxID_ANY); | ||||
|                 btn->Bind(wxEVT_BUTTON, [btn, this](wxCommandEvent &event){ | ||||
|                     event.Skip(); | ||||
|                     wxTheApp->CallAfter([btn, this]() { set_uniform_scaling(btn->IsLocked()); }); | ||||
|                 }); | ||||
|                 m_lock_bnt = btn; | ||||
|                 return btn; | ||||
|             }; | ||||
|         } | ||||
| 
 | ||||
|         // Add empty bmp (Its size have to be equal to PrusaLockButton) in front of "Size" option to label alignment
 | ||||
|         else if (option_name == "Size") { | ||||
|             line.near_label_widget = [this](wxWindow* parent) { | ||||
|                 return new wxStaticBitmap(parent, wxID_ANY, wxNullBitmap, wxDefaultPosition,  | ||||
|                                           wxBitmap(from_u8(var("one_layer_lock_on.png")), wxBITMAP_TYPE_PNG).GetSize()); | ||||
|             }; | ||||
|         } | ||||
| 
 | ||||
|         const std::string lower_name = boost::algorithm::to_lower_copy(option_name); | ||||
| 
 | ||||
|         std::vector<std::string> axes{ "x", "y", "z" }; | ||||
|  | @ -379,6 +400,15 @@ void ObjectManipulation::update_if_dirty() | |||
| 
 | ||||
|     m_cache.rotation = m_new_rotation; | ||||
| 
 | ||||
|     if (wxGetApp().plater()->canvas3D()->get_selection().requires_uniform_scale()) { | ||||
|         m_lock_bnt->SetLock(true); | ||||
|         m_lock_bnt->Disable(); | ||||
|     } | ||||
|     else { | ||||
|         m_lock_bnt->SetLock(m_uniform_scale); | ||||
|         m_lock_bnt->Enable(); | ||||
|     } | ||||
| 
 | ||||
|     if (m_new_enabled) | ||||
|         m_og->enable(); | ||||
|     else | ||||
|  | @ -479,7 +509,7 @@ void ObjectManipulation::change_scale_value(const Vec3d& scale) | |||
| { | ||||
|     Vec3d scaling_factor = scale; | ||||
|     const GLCanvas3D::Selection& selection = wxGetApp().plater()->canvas3D()->get_selection(); | ||||
|     if (selection.requires_uniform_scale()) | ||||
|     if (m_uniform_scale || selection.requires_uniform_scale()) | ||||
|     { | ||||
| #if ENABLE_IMPROVED_SIDEBAR_OBJECTS_MANIPULATION | ||||
|         Vec3d abs_scale_diff = (scale - m_cache.scale).cwiseAbs(); | ||||
|  | @ -535,7 +565,7 @@ void ObjectManipulation::change_size_value(const Vec3d& size) | |||
|     Vec3d scale = 100.0 * Vec3d(size(0) / ref_size(0), size(1) / ref_size(1), size(2) / ref_size(2)); | ||||
|     Vec3d scaling_factor = scale; | ||||
| 
 | ||||
|     if (selection.requires_uniform_scale()) | ||||
|     if (m_uniform_scale || selection.requires_uniform_scale()) | ||||
|     { | ||||
|         Vec3d abs_scale_diff = (scale - m_cache.scale).cwiseAbs(); | ||||
|         double max_diff = abs_scale_diff(X); | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ | |||
| #include "GLCanvas3D.hpp" | ||||
| 
 | ||||
| class wxStaticText; | ||||
| class PrusaLockButton; | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| namespace GUI { | ||||
|  | @ -74,6 +75,8 @@ class ObjectManipulation : public OG_Settings | |||
|     Vec3d           m_new_scale; | ||||
|     Vec3d           m_new_size; | ||||
|     bool            m_new_enabled; | ||||
|     bool            m_uniform_scale {false}; | ||||
|     PrusaLockButton* m_lock_bnt{ nullptr }; | ||||
| 
 | ||||
| public: | ||||
|     ObjectManipulation(wxWindow* parent); | ||||
|  | @ -88,6 +91,9 @@ public: | |||
| 	// Called from the App to update the UI if dirty.
 | ||||
| 	void		update_if_dirty(); | ||||
| 
 | ||||
|     void        set_uniform_scaling(const bool uniform_scale) { m_uniform_scale = uniform_scale;} | ||||
|     bool        get_uniform_scaling() const { return m_uniform_scale; } | ||||
| 
 | ||||
| private: | ||||
|     void reset_settings_value(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -2201,6 +2201,7 @@ PrusaLockButton::PrusaLockButton(   wxWindow *parent, | |||
|     SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); | ||||
| #endif // __WXMSW__
 | ||||
|     SetBitmap(m_bmp_unlock_on); | ||||
|     SetBitmapDisabled(m_bmp_lock_on); | ||||
| 
 | ||||
|     //button events
 | ||||
|     Bind(wxEVT_BUTTON,          &PrusaLockButton::OnButton, this); | ||||
|  | @ -2216,6 +2217,12 @@ void PrusaLockButton::OnButton(wxCommandEvent& event) | |||
|     event.Skip(); | ||||
| } | ||||
| 
 | ||||
| void PrusaLockButton::SetLock(bool lock) | ||||
| { | ||||
|     m_is_pushed = lock; | ||||
|     enter_button(true); | ||||
| } | ||||
| 
 | ||||
| void PrusaLockButton::enter_button(const bool enter) | ||||
| { | ||||
|     wxBitmap* icon = m_is_pushed ? | ||||
|  |  | |||
|  | @ -851,6 +851,7 @@ public: | |||
|     void    OnLeaveBtn(wxMouseEvent& event) { enter_button(false); event.Skip(); } | ||||
| 
 | ||||
|     bool    IsLocked() const { return m_is_pushed; } | ||||
|     void    SetLock(bool lock); | ||||
| 
 | ||||
| protected: | ||||
|     void    enter_button(const bool enter); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bubnikv
						bubnikv