summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/GraphEdit.xml23
-rw-r--r--scene/gui/graph_edit.cpp15
-rw-r--r--scene/gui/graph_edit.h2
3 files changed, 40 insertions, 0 deletions
diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml
index 965dbe7449..33145dccd0 100644
--- a/doc/classes/GraphEdit.xml
+++ b/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" />
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index f51031765c..42f434f0ac 100644
--- a/scene/gui/graph_edit.cpp
+++ b/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");
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index beb17ec4cf..cf35aeb8b2 100644
--- a/scene/gui/graph_edit.h
+++ b/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);