mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 05:31:01 +00:00 
			
		
		
		
	Merge pull request #90653 from ajreckof/Fix-going-forward-backward-in-editor-selection-history-
Fix going forward backward in editor selection history.
This commit is contained in:
		
						commit
						c50e80b481
					
				
					 5 changed files with 34 additions and 5 deletions
				
			
		|  | @ -2364,7 +2364,13 @@ static bool overrides_external_editor(Object *p_object) { | ||||||
| 
 | 
 | ||||||
| void EditorNode::_add_to_history(const Object *p_object, const String &p_property, bool p_inspector_only) { | void EditorNode::_add_to_history(const Object *p_object, const String &p_property, bool p_inspector_only) { | ||||||
| 	ObjectID id = p_object->get_instance_id(); | 	ObjectID id = p_object->get_instance_id(); | ||||||
| 	if (id != editor_history.get_current()) { | 	ObjectID history_id = editor_history.get_current(); | ||||||
|  | 	if (id != history_id) { | ||||||
|  | 		const MultiNodeEdit *multi_node_edit = Object::cast_to<const MultiNodeEdit>(p_object); | ||||||
|  | 		const MultiNodeEdit *history_multi_node_edit = Object::cast_to<const MultiNodeEdit>(ObjectDB::get_instance(history_id)); | ||||||
|  | 		if (multi_node_edit && history_multi_node_edit && multi_node_edit->is_same_selection(history_multi_node_edit)) { | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
| 		if (p_inspector_only) { | 		if (p_inspector_only) { | ||||||
| 			editor_history.add_object(id, String(), true); | 			editor_history.add_object(id, String(), true); | ||||||
| 		} else if (p_property.is_empty()) { | 		} else if (p_property.is_empty()) { | ||||||
|  | @ -2458,6 +2464,7 @@ void EditorNode::_edit_current(bool p_skip_foreign, bool p_skip_inspector_update | ||||||
| 		if (current_node->is_inside_tree()) { | 		if (current_node->is_inside_tree()) { | ||||||
| 			NodeDock::get_singleton()->set_node(current_node); | 			NodeDock::get_singleton()->set_node(current_node); | ||||||
| 			SceneTreeDock::get_singleton()->set_selected(current_node); | 			SceneTreeDock::get_singleton()->set_selected(current_node); | ||||||
|  | 			SceneTreeDock::get_singleton()->set_selection({ current_node }); | ||||||
| 			InspectorDock::get_singleton()->update(current_node); | 			InspectorDock::get_singleton()->update(current_node); | ||||||
| 			if (!inspector_only && !skip_main_plugin) { | 			if (!inspector_only && !skip_main_plugin) { | ||||||
| 				skip_main_plugin = stay_in_script_editor_on_node_selected && !ScriptEditor::get_singleton()->is_editor_floating() && ScriptEditor::get_singleton()->is_visible_in_tree(); | 				skip_main_plugin = stay_in_script_editor_on_node_selected && !ScriptEditor::get_singleton()->is_editor_floating() && ScriptEditor::get_singleton()->is_visible_in_tree(); | ||||||
|  | @ -2479,13 +2486,13 @@ void EditorNode::_edit_current(bool p_skip_foreign, bool p_skip_inspector_update | ||||||
| 	} else { | 	} else { | ||||||
| 		Node *selected_node = nullptr; | 		Node *selected_node = nullptr; | ||||||
| 
 | 
 | ||||||
|  | 		Vector<Node *> multi_nodes; | ||||||
| 		if (current_obj->is_class("MultiNodeEdit")) { | 		if (current_obj->is_class("MultiNodeEdit")) { | ||||||
| 			Node *scene = get_edited_scene(); | 			Node *scene = get_edited_scene(); | ||||||
| 			if (scene) { | 			if (scene) { | ||||||
| 				MultiNodeEdit *multi_node_edit = Object::cast_to<MultiNodeEdit>(current_obj); | 				MultiNodeEdit *multi_node_edit = Object::cast_to<MultiNodeEdit>(current_obj); | ||||||
| 				int node_count = multi_node_edit->get_node_count(); | 				int node_count = multi_node_edit->get_node_count(); | ||||||
| 				if (node_count > 0) { | 				if (node_count > 0) { | ||||||
| 					List<Node *> multi_nodes; |  | ||||||
| 					for (int node_index = 0; node_index < node_count; ++node_index) { | 					for (int node_index = 0; node_index < node_count; ++node_index) { | ||||||
| 						Node *node = scene->get_node(multi_node_edit->get_node(node_index)); | 						Node *node = scene->get_node(multi_node_edit->get_node(node_index)); | ||||||
| 						if (node) { | 						if (node) { | ||||||
|  | @ -2495,7 +2502,7 @@ void EditorNode::_edit_current(bool p_skip_foreign, bool p_skip_inspector_update | ||||||
| 					if (!multi_nodes.is_empty()) { | 					if (!multi_nodes.is_empty()) { | ||||||
| 						// Pick the top-most node.
 | 						// Pick the top-most node.
 | ||||||
| 						multi_nodes.sort_custom<Node::Comparator>(); | 						multi_nodes.sort_custom<Node::Comparator>(); | ||||||
| 						selected_node = multi_nodes.front()->get(); | 						selected_node = multi_nodes[0]; | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | @ -2504,6 +2511,7 @@ void EditorNode::_edit_current(bool p_skip_foreign, bool p_skip_inspector_update | ||||||
| 		InspectorDock::get_inspector_singleton()->edit(current_obj); | 		InspectorDock::get_inspector_singleton()->edit(current_obj); | ||||||
| 		NodeDock::get_singleton()->set_node(nullptr); | 		NodeDock::get_singleton()->set_node(nullptr); | ||||||
| 		SceneTreeDock::get_singleton()->set_selected(selected_node); | 		SceneTreeDock::get_singleton()->set_selected(selected_node); | ||||||
|  | 		SceneTreeDock::get_singleton()->set_selection(multi_nodes); | ||||||
| 		InspectorDock::get_singleton()->update(nullptr); | 		InspectorDock::get_singleton()->update(nullptr); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -244,7 +244,7 @@ int MultiNodeEdit::get_node_count() const { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| NodePath MultiNodeEdit::get_node(int p_index) const { | NodePath MultiNodeEdit::get_node(int p_index) const { | ||||||
| 	ERR_FAIL_INDEX_V(p_index, nodes.size(), NodePath()); | 	ERR_FAIL_INDEX_V(p_index, get_node_count(), NodePath()); | ||||||
| 	return nodes[p_index]; | 	return nodes[p_index]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -36,7 +36,7 @@ | ||||||
| class MultiNodeEdit : public RefCounted { | class MultiNodeEdit : public RefCounted { | ||||||
| 	GDCLASS(MultiNodeEdit, RefCounted); | 	GDCLASS(MultiNodeEdit, RefCounted); | ||||||
| 
 | 
 | ||||||
| 	List<NodePath> nodes; | 	LocalVector<NodePath> nodes; | ||||||
| 	struct PLData { | 	struct PLData { | ||||||
| 		int uses = 0; | 		int uses = 0; | ||||||
| 		PropertyInfo info; | 		PropertyInfo info; | ||||||
|  | @ -67,6 +67,19 @@ public: | ||||||
| 
 | 
 | ||||||
| 	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); | ||||||
| 
 | 
 | ||||||
|  | 	// If the nodes selected are the same independently of order then return true.
 | ||||||
|  | 	bool is_same_selection(const MultiNodeEdit *p_other) const { | ||||||
|  | 		if (get_node_count() != p_other->get_node_count()) { | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  | 		for (int i = 0; i < get_node_count(); i++) { | ||||||
|  | 			if (nodes.find(p_other->get_node(i)) == -1) { | ||||||
|  | 				return false; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
| 	MultiNodeEdit(); | 	MultiNodeEdit(); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -3020,6 +3020,13 @@ void SceneTreeDock::set_edited_scene(Node *p_scene) { | ||||||
| 	edited_scene = p_scene; | 	edited_scene = p_scene; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void SceneTreeDock::set_selection(const Vector<Node *> &p_nodes) { | ||||||
|  | 	editor_selection->clear(); | ||||||
|  | 	for (Node *node : p_nodes) { | ||||||
|  | 		editor_selection->add_node(node); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void SceneTreeDock::set_selected(Node *p_node, bool p_emit_selected) { | void SceneTreeDock::set_selected(Node *p_node, bool p_emit_selected) { | ||||||
| 	scene_tree->set_selected(p_node, p_emit_selected); | 	scene_tree->set_selected(p_node, p_emit_selected); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -322,6 +322,7 @@ public: | ||||||
| 	void set_edited_scene(Node *p_scene); | 	void set_edited_scene(Node *p_scene); | ||||||
| 	void instantiate(const String &p_file); | 	void instantiate(const String &p_file); | ||||||
| 	void instantiate_scenes(const Vector<String> &p_files, Node *p_parent = nullptr); | 	void instantiate_scenes(const Vector<String> &p_files, Node *p_parent = nullptr); | ||||||
|  | 	void set_selection(const Vector<Node *> &p_nodes); | ||||||
| 	void set_selected(Node *p_node, bool p_emit_selected = false); | 	void set_selected(Node *p_node, bool p_emit_selected = false); | ||||||
| 	void fill_path_renames(Node *p_node, Node *p_new_parent, HashMap<Node *, NodePath> *p_renames); | 	void fill_path_renames(Node *p_node, Node *p_new_parent, HashMap<Node *, NodePath> *p_renames); | ||||||
| 	void perform_node_renames(Node *p_base, HashMap<Node *, NodePath> *p_renames, HashMap<Ref<Animation>, HashSet<int>> *r_rem_anims = nullptr); | 	void perform_node_renames(Node *p_base, HashMap<Node *, NodePath> *p_renames, HashMap<Ref<Animation>, HashSet<int>> *r_rem_anims = nullptr); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Rémi Verschelde
						Rémi Verschelde