diff --git a/editor/project_export.cpp b/editor/project_export.cpp index e8c2b1f9547..75509c75448 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -721,14 +721,19 @@ void ProjectExportDialog::_fill_resource_tree() { } bool ProjectExportDialog::_fill_tree(EditorFileSystemDirectory *p_dir, TreeItem *p_item, Ref ¤t, bool p_only_scenes) { + p_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); p_item->set_icon(0, presets->get_theme_icon("folder", "FileDialog")); p_item->set_text(0, p_dir->get_name() + "/"); + p_item->set_editable(0, true); + p_item->set_metadata(0, p_dir->get_path()); bool used = false; + bool checked = true; for (int i = 0; i < p_dir->get_subdir_count(); i++) { TreeItem *subdir = include_files->create_item(p_item); if (_fill_tree(p_dir->get_subdir(i), subdir, current, p_only_scenes)) { used = true; + checked = checked && subdir->is_checked(0); } else { memdelete(subdir); } @@ -750,10 +755,12 @@ bool ProjectExportDialog::_fill_tree(EditorFileSystemDirectory *p_dir, TreeItem file->set_editable(0, true); file->set_checked(0, current->has_export_file(path)); file->set_metadata(0, path); + checked = checked && file->is_checked(0); used = true; } + p_item->set_checked(0, checked); return used; } @@ -775,11 +782,51 @@ void ProjectExportDialog::_tree_changed() { String path = item->get_metadata(0); bool added = item->is_checked(0); - if (added) { - current->add_export_file(path); + if (path.ends_with("/")) { + _check_dir_recursive(item, added); } else { - current->remove_export_file(path); + if (added) { + current->add_export_file(path); + } else { + current->remove_export_file(path); + } } + _refresh_parent_checks(item); // Makes parent folder checked if all files/folders are checked. +} + +void ProjectExportDialog::_check_dir_recursive(TreeItem *p_dir, bool p_checked) { + for (TreeItem *child = p_dir->get_children(); child; child = child->get_next()) { + String path = child->get_metadata(0); + + child->set_checked(0, p_checked); + if (path.ends_with("/")) { + _check_dir_recursive(child, p_checked); + } else { + if (p_checked) { + get_current_preset()->add_export_file(path); + } else { + get_current_preset()->remove_export_file(path); + } + } + } +} + +void ProjectExportDialog::_refresh_parent_checks(TreeItem *p_item) { + TreeItem *parent = p_item->get_parent(); + if (!parent) { + return; + } + + bool checked = true; + for (TreeItem *child = parent->get_children(); child; child = child->get_next()) { + checked = checked && child->is_checked(0); + if (!checked) { + break; + } + } + parent->set_checked(0, checked); + + _refresh_parent_checks(parent); } void ProjectExportDialog::_export_pck_zip() { diff --git a/editor/project_export.h b/editor/project_export.h index 026daac2ad9..b8ca0dd9f2b 100644 --- a/editor/project_export.h +++ b/editor/project_export.h @@ -123,6 +123,8 @@ private: void _fill_resource_tree(); bool _fill_tree(EditorFileSystemDirectory *p_dir, TreeItem *p_item, Ref ¤t, bool p_only_scenes); void _tree_changed(); + void _check_dir_recursive(TreeItem *p_dir, bool p_checked); + void _refresh_parent_checks(TreeItem *p_item); Variant get_drag_data_fw(const Point2 &p_point, Control *p_from); bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;