Browse Source

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.
Marius Hanl 2 years ago
parent
commit
6f7228e2da
3 changed files with 58 additions and 0 deletions
  1. 3 0
      editor/editor_inspector.cpp
  2. 54 0
      editor/multi_node_edit.cpp
  3. 1 0
      editor/multi_node_edit.h

+ 3 - 0
editor/editor_inspector.cpp

@@ -1655,7 +1655,10 @@ void EditorInspector::update_tree() {
 			StringName classname = object->get_class_name();
 			StringName classname = object->get_class_name();
 			if (object_class != String()) {
 			if (object_class != String()) {
 				classname = object_class;
 				classname = object_class;
+			} else if (Object::cast_to<MultiNodeEdit>(object)) {
+				classname = Object::cast_to<MultiNodeEdit>(object)->get_edited_class_name();
 			}
 			}
+
 			StringName propname = property_prefix + p.name;
 			StringName propname = property_prefix + p.name;
 			String descr;
 			String descr;
 			bool found = false;
 			bool found = false;

+ 54 - 0
editor/multi_node_edit.cpp

@@ -197,6 +197,60 @@ NodePath MultiNodeEdit::get_node(int p_index) const {
 	return nodes[p_index];
 	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<NodePath>::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<NodePath>::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) {
 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);
 	_set_impl(p_property, p_value, p_field);
 }
 }

+ 1 - 0
editor/multi_node_edit.h

@@ -55,6 +55,7 @@ public:
 
 
 	int get_node_count() const;
 	int get_node_count() const;
 	NodePath get_node(int p_index) 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);
 	void set_property_field(const StringName &p_property, const Variant &p_value, const String &p_field);