From 6f7228e2dadff2f777968f671e123c5c0208bfeb Mon Sep 17 00:00:00 2001 From: Marius Hanl Date: Fri, 18 Nov 2022 21:20:36 +0100 Subject: [PATCH] Fix Tooltips do not work properly when selecting multiple nodes (MultiNodeEdit) The editor inspector will now get the edited class name from the MultiNodeEdit when it is used. The name of the selected nodes is searched in the scene and if not found in the parent class(es). This is a mostly clean backport from Godot 4.0. --- editor/editor_inspector.cpp | 3 +++ editor/multi_node_edit.cpp | 54 +++++++++++++++++++++++++++++++++++++ editor/multi_node_edit.h | 1 + 3 files changed, 58 insertions(+) diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 9832db63268..4d2985981c6 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -1655,7 +1655,10 @@ void EditorInspector::update_tree() { StringName classname = object->get_class_name(); if (object_class != String()) { classname = object_class; + } else if (Object::cast_to(object)) { + classname = Object::cast_to(object)->get_edited_class_name(); } + StringName propname = property_prefix + p.name; String descr; bool found = false; diff --git a/editor/multi_node_edit.cpp b/editor/multi_node_edit.cpp index 2cd024a92ee..4bcd52e100c 100644 --- a/editor/multi_node_edit.cpp +++ b/editor/multi_node_edit.cpp @@ -197,6 +197,60 @@ NodePath MultiNodeEdit::get_node(int p_index) const { return nodes[p_index]; } +StringName MultiNodeEdit::get_edited_class_name() const { + Node *es = EditorNode::get_singleton()->get_edited_scene(); + if (!es) { + return StringName("Node"); + } + + // Get the class name of the first node. + StringName class_name; + for (const List::Element *E = nodes.front(); E; E = E->next()) { + Node *node = es->get_node_or_null(E->get()); + if (!node) { + continue; + } + + class_name = node->get_class_name(); + break; + } + + if (class_name == StringName()) { + return StringName("Node"); + } + + bool check_again = true; + while (check_again) { + check_again = false; + + if (class_name == StringName("Node") || class_name == StringName()) { + // All nodes inherit from Node, so no need to continue checking. + return StringName("Node"); + } + + // Check that all nodes inherit from class_name. + for (const List::Element *E = nodes.front(); E; E = E->next()) { + Node *node = es->get_node_or_null(E->get()); + if (!node) { + continue; + } + + const StringName node_class_name = node->get_class_name(); + if (class_name == node_class_name || ClassDB::is_parent_class(node_class_name, class_name)) { + // class_name is the same or a parent of the node's class. + continue; + } + + // class_name is not a parent of the node's class, so check again with the parent class. + class_name = ClassDB::get_parent_class(class_name); + check_again = true; + break; + } + } + + return class_name; +} + void MultiNodeEdit::set_property_field(const StringName &p_property, const Variant &p_value, const String &p_field) { _set_impl(p_property, p_value, p_field); } diff --git a/editor/multi_node_edit.h b/editor/multi_node_edit.h index e5b9d799e99..1602c722e35 100644 --- a/editor/multi_node_edit.h +++ b/editor/multi_node_edit.h @@ -55,6 +55,7 @@ public: int get_node_count() const; NodePath get_node(int p_index) const; + StringName get_edited_class_name() const; void set_property_field(const StringName &p_property, const Variant &p_value, const String &p_field);