From 1c695fd97eb4d987bdf2914ed97ee491f4ab3a80 Mon Sep 17 00:00:00 2001
From: YuSanka <yusanka@gmail.com>
Date: Tue, 12 Jun 2018 23:42:01 +0200
Subject: [PATCH] Added object movers to the object settings. Added
 SliderControl to Field.

---
 xs/src/slic3r/GUI/Field.cpp        | 64 ++++++++++++++++++++++++++++++
 xs/src/slic3r/GUI/Field.hpp        | 32 +++++++++++++++
 xs/src/slic3r/GUI/GUI.cpp          | 46 ++++++++++++++++++++-
 xs/src/slic3r/GUI/GUI.hpp          |  1 +
 xs/src/slic3r/GUI/OptionsGroup.cpp |  3 +-
 5 files changed, 144 insertions(+), 2 deletions(-)

diff --git a/xs/src/slic3r/GUI/Field.cpp b/xs/src/slic3r/GUI/Field.cpp
index 43c9e7db9..acab4f4b6 100644
--- a/xs/src/slic3r/GUI/Field.cpp
+++ b/xs/src/slic3r/GUI/Field.cpp
@@ -665,6 +665,70 @@ boost::any& PointCtrl::get_value()
 	return m_value = ret_point;
 }
 
+void SliderCtrl::BUILD()
+{
+	auto size = wxSize(wxDefaultSize);
+	if (m_opt.height >= 0) size.SetHeight(m_opt.height);
+	if (m_opt.width >= 0) size.SetWidth(m_opt.width);
+
+	auto temp = new wxBoxSizer(wxHORIZONTAL);
+
+	auto default = static_cast<ConfigOptionInt*>(m_opt.default_value)->value;
+	auto min = m_opt.min == INT_MIN ? 0 : m_opt.min;
+	auto max = m_opt.max == INT_MAX ? 100 : m_opt.max;
+
+	m_slider = new wxSlider(m_parent, wxID_ANY, default * m_scale, 
+							min * m_scale, max * m_scale,
+							wxDefaultPosition, size);
+ 	wxSize field_size(40, -1);
+
+	m_textctrl = new wxTextCtrl(m_parent, wxID_ANY, wxString::Format("%d", m_slider->GetValue()/m_scale), 
+								wxDefaultPosition, field_size);
+
+	temp->Add(m_slider, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL, 0);
+	temp->Add(m_textctrl, 0, wxALIGN_CENTER_VERTICAL, 0);
+
+	m_slider->Bind(wxEVT_SLIDER, ([this](wxCommandEvent e) {
+		if (!m_disable_change_event){
+			int val = boost::any_cast<int>(get_value());
+			m_textctrl->SetLabel(wxString::Format("%d", val));
+			on_change_field();
+		}
+	}), m_slider->GetId());
+
+	m_textctrl->Bind(wxEVT_TEXT, ([this](wxCommandEvent e) {
+		std::string value = e.GetString().utf8_str().data();
+		if (is_matched(value, "^-?\\d+(\\.\\d*)?$")){
+			m_disable_change_event = true;
+			m_slider->SetValue(stoi(value)*m_scale);
+			m_disable_change_event = false;
+			on_change_field();
+		}
+	}), m_textctrl->GetId());
+
+	// 	// recast as a wxWindow to fit the calling convention
+	m_sizer = dynamic_cast<wxSizer*>(temp);
+}
+
+void SliderCtrl::set_value(const boost::any& value, bool change_event)
+{
+	m_disable_change_event = !change_event;
+
+	m_slider->SetValue(boost::any_cast<int>(value)*m_scale);
+	int val = boost::any_cast<int>(get_value());
+	m_textctrl->SetLabel(wxString::Format("%d", val));
+
+	m_disable_change_event = false;
+}
+
+boost::any& SliderCtrl::get_value()
+{
+// 	int ret_val;
+// 	x_textctrl->GetValue().ToDouble(&val);
+	return m_value = int(m_slider->GetValue()/m_scale);
+}
+
+
 } // GUI
 } // Slic3r
 
diff --git a/xs/src/slic3r/GUI/Field.hpp b/xs/src/slic3r/GUI/Field.hpp
index 948178d3e..40f56c0d3 100644
--- a/xs/src/slic3r/GUI/Field.hpp
+++ b/xs/src/slic3r/GUI/Field.hpp
@@ -384,6 +384,38 @@ public:
 	wxSizer*		getSizer() override { return sizer; }
 };
 
+class SliderCtrl : public Field {
+	using Field::Field;
+public:
+	SliderCtrl(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {}
+	SliderCtrl(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {}
+	~SliderCtrl() {}
+
+	wxSizer*		m_sizer{ nullptr };
+	wxTextCtrl*		m_textctrl{ nullptr };
+	wxSlider*		m_slider{ nullptr };
+
+	int				m_scale = 10;
+
+	void			BUILD()  override;
+
+	void			set_value(const int value, bool change_event = false);
+	void			set_value(const boost::any& value, bool change_event = false);
+	boost::any&		get_value() override;
+
+	void			enable() override {
+		m_slider->Enable();
+		m_textctrl->Enable();
+		m_textctrl->SetEditable(true);
+	}
+	void			disable() override{
+		m_slider->Disable();
+		m_textctrl->Disable();
+		m_textctrl->SetEditable(false);
+	}
+	wxSizer*		getSizer() override { return m_sizer; }
+};
+
 } // GUI
 } // Slic3r
 
diff --git a/xs/src/slic3r/GUI/GUI.cpp b/xs/src/slic3r/GUI/GUI.cpp
index 01a61ff51..d897b6d29 100644
--- a/xs/src/slic3r/GUI/GUI.cpp
+++ b/xs/src/slic3r/GUI/GUI.cpp
@@ -139,6 +139,7 @@ bool		g_show_print_info = false;
 bool		g_show_manifold_warning_icon = false;
 wxSizer		*m_sizer_object_buttons = nullptr;
 wxSizer		*m_sizer_part_buttons = nullptr;
+wxSizer		*m_sizer_object_movers = nullptr;
 wxDataViewCtrl			*m_objects_ctrl = nullptr;
 MyObjectTreeModel		*m_objects_model = nullptr;
 wxCollapsiblePane		*m_collpane_settings = nullptr;
@@ -1032,6 +1033,42 @@ wxBoxSizer* content_edit_object_buttons(wxWindow* win)
 	return sizer;
 }
 
+wxSizer* object_movers(wxWindow *win)
+{
+	DynamicPrintConfig* config = &g_PresetBundle->/*full_config();//*/printers.get_edited_preset().config; // TODO get config from Model_volume
+	std::shared_ptr<ConfigOptionsGroup> optgroup = std::make_shared<ConfigOptionsGroup>(win, "Move", config);
+ 	optgroup->label_width = 20;
+
+	ConfigOptionDef def;
+	def.label = L("X");
+	def.type = coInt;
+	def.gui_type = "slider";
+	def.default_value = new ConfigOptionInt(0);
+// 	def.min = -(model_object->bounding_box->size->x) * 4;
+// 	def.max =  model_object->bounding_box->size->x * 4;
+
+	Option option = Option(def, "x");
+	option.opt.full_width = true;
+	optgroup->append_single_option_line(option);
+
+	def.label = L("Y");
+// 	def.min = -(model_object->bounding_box->size->y) * 4;
+// 	def.max =  model_object->bounding_box->size->y * 4;
+	option = Option(def, "y");
+	optgroup->append_single_option_line(option);
+	
+	def.label = L("Z");
+// 	def.min = -(model_object->bounding_box->size->z) * 4;
+// 	def.max =  model_object->bounding_box->size->z * 4;
+	option = Option(def, "z");
+	optgroup->append_single_option_line(option);
+
+	m_optgroups.push_back(optgroup);  // ogObjectMovers
+	m_sizer_object_movers = optgroup->sizer;
+	m_sizer_object_movers->Show(false);
+	return optgroup->sizer;
+}
+
 Line add_og_to_object_settings(const std::string& option_name, const std::string& sidetext, int def_value=0)
 {
 	Line line = { _(option_name), "" };
@@ -1075,7 +1112,7 @@ Line add_og_to_object_settings(const std::string& option_name, const std::string
 
 wxBoxSizer* content_settings(wxWindow *win)
 {
-	DynamicPrintConfig* config = &g_PresetBundle->printers.get_edited_preset().config; // TODO get config from Model_volume
+	DynamicPrintConfig* config = &g_PresetBundle->/*full_config();//*/printers.get_edited_preset().config; // TODO get config from Model_volume
 	std::shared_ptr<ConfigOptionsGroup> optgroup = std::make_shared<ConfigOptionsGroup>(win, "Extruders", config);
 	optgroup->label_width = m_label_width;
 
@@ -1095,6 +1132,8 @@ wxBoxSizer* content_settings(wxWindow *win)
 	add_btn->SetBitmap(wxBitmap(from_u8(Slic3r::var("add.png")), wxBITMAP_TYPE_PNG));
 	sizer->Add(add_btn, 0, wxALIGN_LEFT | wxLEFT, 20);
 
+	sizer->Add(object_movers(win), 0, wxEXPAND | wxLEFT, 20);
+
 	return sizer;
 }
 
@@ -1141,6 +1180,8 @@ void unselect_objects()
 		m_sizer_object_buttons->Show(false);
 	if (m_sizer_part_buttons->IsShown(1)) 
 		m_sizer_part_buttons->Show(false);
+	if (m_sizer_object_movers->IsShown(1)) 
+		m_sizer_object_movers->Show(false);
 	if (m_collpane_settings->IsShown())
 		m_collpane_settings->Show(false);
 }
@@ -1159,6 +1200,8 @@ void select_current_object(int idx)
 	if (get_view_mode() == ConfigMenuModeExpert){
 		if (!m_sizer_object_buttons->IsShown(1))
 			m_sizer_object_buttons->Show(true);
+		if (!m_sizer_object_movers->IsShown(1))
+			m_sizer_object_movers->Show(true);
 		if (!m_collpane_settings->IsShown())
 			m_collpane_settings->Show(true);
 	}
@@ -1179,6 +1222,7 @@ void add_expert_mode_part(	wxWindow* parent, wxBoxSizer* sizer,
 		if (collpane->IsCollapsed()) {
 			m_sizer_object_buttons->Show(false);
 			m_sizer_part_buttons->Show(false);
+			m_sizer_object_movers->Show(false);
 			m_collpane_settings->Show(false);
 		}
 // 		else 
diff --git a/xs/src/slic3r/GUI/GUI.hpp b/xs/src/slic3r/GUI/GUI.hpp
index 277729ab0..6e975f953 100644
--- a/xs/src/slic3r/GUI/GUI.hpp
+++ b/xs/src/slic3r/GUI/GUI.hpp
@@ -61,6 +61,7 @@ enum ogGroup{
 	ogFrequentlyChangingParameters,
 	ogFrequentlyObjectSettings,
 	ogObjectSettings,
+	ogObjectMovers,
 	ogPartSettings
 };
 
diff --git a/xs/src/slic3r/GUI/OptionsGroup.cpp b/xs/src/slic3r/GUI/OptionsGroup.cpp
index 52882afda..4778047be 100644
--- a/xs/src/slic3r/GUI/OptionsGroup.cpp
+++ b/xs/src/slic3r/GUI/OptionsGroup.cpp
@@ -30,6 +30,7 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
                 opt.gui_type.compare("i_enum_closed") == 0) {
 		m_fields.emplace(id, STDMOVE(Choice::Create<Choice>(parent(), opt, id)));
     } else if (opt.gui_type.compare("slider") == 0) {
+		m_fields.emplace(id, STDMOVE(SliderCtrl::Create<SliderCtrl>(parent(), opt, id)));
     } else if (opt.gui_type.compare("i_spin") == 0) { // Spinctrl
     } else { 
         switch (opt.type) {
@@ -189,7 +190,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText**	colored_Label/*
 			sizer->Add(field->getWindow(), option.opt.full_width ? 1 : 0, (option.opt.full_width ? wxEXPAND : 0) |
 							wxBOTTOM | wxTOP | wxALIGN_CENTER_VERTICAL, (wxOSX||!staticbox) ? 0 : 2);
 		if (is_sizer_field(field)) 
-			sizer->Add(field->getSizer(), 0, (option.opt.full_width ? wxEXPAND : 0) | wxALIGN_CENTER_VERTICAL, 0);
+			sizer->Add(field->getSizer(), 1, (option.opt.full_width ? wxEXPAND : 0) | wxALIGN_CENTER_VERTICAL, 0);
 		return;
 	}