Jelajahi Sumber

Allow to abort `SpinSlider` value changes

passivestar 1 tahun lalu
induk
melakukan
5689dbc209

+ 57 - 21
editor/gui/editor_spin_slider.cpp

@@ -68,27 +68,15 @@ void EditorSpinSlider::gui_input(const Ref<InputEvent> &p_event) {
 					}
 					return;
 				} else {
-					grabbing_spinner_attempt = true;
-					grabbing_spinner_dist_cache = 0;
-					pre_grab_value = get_value();
-					grabbing_spinner = false;
-					grabbing_spinner_mouse_pos = get_global_mouse_position();
-					emit_signal("grabbed");
+					_grab_start();
 				}
 			} else {
-				if (grabbing_spinner_attempt) {
-					if (grabbing_spinner) {
-						Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
-						Input::get_singleton()->warp_mouse(grabbing_spinner_mouse_pos);
-						queue_redraw();
-						emit_signal("ungrabbed");
-					} else {
-						_focus_entered();
-					}
-
-					grabbing_spinner = false;
-					grabbing_spinner_attempt = false;
-				}
+				_grab_end();
+			}
+		} else if (mb->get_button_index() == MouseButton::RIGHT) {
+			if (mb->is_pressed() && is_grabbing()) {
+				_grab_end();
+				set_value(pre_grab_value);
 			}
 		} else if (mb->get_button_index() == MouseButton::WHEEL_UP || mb->get_button_index() == MouseButton::WHEEL_DOWN) {
 			if (grabber->is_visible()) {
@@ -142,8 +130,47 @@ void EditorSpinSlider::gui_input(const Ref<InputEvent> &p_event) {
 	}
 
 	Ref<InputEventKey> k = p_event;
-	if (k.is_valid() && k->is_pressed() && k->is_action("ui_accept", true)) {
-		_focus_entered();
+	if (k.is_valid() && k->is_pressed()) {
+		if (k->is_action("ui_accept", true)) {
+			_focus_entered();
+		} else if (is_grabbing()) {
+			if (k->is_action("ui_cancel", true)) {
+				_grab_end();
+				set_value(pre_grab_value);
+			}
+			accept_event();
+		}
+	}
+}
+
+void EditorSpinSlider::_grab_start() {
+	grabbing_spinner_attempt = true;
+	grabbing_spinner_dist_cache = 0;
+	pre_grab_value = get_value();
+	grabbing_spinner = false;
+	grabbing_spinner_mouse_pos = get_global_mouse_position();
+	emit_signal("grabbed");
+}
+
+void EditorSpinSlider::_grab_end() {
+	if (grabbing_spinner_attempt) {
+		if (grabbing_spinner) {
+			Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
+			Input::get_singleton()->warp_mouse(grabbing_spinner_mouse_pos);
+			queue_redraw();
+			grabbing_spinner = false;
+			emit_signal("ungrabbed");
+		} else {
+			_focus_entered();
+		}
+
+		grabbing_spinner_attempt = false;
+	}
+
+	if (grabbing_grabber) {
+		grabbing_grabber = false;
+		mousewheel_over_grabber = false;
+		emit_signal("ungrabbed");
 	}
 }
 
@@ -173,16 +200,25 @@ void EditorSpinSlider::_grabber_gui_input(const Ref<InputEvent> &p_event) {
 	if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT) {
 		if (mb->is_pressed()) {
 			grabbing_grabber = true;
+			pre_grab_value = get_value();
 			if (!mousewheel_over_grabber) {
 				grabbing_ratio = get_as_ratio();
 				grabbing_from = grabber->get_transform().xform(mb->get_position()).x;
 			}
+			grab_focus();
 			emit_signal("grabbed");
 		} else {
 			grabbing_grabber = false;
 			mousewheel_over_grabber = false;
 			emit_signal("ungrabbed");
 		}
+	} else if (mb.is_valid() && mb->get_button_index() == MouseButton::RIGHT) {
+		if (mb->is_pressed() && grabbing_grabber) {
+			grabbing_grabber = false;
+			mousewheel_over_grabber = false;
+			set_value(pre_grab_value);
+			emit_signal("ungrabbed");
+		}
 	}
 
 	Ref<InputEventMouseMotion> mm = p_event;

+ 3 - 0
editor/gui/editor_spin_slider.h

@@ -72,6 +72,9 @@ class EditorSpinSlider : public Range {
 	bool hide_slider = false;
 	bool flat = false;
 
+	void _grab_start();
+	void _grab_end();
+
 	void _grabber_gui_input(const Ref<InputEvent> &p_event);
 	void _value_input_closed();
 	void _value_input_submitted(const String &);

+ 4 - 0
editor/plugins/node_3d_editor_plugin.cpp

@@ -1488,6 +1488,10 @@ Transform3D Node3DEditorViewport::_compute_transform(TransformMode p_mode, const
 }
 
 void Node3DEditorViewport::_surface_mouse_enter() {
+	if (Input::get_singleton()->get_mouse_mode() == Input::MOUSE_MODE_CAPTURED) {
+		return;
+	}
+
 	if (!surface->has_focus() && (!get_viewport()->gui_get_focus_owner() || !get_viewport()->gui_get_focus_owner()->is_text_field())) {
 		surface->grab_focus();
 	}