Pārlūkot izejas kodu

Merge pull request #76654 from TokageItLab/improve-filter-util-anim-tree

Add useful functions to `FilterEdit` in `AnimationBlendTreeEditor`
Rémi Verschelde 1 gadu atpakaļ
vecāks
revīzija
0d18a945ca

+ 124 - 1
editor/plugins/animation_blend_tree_editor_plugin.cpp

@@ -623,6 +623,111 @@ void AnimationNodeBlendTreeEditor::_filter_edited() {
 	updating = false;
 }
 
+void AnimationNodeBlendTreeEditor::_filter_fill_selection() {
+	TreeItem *ti = filters->get_root();
+	if (!ti) {
+		return;
+	}
+
+	updating = true;
+	EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
+	undo_redo->create_action(TTR("Fill Selected Filter Children"));
+
+	_filter_fill_selection_recursive(undo_redo, ti, false);
+
+	undo_redo->add_do_method(this, "_update_filters", _filter_edit);
+	undo_redo->add_undo_method(this, "_update_filters", _filter_edit);
+	undo_redo->commit_action();
+	updating = false;
+
+	_update_filters(_filter_edit);
+}
+
+void AnimationNodeBlendTreeEditor::_filter_invert_selection() {
+	TreeItem *ti = filters->get_root();
+	if (!ti) {
+		return;
+	}
+
+	updating = true;
+	EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
+	undo_redo->create_action(TTR("Invert Filter Selection"));
+
+	_filter_invert_selection_recursive(undo_redo, ti);
+
+	undo_redo->add_do_method(this, "_update_filters", _filter_edit);
+	undo_redo->add_undo_method(this, "_update_filters", _filter_edit);
+	undo_redo->commit_action();
+	updating = false;
+
+	_update_filters(_filter_edit);
+}
+
+void AnimationNodeBlendTreeEditor::_filter_clear_selection() {
+	TreeItem *ti = filters->get_root();
+	if (!ti) {
+		return;
+	}
+
+	updating = true;
+	EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton();
+	undo_redo->create_action(TTR("Clear Filter Selection"));
+
+	_filter_clear_selection_recursive(undo_redo, ti);
+
+	undo_redo->add_do_method(this, "_update_filters", _filter_edit);
+	undo_redo->add_undo_method(this, "_update_filters", _filter_edit);
+	undo_redo->commit_action();
+	updating = false;
+
+	_update_filters(_filter_edit);
+}
+
+void AnimationNodeBlendTreeEditor::_filter_fill_selection_recursive(EditorUndoRedoManager *p_undo_redo, TreeItem *p_item, bool p_parent_filtered) {
+	TreeItem *ti = p_item->get_first_child();
+	bool parent_filtered = p_parent_filtered;
+	while (ti) {
+		NodePath item_path = ti->get_metadata(0);
+		bool filtered = _filter_edit->is_path_filtered(item_path);
+		parent_filtered |= filtered;
+
+		p_undo_redo->add_do_method(_filter_edit.ptr(), "set_filter_path", item_path, parent_filtered);
+		p_undo_redo->add_undo_method(_filter_edit.ptr(), "set_filter_path", item_path, filtered);
+
+		_filter_fill_selection_recursive(p_undo_redo, ti, parent_filtered);
+		ti = ti->get_next();
+		parent_filtered = p_parent_filtered;
+	}
+}
+
+void AnimationNodeBlendTreeEditor::_filter_invert_selection_recursive(EditorUndoRedoManager *p_undo_redo, TreeItem *p_item) {
+	TreeItem *ti = p_item->get_first_child();
+	while (ti) {
+		NodePath item_path = ti->get_metadata(0);
+		bool filtered = _filter_edit->is_path_filtered(item_path);
+
+		p_undo_redo->add_do_method(_filter_edit.ptr(), "set_filter_path", item_path, !filtered);
+		p_undo_redo->add_undo_method(_filter_edit.ptr(), "set_filter_path", item_path, filtered);
+
+		_filter_invert_selection_recursive(p_undo_redo, ti);
+		ti = ti->get_next();
+	}
+}
+
+void AnimationNodeBlendTreeEditor::_filter_clear_selection_recursive(EditorUndoRedoManager *p_undo_redo, TreeItem *p_item) {
+	TreeItem *ti = p_item->get_first_child();
+	while (ti) {
+		NodePath item_path = ti->get_metadata(0);
+		bool filtered = _filter_edit->is_path_filtered(item_path);
+
+		p_undo_redo->add_do_method(_filter_edit.ptr(), "set_filter_path", item_path, false);
+		p_undo_redo->add_undo_method(_filter_edit.ptr(), "set_filter_path", item_path, filtered);
+
+		_filter_clear_selection_recursive(p_undo_redo, ti);
+		ti = ti->get_next();
+	}
+}
+
 bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &anode) {
 	if (updating || _filter_edit != anode) {
 		return false;
@@ -1121,10 +1226,28 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() {
 	VBoxContainer *filter_vbox = memnew(VBoxContainer);
 	filter_dialog->add_child(filter_vbox);
 
+	HBoxContainer *filter_hbox = memnew(HBoxContainer);
+	filter_vbox->add_child(filter_hbox);
+
 	filter_enabled = memnew(CheckBox);
 	filter_enabled->set_text(TTR("Enable Filtering"));
 	filter_enabled->connect("pressed", callable_mp(this, &AnimationNodeBlendTreeEditor::_filter_toggled));
-	filter_vbox->add_child(filter_enabled);
+	filter_hbox->add_child(filter_enabled);
+
+	filter_fill_selection = memnew(Button);
+	filter_fill_selection->set_text(TTR("Fill Selected Children"));
+	filter_fill_selection->connect("pressed", callable_mp(this, &AnimationNodeBlendTreeEditor::_filter_fill_selection));
+	filter_hbox->add_child(filter_fill_selection);
+
+	filter_invert_selection = memnew(Button);
+	filter_invert_selection->set_text(TTR("Invert"));
+	filter_invert_selection->connect("pressed", callable_mp(this, &AnimationNodeBlendTreeEditor::_filter_invert_selection));
+	filter_hbox->add_child(filter_invert_selection);
+
+	filter_clear_selection = memnew(Button);
+	filter_clear_selection->set_text(TTR("Clear"));
+	filter_clear_selection->connect("pressed", callable_mp(this, &AnimationNodeBlendTreeEditor::_filter_clear_selection));
+	filter_hbox->add_child(filter_clear_selection);
 
 	filters = memnew(Tree);
 	filter_vbox->add_child(filters);

+ 9 - 0
editor/plugins/animation_blend_tree_editor_plugin.h

@@ -66,6 +66,9 @@ class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin {
 	AcceptDialog *filter_dialog = nullptr;
 	Tree *filters = nullptr;
 	CheckBox *filter_enabled = nullptr;
+	Button *filter_fill_selection = nullptr;
+	Button *filter_invert_selection = nullptr;
+	Button *filter_clear_selection = nullptr;
 
 	HashMap<StringName, ProgressBar *> animations;
 	Vector<EditorProperty *> visible_properties;
@@ -116,6 +119,12 @@ class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin {
 	void _inspect_filters(const String &p_which);
 	void _filter_edited();
 	void _filter_toggled();
+	void _filter_fill_selection();
+	void _filter_invert_selection();
+	void _filter_clear_selection();
+	void _filter_fill_selection_recursive(EditorUndoRedoManager *p_undo_redo, TreeItem *p_item, bool p_parent_filtered);
+	void _filter_invert_selection_recursive(EditorUndoRedoManager *p_undo_redo, TreeItem *p_item);
+	void _filter_clear_selection_recursive(EditorUndoRedoManager *p_undo_redo, TreeItem *p_item);
 	Ref<AnimationNode> _filter_edit;
 
 	void _popup(bool p_has_input_ports, const Vector2 &p_node_position);