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