Преглед изворни кода

Add GraphEdit.is_node_hover_valid(...) method

This is a virtual method that can be used to add additional error
condition checks while the connection is still being dragged. If true is
returned, the connection is valid. If false is returned, the connection
is invalid and thus not possible (ie. it will not snap). The virtual
method is exposed with an underscore to scripts.
Johannes Witt пре 4 година
родитељ
комит
2fb69afde6
3 измењених фајлова са 40 додато и 0 уклоњено
  1. 23 0
      doc/classes/GraphEdit.xml
  2. 15 0
      scene/gui/graph_edit.cpp
  3. 2 0
      scene/gui/graph_edit.h

+ 23 - 0
doc/classes/GraphEdit.xml

@@ -55,6 +55,29 @@
 				[/codeblock]
 				[/codeblock]
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="_is_node_hover_valid" qualifiers="virtual">
+			<return type="bool" />
+			<argument index="0" name="from" type="StringName" />
+			<argument index="1" name="from_slot" type="int" />
+			<argument index="2" name="to" type="StringName" />
+			<argument index="3" name="to_slot" type="int" />
+			<description>
+				This virtual method can be used to insert additional error detection while the user is dragging a connection over a valid port.
+				Return [code]true[/code] if the connection is indeed valid or return [code]false[/code] if the connection is impossible. If the connection is impossible, no snapping to the port and thus no connection request to that port will happen.
+				In this example a connection to same node is suppressed:
+				[codeblocks]
+				[gdscript]
+				func _is_node_hover_valid(from, from_slot, to, to_slot):
+				    return from != to
+				[/gdscript]
+				[csharp]
+				public override bool _IsNodeHoverValid(String from, int fromSlot, String to, int toSlot) {
+				    return from != to;
+				}
+				[/csharp]
+				[/codeblocks]
+			</description>
+		</method>
 		<method name="add_valid_connection_type">
 		<method name="add_valid_connection_type">
 			<return type="void" />
 			<return type="void" />
 			<argument index="0" name="from_type" type="int" />
 			<argument index="0" name="from_type" type="int" />

+ 15 - 0
scene/gui/graph_edit.cpp

@@ -710,6 +710,9 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
 
 
 						int type = gn->get_connection_output_type(j);
 						int type = gn->get_connection_output_type(j);
 						if ((type == connecting_type || valid_connection_types.has(ConnType(connecting_type, type))) && is_in_output_hotzone(gn, j, mpos, port_size)) {
 						if ((type == connecting_type || valid_connection_types.has(ConnType(connecting_type, type))) && is_in_output_hotzone(gn, j, mpos, port_size)) {
+							if (!is_node_hover_valid(gn->get_name(), j, connecting_from, connecting_index)) {
+								continue;
+							}
 							connecting_target = true;
 							connecting_target = true;
 							connecting_to = pos;
 							connecting_to = pos;
 							connecting_target_to = gn->get_name();
 							connecting_target_to = gn->get_name();
@@ -725,6 +728,9 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
 
 
 						int type = gn->get_connection_input_type(j);
 						int type = gn->get_connection_input_type(j);
 						if ((type == connecting_type || valid_connection_types.has(ConnType(connecting_type, type))) && is_in_input_hotzone(gn, j, mpos, port_size)) {
 						if ((type == connecting_type || valid_connection_types.has(ConnType(connecting_type, type))) && is_in_input_hotzone(gn, j, mpos, port_size)) {
+							if (!is_node_hover_valid(connecting_from, connecting_index, gn->get_name(), j)) {
+								continue;
+							}
 							connecting_target = true;
 							connecting_target = true;
 							connecting_to = pos;
 							connecting_to = pos;
 							connecting_target_to = gn->get_name();
 							connecting_target_to = gn->get_name();
@@ -1453,6 +1459,14 @@ void GraphEdit::force_connection_drag_end() {
 	emit_signal(SNAME("connection_drag_ended"));
 	emit_signal(SNAME("connection_drag_ended"));
 }
 }
 
 
+bool GraphEdit::is_node_hover_valid(const StringName &p_from, const int p_from_port, const StringName &p_to, const int p_to_port) {
+	bool valid;
+	if (GDVIRTUAL_CALL(_is_node_hover_valid, p_from, p_from_port, p_to, p_to_port, valid)) {
+		return valid;
+	}
+	return true;
+}
+
 void GraphEdit::set_panning_scheme(PanningScheme p_scheme) {
 void GraphEdit::set_panning_scheme(PanningScheme p_scheme) {
 	panning_scheme = p_scheme;
 	panning_scheme = p_scheme;
 	panner->set_control_scheme((ViewPanner::ControlScheme)p_scheme);
 	panner->set_control_scheme((ViewPanner::ControlScheme)p_scheme);
@@ -2315,6 +2329,7 @@ void GraphEdit::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_selected", "node"), &GraphEdit::set_selected);
 	ClassDB::bind_method(D_METHOD("set_selected", "node"), &GraphEdit::set_selected);
 
 
 	GDVIRTUAL_BIND(_get_connection_line, "from", "to")
 	GDVIRTUAL_BIND(_get_connection_line, "from", "to")
+	GDVIRTUAL_BIND(_is_node_hover_valid, "from", "from_slot", "to", "to_slot");
 
 
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "right_disconnects"), "set_right_disconnects", "is_right_disconnects_enabled");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "right_disconnects"), "set_right_disconnects", "is_right_disconnects_enabled");
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scroll_offset", PROPERTY_HINT_NONE, "suffix:px"), "set_scroll_ofs", "get_scroll_ofs");
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scroll_offset", PROPERTY_HINT_NONE, "suffix:px"), "set_scroll_ofs", "get_scroll_ofs");

+ 2 - 0
scene/gui/graph_edit.h

@@ -280,6 +280,7 @@ protected:
 	GDVIRTUAL2RC(Vector<Vector2>, _get_connection_line, Vector2, Vector2)
 	GDVIRTUAL2RC(Vector<Vector2>, _get_connection_line, Vector2, Vector2)
 	GDVIRTUAL3R(bool, _is_in_input_hotzone, Object *, int, Vector2)
 	GDVIRTUAL3R(bool, _is_in_input_hotzone, Object *, int, Vector2)
 	GDVIRTUAL3R(bool, _is_in_output_hotzone, Object *, int, Vector2)
 	GDVIRTUAL3R(bool, _is_in_output_hotzone, Object *, int, Vector2)
+	GDVIRTUAL4R(bool, _is_node_hover_valid, StringName, int, StringName, int);
 
 
 public:
 public:
 	Error connect_node(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port);
 	Error connect_node(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port);
@@ -287,6 +288,7 @@ public:
 	void disconnect_node(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port);
 	void disconnect_node(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port);
 	void clear_connections();
 	void clear_connections();
 	void force_connection_drag_end();
 	void force_connection_drag_end();
+	virtual bool is_node_hover_valid(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port);
 
 
 	void set_connection_activity(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port, float p_activity);
 	void set_connection_activity(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port, float p_activity);