Ver código fonte

Merge pull request #20182 from allkhor/cherry_from_dcf5be92

 Make BaseButton not emit press when container is scrolled [2.1]
Rémi Verschelde 7 anos atrás
pai
commit
08f824243e

+ 1 - 1
scene/gui/base_button.cpp

@@ -225,7 +225,7 @@ void BaseButton::_notification(int p_what) {
 		status.hovering = false;
 		status.hovering = false;
 		update();
 		update();
 	}
 	}
-	if (p_what == NOTIFICATION_DRAG_BEGIN) {
+	if (p_what == NOTIFICATION_DRAG_BEGIN || p_what == NOTIFICATION_SCROLL_BEGIN) {
 
 
 		if (status.press_attempt) {
 		if (status.press_attempt) {
 			status.press_attempt = false;
 			status.press_attempt = false;

+ 2 - 0
scene/gui/control.cpp

@@ -2361,6 +2361,8 @@ void Control::_bind_methods() {
 	BIND_CONSTANT(NOTIFICATION_FOCUS_EXIT);
 	BIND_CONSTANT(NOTIFICATION_FOCUS_EXIT);
 	BIND_CONSTANT(NOTIFICATION_THEME_CHANGED);
 	BIND_CONSTANT(NOTIFICATION_THEME_CHANGED);
 	BIND_CONSTANT(NOTIFICATION_MODAL_CLOSE);
 	BIND_CONSTANT(NOTIFICATION_MODAL_CLOSE);
+	BIND_CONSTANT(NOTIFICATION_SCROLL_BEGIN);
+	BIND_CONSTANT(NOTIFICATION_SCROLL_END);
 
 
 	BIND_CONSTANT(CURSOR_ARROW);
 	BIND_CONSTANT(CURSOR_ARROW);
 	BIND_CONSTANT(CURSOR_IBEAM);
 	BIND_CONSTANT(CURSOR_IBEAM);

+ 2 - 0
scene/gui/control.h

@@ -218,6 +218,8 @@ public:
 		NOTIFICATION_FOCUS_EXIT = 44,
 		NOTIFICATION_FOCUS_EXIT = 44,
 		NOTIFICATION_THEME_CHANGED = 45,
 		NOTIFICATION_THEME_CHANGED = 45,
 		NOTIFICATION_MODAL_CLOSE = 46,
 		NOTIFICATION_MODAL_CLOSE = 46,
+		NOTIFICATION_SCROLL_BEGIN = 47,
+		NOTIFICATION_SCROLL_END = 48,
 
 
 	};
 	};
 
 

+ 49 - 24
scene/gui/scroll_container.cpp

@@ -74,6 +74,12 @@ void ScrollContainer::_cancel_drag() {
 	drag_accum = Vector2();
 	drag_accum = Vector2();
 	last_drag_accum = Vector2();
 	last_drag_accum = Vector2();
 	drag_from = Vector2();
 	drag_from = Vector2();
+
+	if (beyond_deadzone) {
+		emit_signal("scroll_ended");
+		propagate_notification(NOTIFICATION_SCROLL_END);
+		beyond_deadzone = false;
+	}
 }
 }
 
 
 void ScrollContainer::_input_event(const InputEvent &p_input_event) {
 void ScrollContainer::_input_event(const InputEvent &p_input_event) {
@@ -123,13 +129,7 @@ void ScrollContainer::_input_event(const InputEvent &p_input_event) {
 			if (mb.pressed) {
 			if (mb.pressed) {
 
 
 				if (drag_touching) {
 				if (drag_touching) {
-					set_fixed_process(false);
-					drag_touching_deaccel = false;
-					drag_touching = false;
-					drag_speed = Vector2();
-					drag_accum = Vector2();
-					last_drag_accum = Vector2();
-					drag_from = Vector2();
+					_cancel_drag();
 				}
 				}
 
 
 				if (true) {
 				if (true) {
@@ -139,6 +139,7 @@ void ScrollContainer::_input_event(const InputEvent &p_input_event) {
 					drag_from = Vector2(h_scroll->get_val(), v_scroll->get_val());
 					drag_from = Vector2(h_scroll->get_val(), v_scroll->get_val());
 					drag_touching = OS::get_singleton()->has_touchscreen_ui_hint();
 					drag_touching = OS::get_singleton()->has_touchscreen_ui_hint();
 					drag_touching_deaccel = false;
 					drag_touching_deaccel = false;
+					beyond_deadzone = false;
 					time_since_motion = 0;
 					time_since_motion = 0;
 					if (drag_touching) {
 					if (drag_touching) {
 						set_fixed_process(true);
 						set_fixed_process(true);
@@ -150,9 +151,7 @@ void ScrollContainer::_input_event(const InputEvent &p_input_event) {
 				if (drag_touching) {
 				if (drag_touching) {
 
 
 					if (drag_speed == Vector2()) {
 					if (drag_speed == Vector2()) {
-						drag_touching_deaccel = false;
-						drag_touching = false;
-						set_fixed_process(false);
+						_cancel_drag();
 					} else {
 					} else {
 
 
 						drag_touching_deaccel = true;
 						drag_touching_deaccel = true;
@@ -169,17 +168,26 @@ void ScrollContainer::_input_event(const InputEvent &p_input_event) {
 
 
 				Vector2 motion = Vector2(mm.relative_x, mm.relative_y);
 				Vector2 motion = Vector2(mm.relative_x, mm.relative_y);
 				drag_accum -= motion;
 				drag_accum -= motion;
-				Vector2 diff = drag_from + drag_accum;
-
-				if (scroll_h)
-					h_scroll->set_val(diff.x);
-				else
-					drag_accum.x = 0;
-				if (scroll_v)
-					v_scroll->set_val(diff.y);
-				else
-					drag_accum.y = 0;
-				time_since_motion = 0;
+				if (beyond_deadzone || scroll_h && Math::abs(drag_accum.x) > deadzone || scroll_v && Math::abs(drag_accum.y) > deadzone) {
+					if (!beyond_deadzone) {
+						propagate_notification(NOTIFICATION_SCROLL_BEGIN);
+						emit_signal("scroll_started");
+
+						beyond_deadzone = true;
+						// resetting drag_accum here ensures smooth scrolling after reaching deadzone
+						drag_accum = -motion;
+					}
+					Vector2 diff = drag_from + drag_accum;
+					if (scroll_h)
+						h_scroll->set_val(diff.x);
+					else
+						drag_accum.x = 0;
+					if (scroll_v)
+						v_scroll->set_val(diff.y);
+					else
+						drag_accum.y = 0;
+					time_since_motion = 0;
+				}
 			}
 			}
 
 
 		} break;
 		} break;
@@ -317,9 +325,7 @@ void ScrollContainer::_notification(int p_what) {
 				drag_speed = Vector2(sgn_x * val_x, sgn_y * val_y);
 				drag_speed = Vector2(sgn_x * val_x, sgn_y * val_y);
 
 
 				if (turnoff_h && turnoff_v) {
 				if (turnoff_h && turnoff_v) {
-					set_fixed_process(false);
-					drag_touching = false;
-					drag_touching_deaccel = false;
+					_cancel_drag();
 				}
 				}
 
 
 			} else {
 			} else {
@@ -407,6 +413,7 @@ int ScrollContainer::get_v_scroll() const {
 
 
 	return v_scroll->get_val();
 	return v_scroll->get_val();
 }
 }
+
 void ScrollContainer::set_v_scroll(int p_pos) {
 void ScrollContainer::set_v_scroll(int p_pos) {
 
 
 	v_scroll->set_val(p_pos);
 	v_scroll->set_val(p_pos);
@@ -417,12 +424,21 @@ int ScrollContainer::get_h_scroll() const {
 
 
 	return h_scroll->get_val();
 	return h_scroll->get_val();
 }
 }
+
 void ScrollContainer::set_h_scroll(int p_pos) {
 void ScrollContainer::set_h_scroll(int p_pos) {
 
 
 	h_scroll->set_val(p_pos);
 	h_scroll->set_val(p_pos);
 	_cancel_drag();
 	_cancel_drag();
 }
 }
 
 
+int ScrollContainer::get_deadzone() const {
+	return deadzone;
+}
+
+void ScrollContainer::set_deadzone(int p_deadzone) {
+	deadzone = p_deadzone;
+}
+
 void ScrollContainer::_bind_methods() {
 void ScrollContainer::_bind_methods() {
 
 
 	ObjectTypeDB::bind_method(_MD("_scroll_moved"), &ScrollContainer::_scroll_moved);
 	ObjectTypeDB::bind_method(_MD("_scroll_moved"), &ScrollContainer::_scroll_moved);
@@ -436,9 +452,15 @@ void ScrollContainer::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("get_h_scroll"), &ScrollContainer::get_h_scroll);
 	ObjectTypeDB::bind_method(_MD("get_h_scroll"), &ScrollContainer::get_h_scroll);
 	ObjectTypeDB::bind_method(_MD("set_v_scroll", "val"), &ScrollContainer::set_v_scroll);
 	ObjectTypeDB::bind_method(_MD("set_v_scroll", "val"), &ScrollContainer::set_v_scroll);
 	ObjectTypeDB::bind_method(_MD("get_v_scroll"), &ScrollContainer::get_v_scroll);
 	ObjectTypeDB::bind_method(_MD("get_v_scroll"), &ScrollContainer::get_v_scroll);
+	ObjectTypeDB::bind_method(_MD("set_deadzone", "deadzone"), &ScrollContainer::set_deadzone);
+	ObjectTypeDB::bind_method(_MD("get_deadzone"), &ScrollContainer::get_deadzone);
+
+	ADD_SIGNAL(MethodInfo("scroll_started"));
+	ADD_SIGNAL(MethodInfo("scroll_ended"));
 
 
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll/horizontal"), _SCS("set_enable_h_scroll"), _SCS("is_h_scroll_enabled"));
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll/horizontal"), _SCS("set_enable_h_scroll"), _SCS("is_h_scroll_enabled"));
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll/vertical"), _SCS("set_enable_v_scroll"), _SCS("is_v_scroll_enabled"));
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scroll/vertical"), _SCS("set_enable_v_scroll"), _SCS("is_v_scroll_enabled"));
+	ADD_PROPERTY(PropertyInfo(Variant::INT, "scroll/deadzone"), _SCS("set_deadzone"), _SCS("get_deadzone"));
 };
 };
 
 
 ScrollContainer::ScrollContainer() {
 ScrollContainer::ScrollContainer() {
@@ -457,6 +479,9 @@ ScrollContainer::ScrollContainer() {
 	drag_speed = Vector2();
 	drag_speed = Vector2();
 	drag_touching = false;
 	drag_touching = false;
 	drag_touching_deaccel = false;
 	drag_touching_deaccel = false;
+	beyond_deadzone = false;
 	scroll_h = true;
 	scroll_h = true;
 	scroll_v = true;
 	scroll_v = true;
+
+	deadzone = GLOBAL_DEF("gui/common/default_scroll_deadzone", 0);
 };
 };

+ 6 - 0
scene/gui/scroll_container.h

@@ -55,10 +55,13 @@ class ScrollContainer : public Container {
 	bool drag_touching;
 	bool drag_touching;
 	bool drag_touching_deaccel;
 	bool drag_touching_deaccel;
 	bool click_handled;
 	bool click_handled;
+	bool beyond_deadzone;
 
 
 	bool scroll_h;
 	bool scroll_h;
 	bool scroll_v;
 	bool scroll_v;
 
 
+	int deadzone;
+
 	void _cancel_drag();
 	void _cancel_drag();
 
 
 protected:
 protected:
@@ -85,6 +88,9 @@ public:
 	void set_enable_v_scroll(bool p_enable);
 	void set_enable_v_scroll(bool p_enable);
 	bool is_v_scroll_enabled() const;
 	bool is_v_scroll_enabled() const;
 
 
+	int get_deadzone() const;
+	void set_deadzone(int p_deadzone);
+
 	virtual bool clips_input() const;
 	virtual bool clips_input() const;
 	ScrollContainer();
 	ScrollContainer();
 };
 };