implemented expanding and collapsing directories

main
nick 2024-10-14 15:26:42 -04:00
parent bec3e6b3be
commit 78b5a0e9a8
1 changed files with 49 additions and 25 deletions

View File

@ -80,6 +80,8 @@ impl Directory {
}
pub fn insert(&mut self, name: String, is_file: bool) {
self.selected_mut().expanded = true;
let current_depth = self.selected().depth;
let depth = if self.selected().is_file {
@ -322,8 +324,11 @@ impl Directory {
KeyCode::End => {
self.selection = u16::try_from(self.dirs.len()-1).unwrap_or(u16::MAX);
if self.selection > self.display_start + self.height {
self.display_start = self.selection - self.height
self.display_start = self.selection - self.height;
}
},
KeyCode::Tab if !self.selected().is_file => {
self.selected_mut().expanded ^= true;
}
_ => (),
}
@ -373,38 +378,57 @@ impl Directory {
}
fn display_lines(&self) -> impl Iterator<Item = String> + '_ {
self.dirs.iter().enumerate().scan(
Vec::new(),
|indent_parts, (i, current)| {
let is_last_at_this_depth = is_last_at_this_depth(&self.dirs[i+1..], current.depth);
let (new_part, continue_part) = if is_last_at_this_depth {
(TreePart::Last, TreePart::Blank)
} else {
(TreePart::First, TreePart::Wait)
};
let scan_fn = |(indent_parts, unexpanded_depth): &mut (Vec<TreePart>, Option<u8>), (i, current): (usize, &Item)| -> Option<String> {
if unexpanded_depth.is_some_and(|d| current.depth > d) {
return Some(String::new());
}
if i == 0 { return Some(current.name.clone() + "/") }
if current.expanded {
*unexpanded_depth = None;
} else {
*unexpanded_depth = Some(current.depth);
}
let is_last_at_this_depth = is_last_at_this_depth(&self.dirs[i+1..], current.depth);
let (new_part, continue_part) = if is_last_at_this_depth {
(TreePart::Last, TreePart::Blank)
} else {
(TreePart::First, TreePart::Wait)
};
let mut result = if i == 0 {
String::new()
} else {
if current.depth as usize > indent_parts.len() {
indent_parts.push(continue_part);
} else {
indent_parts[current.depth as usize-1] = continue_part;
}
let result = indent_parts[0 .. current.depth as usize - 1]
.iter()
.fold(String::new(), |result, t| result + t.display())
+ new_part.display()
+ &current.name
+ if current.is_file {
""
} else {
"/"
};
indent_parts[0 .. current.depth as usize - 1]
.iter()
.fold(String::new(), |result, t| result + t.display())
+ new_part.display()
};
Some(result)
result += &current.name;
if !current.is_file {
result += "/";
}
)
if !current.expanded {
result += "...";
};
Some(result)
};
let initial_state = (Vec::new(), None);
self.dirs.iter()
.enumerate()
.scan(initial_state, scan_fn)
.filter(|s| !s.is_empty())
}
}