diff --git a/editor/docks/node_dock.cpp b/editor/docks/node_dock.cpp index 1f02d87e57b..6de79672e02 100644 --- a/editor/docks/node_dock.cpp +++ b/editor/docks/node_dock.cpp @@ -83,17 +83,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(p_object)); - if (p_node) { + if (p_object) { if (connections_button->is_pressed()) { connections->show(); } else { groups->show(); } + if (Object::cast_to(p_object)) { + show_connections(); + groups_button->set_disabled(true); + } else { + groups_button->set_disabled(false); + } + mode_hb->show(); select_a_node->hide(); } else { @@ -150,7 +157,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); diff --git a/editor/docks/node_dock.h b/editor/docks/node_dock.h index cf7a67cb39d..380f152e216 100644 --- a/editor/docks/node_dock.h +++ b/editor/docks/node_dock.h @@ -62,7 +62,7 @@ protected: virtual void load_layout_from_config(const Ref &p_layout, const String &p_section) override; public: - void set_node(Node *p_node); + void set_object(Object *p_object); void show_groups(); void show_connections(); diff --git a/editor/docks/scene_tree_dock.cpp b/editor/docks/scene_tree_dock.cpp index 66fc27704e2..7fb32ab0368 100644 --- a/editor/docks/scene_tree_dock.cpp +++ b/editor/docks/scene_tree_dock.cpp @@ -1361,7 +1361,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(); @@ -2861,7 +2861,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() { diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 6096392bfe4..5036f4670ec 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -2673,7 +2673,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(); @@ -2794,7 +2794,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(); @@ -2828,7 +2828,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()); @@ -2858,7 +2858,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); @@ -2870,7 +2870,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); } @@ -2918,7 +2918,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); diff --git a/editor/scene/connections_dialog.cpp b/editor/scene/connections_dialog.cpp index ee680cf8d9e..da3871959b3 100644 --- a/editor/scene/connections_dialog.cpp +++ b/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(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(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(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 &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(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(source)); if (p_cd.target) { - set_dst_node(static_cast(p_cd.target)); + set_dst_node(Object::cast_to(p_cd.target)); set_dst_method(p_cd.method); } @@ -985,7 +991,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(selected_object)->get_node(dst_path); + ERR_FAIL_NULL(target); ConnectDialog::ConnectionData cd; @@ -1078,7 +1085,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()) { @@ -1095,7 +1102,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(p_cd.source); + Object *source = p_cd.source; Node *target = Object::cast_to(p_cd.target); if (!source || !target) { @@ -1119,14 +1126,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. @@ -1154,8 +1161,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(); } @@ -1173,7 +1180,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"))); @@ -1220,19 +1227,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(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")); @@ -1249,8 +1261,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(cd.source); - Node *dst = Object::cast_to(cd.target); + Object *src = cd.source; + Object *dst = cd.target; if (src && dst) { const StringName &signal_name = cd.signal; @@ -1272,7 +1284,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; @@ -1343,6 +1355,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()); } @@ -1510,8 +1523,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(selected_object) != nullptr); update_tree(); } @@ -1522,15 +1536,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