use crate::model::{AliasId, Mode, NodeKind, TuiModel};
pub fn handle_toggle(model: &mut TuiModel) {
if model.mode != Mode::Normal && !matches!(model.mode, Mode::Transfer(_)) {
return;
}
if let Some(node) = model.tree.get(model.cursor).cloned() {
if node.kind.is_selectable() {
if let Some(ref id) = node.alias_id {
if !model.selected.remove(id) {
model.selected.insert(id.clone());
}
}
} else {
let child_ids = collect_child_aliases(model, model.cursor);
if !child_ids.is_empty() {
let any_selected = child_ids.iter().any(|id| model.selected.contains(id));
if any_selected {
for id in &child_ids {
model.selected.remove(id);
}
} else {
for id in child_ids {
model.selected.insert(id);
}
}
}
}
}
}
pub(super) fn collect_child_aliases(model: &TuiModel, header_idx: usize) -> Vec<AliasId> {
let mut ids = Vec::new();
let start_kind = &model.tree[header_idx].kind;
for node in model.tree.iter().skip(header_idx + 1) {
match node.kind {
NodeKind::AliasItem | NodeKind::SubcommandItem => {
if let Some(ref id) = node.alias_id {
ids.push(id.clone());
}
}
NodeKind::SubcommandGroupNode => {}
NodeKind::SubcommandProgramHeader => {
if *start_kind != NodeKind::SubcommandGroupNode {
break;
}
}
NodeKind::GlobalHeader | NodeKind::ProjectHeader | NodeKind::ProfileHeader => break,
}
}
ids
}