diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2022-10-14 10:19:47 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2022-10-14 10:19:47 +0200 |
commit | 7502c808fa24b22e216051f8399abba2992fe77f (patch) | |
tree | d12656e4d8f3777fe704eb62eff12bfcd40ca436 /editor | |
parent | 95af765f533e7f0f9f997ee1ce4ba70680441b0b (diff) | |
parent | 6a77563b25bd8d71b4b091ba048905e190ee3955 (diff) |
Merge pull request #66665 from Mickeon/editor-do-not-edit-inherited-signals
Do not allow editing Scene-inherited signal connections
Diffstat (limited to 'editor')
-rw-r--r-- | editor/connections_dialog.cpp | 59 | ||||
-rw-r--r-- | editor/connections_dialog.h | 3 |
2 files changed, 58 insertions, 4 deletions
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index 2105a101d8..de7f5c8b88 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -37,6 +37,7 @@ #include "editor/editor_undo_redo_manager.h" #include "editor/scene_tree_dock.h" #include "plugins/script_editor_plugin.h" +#include "scene/resources/packed_scene.h" static Node *_find_first_script(Node *p_root, Node *p_node) { if (p_node != p_root && p_node->get_owner() != p_root) { @@ -733,9 +734,11 @@ void ConnectionsDock::_disconnect_all() { while (child) { Connection connection = child->get_metadata(0); - 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.binds, cd.flags); + 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.binds, cd.flags); + } child = child->get_next(); } @@ -780,6 +783,26 @@ bool ConnectionsDock::_is_item_signal(TreeItem &p_item) { return (p_item.get_parent() == tree->get_root() || p_item.get_parent()->get_parent() == tree->get_root()); } +bool ConnectionsDock::_is_connection_inherited(Connection &p_connection) { + Node *scene_root = EditorNode::get_singleton()->get_edited_scene(); + Ref<PackedScene> scn = ResourceLoader::load(scene_root->get_scene_file_path()); + ERR_FAIL_NULL_V(scn, false); + + Ref<SceneState> state = scn->get_state(); + ERR_FAIL_NULL_V(state, false); + + Node *source = Object::cast_to<Node>(p_connection.signal.get_object()); + Node *target = Object::cast_to<Node>(p_connection.callable.get_object()); + + const NodePath source_path = scene_root->get_path_to(source); + const NodePath target_path = scene_root->get_path_to(target); + const StringName signal_name = p_connection.signal.get_name(); + const StringName method_name = p_connection.callable.get_method(); + + // If it cannot be found in PackedScene, this connection was inherited. + return !state->has_connection(source_path, signal_name, target_path, method_name, true); +} + /* * Open connection dialog with TreeItem data to CREATE a brand-new connection. */ @@ -866,6 +889,19 @@ void ConnectionsDock::_handle_signal_menu_option(int p_option) { } } +void ConnectionsDock::_signal_menu_about_to_popup() { + TreeItem *signal_item = tree->get_selected(); + + bool disable_disconnect_all = true; + for (int i = 0; i < signal_item->get_child_count(); i++) { + if (!signal_item->get_child(i)->has_meta("_inherited_connection")) { + disable_disconnect_all = false; + } + } + + signal_menu->set_item_disabled(slot_menu->get_item_index(DISCONNECT_ALL), disable_disconnect_all); +} + void ConnectionsDock::_handle_slot_menu_option(int p_option) { TreeItem *item = tree->get_selected(); @@ -888,6 +924,13 @@ void ConnectionsDock::_handle_slot_menu_option(int p_option) { } } +void ConnectionsDock::_slot_menu_about_to_popup() { + bool connection_is_inherited = tree->get_selected()->has_meta("_inherited_connection"); + + slot_menu->set_item_disabled(slot_menu->get_item_index(EDIT), connection_is_inherited); + slot_menu->set_item_disabled(slot_menu->get_item_index(DISCONNECT), connection_is_inherited); +} + void ConnectionsDock::_rmb_pressed(Vector2 p_position, MouseButton p_button) { if (p_button != MouseButton::RIGHT) { return; @@ -1001,7 +1044,7 @@ void ConnectionsDock::update_tree() { name = base; } - if (!icon.is_valid()) { + if (icon.is_null()) { icon = get_theme_icon(SNAME("Object"), SNAME("EditorIcons")); } @@ -1133,6 +1176,12 @@ void ConnectionsDock::update_tree() { connection_item->set_text(0, path); connection_item->set_metadata(0, connection); connection_item->set_icon(0, get_theme_icon(SNAME("Slot"), SNAME("EditorIcons"))); + + if (_is_connection_inherited(connection)) { + // The scene inherits this connection. + connection_item->set_custom_color(0, get_theme_color(SNAME("warning_color"), SNAME("Editor"))); + connection_item->set_meta("_inherited_connection", true); + } } } @@ -1185,6 +1234,7 @@ ConnectionsDock::ConnectionsDock() { signal_menu = memnew(PopupMenu); add_child(signal_menu); signal_menu->connect("id_pressed", callable_mp(this, &ConnectionsDock::_handle_signal_menu_option)); + signal_menu->connect("about_to_popup", callable_mp(this, &ConnectionsDock::_signal_menu_about_to_popup)); signal_menu->add_item(TTR("Connect..."), CONNECT); signal_menu->add_item(TTR("Disconnect All"), DISCONNECT_ALL); signal_menu->add_item(TTR("Copy Name"), COPY_NAME); @@ -1192,6 +1242,7 @@ ConnectionsDock::ConnectionsDock() { slot_menu = memnew(PopupMenu); add_child(slot_menu); slot_menu->connect("id_pressed", callable_mp(this, &ConnectionsDock::_handle_slot_menu_option)); + slot_menu->connect("about_to_popup", callable_mp(this, &ConnectionsDock::_slot_menu_about_to_popup)); slot_menu->add_item(TTR("Edit..."), EDIT); slot_menu->add_item(TTR("Go to Method"), GO_TO_SCRIPT); slot_menu->add_item(TTR("Disconnect"), DISCONNECT); diff --git a/editor/connections_dialog.h b/editor/connections_dialog.h index 16a60306aa..126a0ca828 100644 --- a/editor/connections_dialog.h +++ b/editor/connections_dialog.h @@ -212,13 +212,16 @@ class ConnectionsDock : public VBoxContainer { void _tree_item_selected(); void _tree_item_activated(); bool _is_item_signal(TreeItem &p_item); + bool _is_connection_inherited(Connection &p_connection); void _open_connection_dialog(TreeItem &p_item); void _open_connection_dialog(ConnectDialog::ConnectionData p_cd); void _go_to_script(TreeItem &p_item); void _handle_signal_menu_option(int p_option); + void _signal_menu_about_to_popup(); void _handle_slot_menu_option(int p_option); + void _slot_menu_about_to_popup(); void _rmb_pressed(Vector2 p_position, MouseButton p_button); void _close(); |