From 83ab034f9a8769e2d2e8ce306bafa16682150234 Mon Sep 17 00:00:00 2001
From: YuSanka <yusanka@gmail.com>
Date: Wed, 11 Aug 2021 14:34:49 +0200
Subject: [PATCH] Fixed ENTER for ComboBoxes and TextCtrls in Settings Tabs
 (related to #6692) + Code cleaning : Deleted unused set_focus

---
 src/slic3r/GUI/Field.cpp        | 58 ++++++++-------------------------
 src/slic3r/GUI/Field.hpp        | 19 +++++------
 src/slic3r/GUI/OptionsGroup.cpp | 11 -------
 src/slic3r/GUI/OptionsGroup.hpp |  2 --
 4 files changed, 22 insertions(+), 68 deletions(-)

diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp
index d7d474531..69072d375 100644
--- a/src/slic3r/GUI/Field.cpp
+++ b/src/slic3r/GUI/Field.cpp
@@ -73,8 +73,6 @@ Field::~Field()
 {
 	if (m_on_kill_focus)
 		m_on_kill_focus = nullptr;
-	if (m_on_set_focus)
-		m_on_set_focus = nullptr;
 	if (m_on_change)
 		m_on_change = nullptr;
 	if (m_back_to_initial_value)
@@ -156,15 +154,6 @@ void Field::on_kill_focus()
         m_on_kill_focus(m_opt_id);
 }
 
-void Field::on_set_focus(wxEvent& event)
-{
-    // to allow the default behavior
-	event.Skip();
-	// call the registered function if it is available
-    if (m_on_set_focus!=nullptr)
-        m_on_set_focus(m_opt_id);
-}
-
 void Field::on_change_field()
 {
 //       std::cerr << "calling Field::_on_change \n";
@@ -507,13 +496,11 @@ void TextCtrl::BUILD() {
             e.Skip();
             temp->GetToolTip()->Enable(true);
 #endif // __WXGTK__
-            bEnterPressed = true;
+            EnterPressed enter(this);
             propagate_value();
         }), temp->GetId());
     }
 
-    temp->Bind(wxEVT_SET_FOCUS, ([this](wxEvent& e) { on_set_focus(e); }), temp->GetId());
-
 	temp->Bind(wxEVT_LEFT_DOWN, ([temp](wxEvent& event)
 	{
 		//! to allow the default handling
@@ -530,26 +517,11 @@ void TextCtrl::BUILD() {
 	temp->Bind(wxEVT_KILL_FOCUS, ([this, temp](wxEvent& e)
 	{
 		e.Skip();
-#ifdef __WXOSX__
-		// OSX issue: For some unknown reason wxEVT_KILL_FOCUS is emitted twice in a row in some cases
-	    // (like when information dialog is shown during an update of the option value)
-		// Thus, suppress its second call
-		if (bKilledFocus)
-			return;
-		bKilledFocus = true;
-#endif // __WXOSX__
-
 #if !defined(__WXGTK__)
 		temp->GetToolTip()->Enable(true);
 #endif // __WXGTK__
-        if (bEnterPressed)
-            bEnterPressed = false;
-		else
+        if (!bEnterPressed)
             propagate_value();
-#ifdef __WXOSX__
-		// After processing of KILL_FOCUS event we should to invalidate a bKilledFocus flag
-		bKilledFocus = false;
-#endif // __WXOSX__
 	}), temp->GetId());
 /*
 	// select all text using Ctrl+A
@@ -990,26 +962,13 @@ void Choice::BUILD() {
     if (m_is_editable) {
         temp->Bind(wxEVT_KILL_FOCUS, [this](wxEvent& e) {
             e.Skip();
-            if (bKilledFocus)
-                return;
-
-            bKilledFocus = true;
-
-            if (bEnterPressed)
-                bEnterPressed = false;
-            else
+            if (!bEnterPressed)
                 propagate_value();
-            // After processing of KILL_FOCUS event we should to invalidate a bKilledFocus flag
-            bKilledFocus = false;
         } );
 
         temp->Bind(wxEVT_TEXT_ENTER, [this, temp](wxEvent& e) {
-#ifdef _WIN32
-            temp->SetFocus();
-#else
-            bEnterPressed = true;
+            EnterPressed enter(this);
             propagate_value();
-#endif //_WIN32
         } );
     }
 
@@ -1161,6 +1120,15 @@ void Choice::set_value(const boost::any& value, bool change_event)
         }
         else
 			field->SetSelection(idx);
+
+        if (!m_value.empty() && m_opt.opt_key == "fill_density") {
+            // If m_value was changed before, then update m_value here too to avoid case 
+            // when control's value is already changed from the ConfigManipulation::update_print_fff_config(),
+            // but m_value doesn't respect it.
+            if (double val; text_value.ToDouble(&val))
+                m_value = val;
+        }
+
 		break;
 	}
 	case coEnum: {
diff --git a/src/slic3r/GUI/Field.hpp b/src/slic3r/GUI/Field.hpp
index 34a2481b5..8bdf4b8d8 100644
--- a/src/slic3r/GUI/Field.hpp
+++ b/src/slic3r/GUI/Field.hpp
@@ -52,10 +52,17 @@ protected:
 	//! in another case we can't unfocused control at all
 	void			on_kill_focus();
     /// Call the attached on_change method. 
-    void			on_set_focus(wxEvent& event);
-    /// Call the attached on_change method. 
     void			on_change_field();
 
+    class EnterPressed {
+    public:
+        EnterPressed(Field* field) : 
+            m_parent(field){ m_parent->set_enter_pressed(true);  }
+        ~EnterPressed()    { m_parent->set_enter_pressed(false); }
+    private:
+        Field* m_parent;
+    };
+
 public:
     /// Call the attached m_back_to_initial_value method. 
 	void			on_back_to_initial_value();
@@ -69,9 +76,6 @@ public:
     /// Function object to store callback passed in from owning object.
 	t_kill_focus	m_on_kill_focus {nullptr};
 
-    /// Function object to store callback passed in from owning object.
-	t_kill_focus	m_on_set_focus {nullptr};
-
     /// Function object to store callback passed in from owning object.
 	t_change		m_on_change {nullptr};
 
@@ -236,10 +240,6 @@ class TextCtrl : public Field {
     void    change_field_value(wxEvent& event);
 #endif //__WXGTK__
 
-#ifdef __WXOSX__
-	bool	bKilledFocus = false;
-#endif // __WXOSX__
-
 public:
 	TextCtrl(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt,  id) {}
 	TextCtrl(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {}
@@ -342,7 +342,6 @@ public:
 
 class Choice : public Field {
 	using Field::Field;
-	bool	bKilledFocus = false;
 
 public:
 	Choice(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {}
diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp
index 728981f0a..b57b7f302 100644
--- a/src/slic3r/GUI/OptionsGroup.cpp
+++ b/src/slic3r/GUI/OptionsGroup.cpp
@@ -88,11 +88,6 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
 			if (!m_disabled)
 				this->on_kill_focus(opt_id);
 	};
-    field->m_on_set_focus = [this](const std::string& opt_id) {
-			//! This function will be called from Field.
-			if (!m_disabled)
-				this->on_set_focus(opt_id);
-	};
     field->m_parent = parent();
 
 	field->m_back_to_initial_value = [this](std::string opt_id) {
@@ -514,12 +509,6 @@ void OptionsGroup::clear_fields_except_of(const std::vector<std::string> left_fi
     }
 }
 
-void OptionsGroup::on_set_focus(const std::string& opt_key)
-{
-    if (m_set_focus != nullptr)
-        m_set_focus(opt_key);
-}
-
 void OptionsGroup::on_change_OG(const t_config_option_key& opt_id, const boost::any& value) {
 	if (m_on_change != nullptr)
 		m_on_change(opt_id, value);
diff --git a/src/slic3r/GUI/OptionsGroup.hpp b/src/slic3r/GUI/OptionsGroup.hpp
index 10cea5dda..592f2cd76 100644
--- a/src/slic3r/GUI/OptionsGroup.hpp
+++ b/src/slic3r/GUI/OptionsGroup.hpp
@@ -100,7 +100,6 @@ public:
 	// To be called when the field loses focus, to assign a new initial value to the field.
 	// Used by the relative position / rotation / scale manipulation fields of the Object Manipulation UI.
     t_kill_focus    m_fill_empty_value { nullptr };
-    t_kill_focus    m_set_focus { nullptr };
 	std::function<DynamicPrintConfig()>	m_get_initial_config{ nullptr };
 	std::function<DynamicPrintConfig()>	m_get_sys_config{ nullptr };
 	std::function<bool()>	have_sys_config{ nullptr };
@@ -208,7 +207,6 @@ protected:
 	const t_field&		build_field(const Option& opt);
 
     virtual void		on_kill_focus(const std::string& opt_key) {};
-	virtual void		on_set_focus(const std::string& opt_key);
 	virtual void		on_change_OG(const t_config_option_key& opt_id, const boost::any& value);
 	virtual void		back_to_initial_value(const std::string& opt_key) {}
 	virtual void		back_to_sys_value(const std::string& opt_key) {}