View resource signals in the Connections Dock

This commit is contained in:
GabCoolDude
2025-07-28 08:54:35 +02:00
parent 4a1c1c483b
commit cdcb2fc389
6 changed files with 79 additions and 56 deletions

View File

@ -199,7 +199,11 @@ void ConnectDialog::_tree_node_selected() {
return;
}
dst_path = source->get_path_to(current);
Node *source_node = Object::cast_to<Node>(source);
if (source_node) {
dst_path = source_node->get_path_to(current);
}
if (!edit_mode) {
set_dst_method(generate_method_callback_name(source, signal, current));
}
@ -212,7 +216,7 @@ void ConnectDialog::_tree_node_selected() {
}
void ConnectDialog::_focus_currently_connected() {
tree->set_selected(source);
tree->set_selected(Object::cast_to<Node>(source));
}
void ConnectDialog::_unbind_count_changed(double p_count) {
@ -267,8 +271,9 @@ void ConnectDialog::_remove_bind() {
/*
* Automatically generates a name for the callback method.
*/
StringName ConnectDialog::generate_method_callback_name(Node *p_source, const String &p_signal_name, Node *p_target) {
String node_name = p_source->get_name();
StringName ConnectDialog::generate_method_callback_name(Object *p_source, const String &p_signal_name, Object *p_target) {
String node_name = p_source->call("get_name");
for (int i = 0; i < node_name.length(); i++) { // TODO: Regex filter may be cleaner.
char32_t c = node_name[i];
if ((i == 0 && !is_unicode_identifier_start(c)) || (i > 0 && !is_unicode_identifier_continue(c))) {
@ -492,7 +497,8 @@ void ConnectDialog::_update_ok_enabled() {
}
void ConnectDialog::_update_warning_label() {
Node *dst = source->get_node(dst_path);
Node *dst = Object::cast_to<Node>(source)->get_node(dst_path);
if (dst == nullptr) {
warning_label->set_visible(false);
return;
@ -537,7 +543,7 @@ void ConnectDialog::_bind_methods() {
ADD_SIGNAL(MethodInfo("connected"));
}
Node *ConnectDialog::get_source() const {
Object *ConnectDialog::get_source() const {
return source;
}
@ -693,15 +699,15 @@ void ConnectDialog::shortcut_input(const Ref<InputEvent> &p_event) {
void ConnectDialog::init(const ConnectionData &p_cd, const PackedStringArray &p_signal_args, bool p_edit) {
set_hide_on_ok(false);
source = static_cast<Node *>(p_cd.source);
source = p_cd.source;
signal = p_cd.signal;
signal_args = p_signal_args;
tree->set_selected(nullptr);
tree->set_marked(source);
tree->set_marked(Object::cast_to<Node>(source));
if (p_cd.target) {
set_dst_node(static_cast<Node *>(p_cd.target));
set_dst_node(Object::cast_to<Node>(p_cd.target));
set_dst_method(p_cd.method);
}
@ -984,7 +990,8 @@ void ConnectionsDock::_filter_changed(const String &p_text) {
*/
void ConnectionsDock::_make_or_edit_connection() {
NodePath dst_path = connect_dialog->get_dst_path();
Node *target = selected_node->get_node(dst_path);
Node *target = Object::cast_to<Node>(selected_object)->get_node(dst_path);
ERR_FAIL_NULL(target);
ConnectDialog::ConnectionData cd;
@ -1077,7 +1084,7 @@ void ConnectionsDock::_make_or_edit_connection() {
script_function_args.push_back("extra_arg_" + itos(i) + ": " + Variant::get_type_name(cd.binds[i].get_type()));
}
EditorNode::get_singleton()->emit_signal(SNAME("script_add_function_request"), target, cd.method, script_function_args);
EditorNode::get_singleton()->emit_signal(SNAME("script_add_function_request"), cd.target, cd.method, script_function_args);
}
if (connect_dialog->is_editing()) {
@ -1094,7 +1101,7 @@ void ConnectionsDock::_make_or_edit_connection() {
* Creates single connection w/ undo-redo functionality.
*/
void ConnectionsDock::_connect(const ConnectDialog::ConnectionData &p_cd) {
Node *source = Object::cast_to<Node>(p_cd.source);
Object *source = p_cd.source;
Node *target = Object::cast_to<Node>(p_cd.target);
if (!source || !target) {
@ -1118,14 +1125,14 @@ void ConnectionsDock::_connect(const ConnectDialog::ConnectionData &p_cd) {
* Break single connection w/ undo-redo functionality.
*/
void ConnectionsDock::_disconnect(const ConnectDialog::ConnectionData &p_cd) {
ERR_FAIL_COND(p_cd.source != selected_node); // Shouldn't happen but... Bugcheck.
ERR_FAIL_COND(p_cd.source != selected_object); // Shouldn't happen but... Bugcheck.
EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
undo_redo->create_action(vformat(TTR("Disconnect '%s' from '%s'"), p_cd.signal, p_cd.method));
Callable callable = p_cd.get_callable();
undo_redo->add_do_method(selected_node, "disconnect", p_cd.signal, callable);
undo_redo->add_undo_method(selected_node, "connect", p_cd.signal, callable, p_cd.flags);
undo_redo->add_do_method(selected_object, "disconnect", p_cd.signal, callable);
undo_redo->add_undo_method(selected_object, "connect", p_cd.signal, callable, p_cd.flags);
undo_redo->add_do_method(this, "update_tree");
undo_redo->add_undo_method(this, "update_tree");
undo_redo->add_do_method(SceneTreeDock::get_singleton()->get_tree_editor(), "update_tree"); // To force redraw of scene tree.
@ -1153,8 +1160,8 @@ void ConnectionsDock::_disconnect_all() {
Connection connection = child->get_metadata(0);
if (!_is_connection_inherited(connection)) {
ConnectDialog::ConnectionData cd = connection;
undo_redo->add_do_method(selected_node, "disconnect", cd.signal, cd.get_callable());
undo_redo->add_undo_method(selected_node, "connect", cd.signal, cd.get_callable(), cd.flags);
undo_redo->add_do_method(selected_object, "disconnect", cd.signal, cd.get_callable());
undo_redo->add_undo_method(selected_object, "connect", cd.signal, cd.get_callable(), cd.flags);
}
child = child->get_next();
}
@ -1172,7 +1179,7 @@ void ConnectionsDock::_tree_item_selected() {
if (item && _get_item_type(*item) == TREE_ITEM_TYPE_SIGNAL) {
connect_button->set_text(TTR("Connect..."));
connect_button->set_button_icon(get_editor_theme_icon(SNAME("Instance")));
connect_button->set_disabled(false);
connect_button->set_disabled(is_editing_resource);
} else if (item && _get_item_type(*item) == TREE_ITEM_TYPE_CONNECTION) {
connect_button->set_text(TTR("Disconnect"));
connect_button->set_button_icon(get_editor_theme_icon(SNAME("Unlinked")));
@ -1219,19 +1226,24 @@ bool ConnectionsDock::_is_connection_inherited(Connection &p_connection) {
* Open connection dialog with TreeItem data to CREATE a brand-new connection.
*/
void ConnectionsDock::_open_connection_dialog(TreeItem &p_item) {
if (is_editing_resource) {
return;
}
const Dictionary sinfo = p_item.get_metadata(0);
const StringName signal_name = sinfo["name"];
const PackedStringArray signal_args = sinfo["args"];
ConnectDialog::ConnectionData cd;
Node *selected_node = Object::cast_to<Node>(selected_object);
Node *dst_node = selected_node->get_owner() ? selected_node->get_owner() : selected_node;
if (!dst_node || dst_node->get_script().is_null()) {
dst_node = _find_first_script(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root());
}
ConnectDialog::ConnectionData cd;
cd.source = selected_node;
cd.signal = signal_name;
cd.source = selected_object;
cd.target = dst_node;
cd.signal = signal_name;
cd.method = ConnectDialog::generate_method_callback_name(cd.source, signal_name, cd.target);
connect_dialog->init(cd, signal_args);
connect_dialog->set_title(TTR("Connect a Signal to a Method"));
@ -1248,8 +1260,8 @@ void ConnectionsDock::_open_edit_connection_dialog(TreeItem &p_item) {
Connection connection = p_item.get_metadata(0);
ConnectDialog::ConnectionData cd = connection;
Node *src = Object::cast_to<Node>(cd.source);
Node *dst = Object::cast_to<Node>(cd.target);
Object *src = cd.source;
Object *dst = cd.target;
if (src && dst) {
const StringName &signal_name = cd.signal;
@ -1271,7 +1283,7 @@ void ConnectionsDock::_go_to_method(TreeItem &p_item) {
Connection connection = p_item.get_metadata(0);
ConnectDialog::ConnectionData cd = connection;
ERR_FAIL_COND(cd.source != selected_node); // Shouldn't happen but... bugcheck.
ERR_FAIL_COND(cd.source != selected_object); // Shouldn't happen but... bugcheck.
if (!cd.target) {
return;
@ -1342,6 +1354,7 @@ void ConnectionsDock::_signal_menu_about_to_popup() {
}
}
signal_menu->set_item_disabled(signal_menu->get_item_index(SIGNAL_MENU_CONNECT), is_editing_resource);
signal_menu->set_item_disabled(signal_menu->get_item_index(SIGNAL_MENU_DISCONNECT_ALL), disable_disconnect_all);
signal_menu->set_item_disabled(signal_menu->get_item_index(SIGNAL_MENU_OPEN_DOCS), String(meta["class"]).is_empty());
}
@ -1509,8 +1522,9 @@ void ConnectionsDock::_bind_methods() {
ClassDB::bind_method("update_tree", &ConnectionsDock::update_tree);
}
void ConnectionsDock::set_node(Node *p_node) {
selected_node = p_node;
void ConnectionsDock::set_object(Object *p_obj) {
selected_object = p_obj;
is_editing_resource = (Object::cast_to<Resource>(selected_object) != nullptr);
update_tree();
}
@ -1521,15 +1535,15 @@ void ConnectionsDock::update_tree() {
}
tree->clear();
if (!selected_node) {
if (!selected_object) {
return;
}
TreeItem *root = tree->create_item();
DocTools *doc_data = EditorHelp::get_doc_data();
EditorData &editor_data = EditorNode::get_editor_data();
StringName native_base = selected_node->get_class();
Ref<Script> script_base = selected_node->get_script();
StringName native_base = selected_object->get_class();
Ref<Script> script_base = selected_object->get_script();
while (native_base != StringName()) {
String class_name;
@ -1643,7 +1657,7 @@ void ConnectionsDock::update_tree() {
// List existing connections.
List<Object::Connection> existing_connections;
selected_node->get_signal_connection_list(signal_name, &existing_connections);
selected_object->get_signal_connection_list(signal_name, &existing_connections);
for (const Object::Connection &F : existing_connections) {
Connection connection = F;
@ -1657,7 +1671,7 @@ void ConnectionsDock::update_tree() {
continue;
}
String path = String(selected_node->get_path_to(target)) + " :: " + cd.method + "()";
String path = String(Object::cast_to<Node>(selected_object)->get_path_to(target)) + " :: " + cd.method + "()";
if (cd.flags & CONNECT_DEFERRED) {
path += " (deferred)";
}
@ -1694,7 +1708,7 @@ void ConnectionsDock::update_tree() {
}
}
connect_button->set_text(TTR("Connect..."));
connect_button->set_text(TTRC("Connect..."));
connect_button->set_button_icon(get_editor_theme_icon(SNAME("Instance")));
connect_button->set_disabled(true);
}