Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix conflicted indeterminate state in asset importer #84953

Merged
merged 1 commit into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 40 additions & 12 deletions editor/editor_asset_installer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,23 +54,51 @@ void EditorAssetInstaller::_item_checked_cbk() {
updating_source = true;
TreeItem *item = source_tree->get_edited();
item->propagate_check(0);
_fix_conflicted_indeterminate_state(source_tree->get_root(), 0);
_update_confirm_button();
_rebuild_destination_tree();
updating_source = false;
}

void EditorAssetInstaller::_check_propagated_to_item(Object *p_obj, int p_column) {
TreeItem *affected_item = Object::cast_to<TreeItem>(p_obj);
if (!affected_item) {
return;
// Determine parent state based on non-conflict children, to avoid indeterminate state, and allow toggle dir with conflicts.
bool EditorAssetInstaller::_fix_conflicted_indeterminate_state(TreeItem *p_item, int p_column) {
if (p_item->get_child_count() == 0) {
return false;
}

Dictionary item_meta = affected_item->get_metadata(0);
bool is_conflict = item_meta.get("is_conflict", false);
if (is_conflict) {
affected_item->set_checked(0, false);
affected_item->propagate_check(0, false);
bool all_non_conflict_checked = true;
bool all_non_conflict_unchecked = true;
bool has_conflict_child = false;
bool has_indeterminate_child = false;
TreeItem *child_item = p_item->get_first_child();
while (child_item) {
has_conflict_child |= _fix_conflicted_indeterminate_state(child_item, p_column);
Dictionary child_meta = child_item->get_metadata(p_column);
bool child_conflict = child_meta.get("is_conflict", false);
if (child_conflict) {
child_item->set_checked(p_column, false);
has_conflict_child = true;
} else {
bool child_checked = child_item->is_checked(p_column);
bool child_indeterminate = child_item->is_indeterminate(p_column);
all_non_conflict_checked &= (child_checked || child_indeterminate);
all_non_conflict_unchecked &= !child_checked;
has_indeterminate_child |= child_indeterminate;
}
child_item = child_item->get_next();
}
if (has_indeterminate_child) {
p_item->set_indeterminate(p_column, true);
} else if (all_non_conflict_checked) {
p_item->set_checked(p_column, true);
} else if (all_non_conflict_unchecked) {
p_item->set_checked(p_column, false);
}
if (has_conflict_child) {
p_item->set_custom_color(p_column, get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
} else {
p_item->clear_custom_color(p_column);
}
return has_conflict_child;
}

bool EditorAssetInstaller::_is_item_checked(const String &p_source_path) const {
Expand Down Expand Up @@ -257,6 +285,7 @@ bool EditorAssetInstaller::_update_source_item_status(TreeItem *p_item, const St
}

p_item->propagate_check(0);
_fix_conflicted_indeterminate_state(p_item->get_tree()->get_root(), 0);
return target_exists;
}

Expand Down Expand Up @@ -311,6 +340,7 @@ TreeItem *EditorAssetInstaller::_create_dir_item(Tree *p_tree, TreeItem *p_paren
ti->set_editable(0, true);
ti->set_checked(0, true);
ti->propagate_check(0);
_fix_conflicted_indeterminate_state(ti->get_tree()->get_root(), 0);

Dictionary meta;
meta["asset_path"] = p_path + "/";
Expand Down Expand Up @@ -707,7 +737,6 @@ EditorAssetInstaller::EditorAssetInstaller() {
source_tree = memnew(Tree);
source_tree->set_v_size_flags(Control::SIZE_EXPAND_FILL);
source_tree->connect("item_edited", callable_mp(this, &EditorAssetInstaller::_item_checked_cbk));
source_tree->connect("check_propagated_to_item", callable_mp(this, &EditorAssetInstaller::_check_propagated_to_item));
source_tree_vb->add_child(source_tree);

VBoxContainer *destination_tree_vb = memnew(VBoxContainer);
Expand All @@ -722,7 +751,6 @@ EditorAssetInstaller::EditorAssetInstaller() {
destination_tree = memnew(Tree);
destination_tree->set_v_size_flags(Control::SIZE_EXPAND_FILL);
destination_tree->connect("item_edited", callable_mp(this, &EditorAssetInstaller::_item_checked_cbk));
destination_tree->connect("check_propagated_to_item", callable_mp(this, &EditorAssetInstaller::_check_propagated_to_item));
destination_tree_vb->add_child(destination_tree);

// Dialog configuration.
Expand Down
2 changes: 1 addition & 1 deletion editor/editor_asset_installer.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class EditorAssetInstaller : public ConfirmationDialog {
void _toggle_source_tree(bool p_visible, bool p_scroll_to_error = false);

void _item_checked_cbk();
void _check_propagated_to_item(Object *p_obj, int p_column);
bool _fix_conflicted_indeterminate_state(TreeItem *p_item, int p_column);
bool _is_item_checked(const String &p_source_path) const;

void _install_asset();
Expand Down
Loading