Browse Source

View resource signals in the Connections Dock

GabCoolDude 4 months ago
parent
commit
cdcb2fc389

+ 12 - 5
editor/docks/node_dock.cpp

@@ -87,17 +87,24 @@ void NodeDock::update_lists() {
 	connections->update_tree();
 }
 
-void NodeDock::set_node(Node *p_node) {
-	connections->set_node(p_node);
-	groups->set_current(p_node);
+void NodeDock::set_object(Object *p_object) {
+	connections->set_object(p_object);
+	groups->set_current(Object::cast_to<Node>(p_object));
 
-	if (p_node) {
+	if (p_object) {
 		if (connections_button->is_pressed()) {
 			connections->show();
 		} else {
 			groups->show();
 		}
 
+		if (Object::cast_to<Resource>(p_object)) {
+			show_connections();
+			groups_button->set_disabled(true);
+		} else {
+			groups_button->set_disabled(false);
+		}
+
 		mode_hb->show();
 		select_a_node->hide();
 	} else {
@@ -148,7 +155,7 @@ NodeDock::NodeDock() {
 
 	select_a_node = memnew(Label);
 	select_a_node->set_focus_mode(FOCUS_ACCESSIBILITY);
-	select_a_node->set_text(TTRC("Select a single node to edit its signals and groups."));
+	select_a_node->set_text(TTRC("Select a single node to edit its signals and groups, or select an independent resource to view its signals."));
 	select_a_node->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
 	select_a_node->set_v_size_flags(SIZE_EXPAND_FILL);
 	select_a_node->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER);

+ 1 - 1
editor/docks/node_dock.h

@@ -62,7 +62,7 @@ protected:
 	static void _bind_methods();
 
 public:
-	void set_node(Node *p_node);
+	void set_object(Object *p_object);
 
 	void show_groups();
 	void show_connections();

+ 2 - 2
editor/docks/scene_tree_dock.cpp

@@ -1359,7 +1359,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
 					undo_redo->add_undo_method(node, "set_scene_file_path", node->get_scene_file_path());
 					_node_replace_owner(node, node, root);
 					_node_strip_signal_inheritance(node);
-					NodeDock::get_singleton()->set_node(node); // Refresh.
+					NodeDock::get_singleton()->set_object(node); // Refresh.
 					undo_redo->add_do_method(scene_tree, "update_tree");
 					undo_redo->add_undo_method(scene_tree, "update_tree");
 					undo_redo->commit_action();
@@ -2859,7 +2859,7 @@ void SceneTreeDock::_delete_confirm(bool p_cut) {
 	editor_history->cleanup_history();
 	InspectorDock::get_singleton()->call("_prepare_history");
 	InspectorDock::get_singleton()->update(nullptr);
-	NodeDock::get_singleton()->set_node(nullptr);
+	NodeDock::get_singleton()->set_object(nullptr);
 }
 
 void SceneTreeDock::_update_script_button() {

+ 6 - 6
editor/editor_node.cpp

@@ -2665,7 +2665,7 @@ void EditorNode::push_node_item(Node *p_node) {
 void EditorNode::push_item(Object *p_object, const String &p_property, bool p_inspector_only) {
 	if (!p_object) {
 		InspectorDock::get_inspector_singleton()->edit(nullptr);
-		NodeDock::get_singleton()->set_node(nullptr);
+		NodeDock::get_singleton()->set_object(nullptr);
 		SceneTreeDock::get_singleton()->set_selected(nullptr);
 		InspectorDock::get_singleton()->update(nullptr);
 		hide_unused_editors();
@@ -2786,7 +2786,7 @@ void EditorNode::_edit_current(bool p_skip_foreign, bool p_skip_inspector_update
 	if (!current_obj) {
 		SceneTreeDock::get_singleton()->set_selected(nullptr);
 		InspectorDock::get_inspector_singleton()->edit(nullptr);
-		NodeDock::get_singleton()->set_node(nullptr);
+		NodeDock::get_singleton()->set_object(nullptr);
 		InspectorDock::get_singleton()->update(nullptr);
 		EditorDebuggerNode::get_singleton()->clear_remote_tree_selection();
 		hide_unused_editors();
@@ -2820,7 +2820,7 @@ void EditorNode::_edit_current(bool p_skip_foreign, bool p_skip_inspector_update
 		if (!p_skip_inspector_update) {
 			InspectorDock::get_inspector_singleton()->edit(current_res);
 			SceneTreeDock::get_singleton()->set_selected(nullptr);
-			NodeDock::get_singleton()->set_node(nullptr);
+			NodeDock::get_singleton()->set_object(current_res);
 			InspectorDock::get_singleton()->update(nullptr);
 			EditorDebuggerNode::get_singleton()->clear_remote_tree_selection();
 			ImportDock::get_singleton()->set_edit_path(current_res->get_path());
@@ -2850,7 +2850,7 @@ void EditorNode::_edit_current(bool p_skip_foreign, bool p_skip_inspector_update
 
 		InspectorDock::get_inspector_singleton()->edit(current_node);
 		if (current_node->is_inside_tree()) {
-			NodeDock::get_singleton()->set_node(current_node);
+			NodeDock::get_singleton()->set_object(current_node);
 			SceneTreeDock::get_singleton()->set_selected(current_node);
 			SceneTreeDock::get_singleton()->set_selection({ current_node });
 			InspectorDock::get_singleton()->update(current_node);
@@ -2862,7 +2862,7 @@ void EditorNode::_edit_current(bool p_skip_foreign, bool p_skip_inspector_update
 				}
 			}
 		} else {
-			NodeDock::get_singleton()->set_node(nullptr);
+			NodeDock::get_singleton()->set_object(nullptr);
 			SceneTreeDock::get_singleton()->set_selected(nullptr);
 			InspectorDock::get_singleton()->update(nullptr);
 		}
@@ -2910,7 +2910,7 @@ void EditorNode::_edit_current(bool p_skip_foreign, bool p_skip_inspector_update
 		}
 
 		InspectorDock::get_inspector_singleton()->edit(current_obj);
-		NodeDock::get_singleton()->set_node(nullptr);
+		NodeDock::get_singleton()->set_object(nullptr);
 		SceneTreeDock::get_singleton()->set_selected(selected_node);
 		SceneTreeDock::get_singleton()->set_selection(multi_nodes);
 		InspectorDock::get_singleton()->update(nullptr);

+ 47 - 33
editor/scene/connections_dialog.cpp

@@ -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);
 }

+ 11 - 9
editor/scene/connections_dialog.h

@@ -51,8 +51,8 @@ class ConnectDialog : public ConfirmationDialog {
 
 public:
 	struct ConnectionData {
-		Node *source = nullptr;
-		Node *target = nullptr;
+		Object *source = nullptr;
+		Object *target = nullptr;
 		StringName signal;
 		StringName method;
 		uint32_t flags = 0;
@@ -62,9 +62,9 @@ public:
 		ConnectionData() {}
 
 		ConnectionData(const Connection &p_connection) {
-			source = Object::cast_to<Node>(p_connection.signal.get_object());
+			source = p_connection.signal.get_object();
 			signal = p_connection.signal.get_name();
-			target = Object::cast_to<Node>(p_connection.callable.get_object());
+			target = p_connection.callable.get_object();
 			flags = p_connection.flags;
 
 			Callable base_callable;
@@ -111,7 +111,7 @@ private:
 	Label *connect_to_label = nullptr;
 	LineEdit *from_signal = nullptr;
 	LineEdit *filter_nodes = nullptr;
-	Node *source = nullptr;
+	Object *source = nullptr;
 	ConnectionData source_connection_data;
 	StringName signal;
 	PackedStringArray signal_args;
@@ -170,8 +170,8 @@ protected:
 	static void _bind_methods();
 
 public:
-	static StringName generate_method_callback_name(Node *p_source, const String &p_signal_name, Node *p_target);
-	Node *get_source() const;
+	static StringName generate_method_callback_name(Object *p_source, const String &p_signal_name, Object *p_target);
+	Object *get_source() const;
 	ConnectionData get_source_connection_data() const;
 	StringName get_signal_name() const;
 	PackedStringArray get_signal_args() const;
@@ -230,7 +230,7 @@ class ConnectionsDock : public VBoxContainer {
 		SLOT_MENU_DISCONNECT,
 	};
 
-	Node *selected_node = nullptr;
+	Object *selected_object = nullptr;
 	ConnectionsDockTree *tree = nullptr;
 
 	ConfirmationDialog *disconnect_all_dialog = nullptr;
@@ -242,6 +242,8 @@ class ConnectionsDock : public VBoxContainer {
 	PopupMenu *slot_menu = nullptr;
 	LineEdit *search_box = nullptr;
 
+	bool is_editing_resource = false;
+
 	void _filter_changed(const String &p_text);
 
 	void _make_or_edit_connection();
@@ -273,7 +275,7 @@ protected:
 	static void _bind_methods();
 
 public:
-	void set_node(Node *p_node);
+	void set_object(Object *p_obj);
 	void update_tree();
 
 	ConnectionsDock();