Pārlūkot izejas kodu

Merge pull request #51128 from HaSa1002/add-graphedit-is-ok-method-4

Rémi Verschelde 3 gadi atpakaļ
vecāks
revīzija
790b63b27c
3 mainītis faili ar 40 papildinājumiem un 0 dzēšanām
  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]
 			</description>
 		</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">
 			<return type="void" />
 			<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);
 						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_to = pos;
 							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);
 						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_to = pos;
 							connecting_target_to = gn->get_name();
@@ -1453,6 +1459,14 @@ void GraphEdit::force_connection_drag_end() {
 	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) {
 	panning_scheme = 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);
 
 	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::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)
 	GDVIRTUAL3R(bool, _is_in_input_hotzone, Object *, int, Vector2)
 	GDVIRTUAL3R(bool, _is_in_output_hotzone, Object *, int, Vector2)
+	GDVIRTUAL4R(bool, _is_node_hover_valid, StringName, int, StringName, int);
 
 public:
 	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 clear_connections();
 	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);