diff --git a/core/object/object.cpp b/core/object/object.cpp
index d08095e8b9..759525aa9d 100644
--- a/core/object/object.cpp
+++ b/core/object/object.cpp
@@ -1924,6 +1924,7 @@ void Object::_bind_methods() {
BIND_ENUM_CONSTANT(CONNECT_PERSIST);
BIND_ENUM_CONSTANT(CONNECT_ONE_SHOT);
BIND_ENUM_CONSTANT(CONNECT_REFERENCE_COUNTED);
+ BIND_ENUM_CONSTANT(CONNECT_APPEND_SOURCE_OBJECT);
}
void Object::set_deferred(const StringName &p_property, const Variant &p_value) {
diff --git a/core/object/object.h b/core/object/object.h
index 9f02fa3824..50c6950f65 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -573,10 +573,11 @@ public:
enum ConnectFlags {
CONNECT_DEFERRED = 1,
- CONNECT_PERSIST = 2, // hint for scene to save this connection
+ CONNECT_PERSIST = 2, // Hint for scene to save this connection.
CONNECT_ONE_SHOT = 4,
CONNECT_REFERENCE_COUNTED = 8,
- CONNECT_INHERITED = 16, // Used in editor builds.
+ CONNECT_APPEND_SOURCE_OBJECT = 16,
+ CONNECT_INHERITED = 32, // Used in editor builds.
};
struct Connection {
diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml
index ba6e40a12a..cfc1cebb18 100644
--- a/doc/classes/Object.xml
+++ b/doc/classes/Object.xml
@@ -1039,5 +1039,8 @@
Reference-counted connections can be assigned to the same [Callable] multiple times. Each disconnection decreases the internal counter. The signal fully disconnects only when the counter reaches 0.
+
+ The source object is automatically bound when a [PackedScene] is instantiated. If this flag bit is enabled, the source object will be appended right after the original arguments of the signal.
+
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp
index fd6f0c10ad..c8ccde374c 100644
--- a/editor/connections_dialog.cpp
+++ b/editor/connections_dialog.cpp
@@ -46,6 +46,7 @@
#include "editor/themes/editor_scale.h"
#include "scene/gui/button.h"
#include "scene/gui/check_box.h"
+#include "scene/gui/flow_container.h"
#include "scene/gui/label.h"
#include "scene/gui/line_edit.h"
#include "scene/gui/margin_container.h"
@@ -195,6 +196,8 @@ void ConnectDialog::_unbind_count_changed(double p_count) {
e->set_read_only(p_count > 0);
}
}
+
+ append_source->set_disabled(p_count > 0);
}
void ConnectDialog::_method_selected() {
@@ -626,6 +629,10 @@ bool ConnectDialog::get_one_shot() const {
return one_shot->is_pressed();
}
+bool ConnectDialog::get_append_source() const {
+ return !append_source->is_disabled() && append_source->is_pressed();
+}
+
/*
* Returns true if ConnectDialog is being used to edit an existing connection.
*/
@@ -667,14 +674,15 @@ void ConnectDialog::init(const ConnectionData &p_cd, const PackedStringArray &p_
_update_ok_enabled();
- bool b_deferred = (p_cd.flags & CONNECT_DEFERRED) == CONNECT_DEFERRED;
- bool b_oneshot = (p_cd.flags & CONNECT_ONE_SHOT) == CONNECT_ONE_SHOT;
+ bool b_deferred = (p_cd.flags & CONNECT_DEFERRED);
+ bool b_oneshot = (p_cd.flags & CONNECT_ONE_SHOT);
+ bool b_append_source = (p_cd.flags & CONNECT_APPEND_SOURCE_OBJECT);
deferred->set_pressed(b_deferred);
one_shot->set_pressed(b_oneshot);
+ append_source->set_pressed(b_append_source);
unbind_count->set_max(p_signal_args.size());
-
unbind_count->set_value(p_cd.unbinds);
_unbind_count_changed(p_cd.unbinds);
@@ -892,20 +900,23 @@ ConnectDialog::ConnectDialog() {
advanced->set_pressed(EditorSettings::get_singleton()->get_project_metadata("editor_metadata", "use_advanced_connections", false));
advanced->connect(SceneStringName(pressed), callable_mp(this, &ConnectDialog::_advanced_pressed));
- HBoxContainer *hbox = memnew(HBoxContainer);
- vbc_right->add_child(hbox);
+ FlowContainer *fc_flags = memnew(FlowContainer);
+ vbc_right->add_child(fc_flags);
deferred = memnew(CheckBox);
- deferred->set_h_size_flags(0);
deferred->set_text(TTR("Deferred"));
deferred->set_tooltip_text(TTR("Defers the signal, storing it in a queue and only firing it at idle time."));
- hbox->add_child(deferred);
+ fc_flags->add_child(deferred);
one_shot = memnew(CheckBox);
- one_shot->set_h_size_flags(0);
one_shot->set_text(TTR("One Shot"));
one_shot->set_tooltip_text(TTR("Disconnects the signal after its first emission."));
- hbox->add_child(one_shot);
+ fc_flags->add_child(one_shot);
+
+ append_source = memnew(CheckBox);
+ append_source->set_text(TTRC("Append Source"));
+ append_source->set_tooltip_text(TTRC("The source object is automatically sent when the signal is emitted."));
+ fc_flags->add_child(append_source);
cdbinds = memnew(ConnectDialogBinds);
@@ -961,7 +972,8 @@ void ConnectionsDock::_make_or_edit_connection() {
}
bool b_deferred = connect_dialog->get_deferred();
bool b_oneshot = connect_dialog->get_one_shot();
- cd.flags = CONNECT_PERSIST | (b_deferred ? CONNECT_DEFERRED : 0) | (b_oneshot ? CONNECT_ONE_SHOT : 0);
+ bool b_append_source = connect_dialog->get_append_source();
+ cd.flags = CONNECT_PERSIST | (b_deferred ? CONNECT_DEFERRED : 0) | (b_oneshot ? CONNECT_ONE_SHOT : 0) | (b_append_source ? CONNECT_APPEND_SOURCE_OBJECT : 0);
// If the function is found in target's own script, check the editor setting
// to determine if the script should be opened.
@@ -1003,6 +1015,45 @@ void ConnectionsDock::_make_or_edit_connection() {
if (add_script_function_request) {
PackedStringArray script_function_args = connect_dialog->get_signal_args();
script_function_args.resize(script_function_args.size() - cd.unbinds);
+
+ // Append the source.
+ if (b_append_source) {
+ String class_name = cd.source->get_class();
+ bool found = false;
+
+ Ref