use iced::Task;
use super::DirectoryTree;
use super::message::DirectoryTreeEvent;
mod on_drag;
mod on_loaded;
mod on_selected;
mod on_toggled;
impl DirectoryTree {
pub fn update(&mut self, msg: DirectoryTreeEvent) -> Task<DirectoryTreeEvent> {
match msg {
DirectoryTreeEvent::Toggled(path) => self.on_toggled(path),
DirectoryTreeEvent::Selected(path, is_dir, mode) => {
self.on_selected(path, is_dir, mode);
Task::none()
}
DirectoryTreeEvent::Drag(msg) => self.on_drag(msg),
DirectoryTreeEvent::DragCompleted { .. } => Task::none(),
DirectoryTreeEvent::Loaded(payload) => {
let targets = self.on_loaded(payload);
self.issue_prefetch_scans(targets)
}
}
}
fn issue_prefetch_scans(
&mut self,
targets: Vec<std::path::PathBuf>,
) -> Task<DirectoryTreeEvent> {
if targets.is_empty() {
return Task::none();
}
let tasks: Vec<Task<DirectoryTreeEvent>> = targets
.into_iter()
.map(|p| {
self.generation = self.generation.wrapping_add(1);
self.prefetching_paths.insert(p.clone());
let depth = depth_of(&self.config.root_path, &p);
super::walker::scan(self.executor.clone(), p, self.generation, depth)
})
.collect();
Task::batch(tasks)
}
}
pub(super) fn depth_of(root: &std::path::Path, path: &std::path::Path) -> u32 {
let Ok(rel) = path.strip_prefix(root) else {
return u32::MAX;
};
rel.components().count() as u32
}
impl DirectoryTree {
#[doc(hidden)]
pub fn __test_expand_blocking(&mut self, path: std::path::PathBuf) {
self.__expand_blocking_impl(path.clone(), true);
let targets = self.select_prefetch_targets(&path);
for t in targets {
self.prefetching_paths.insert(t.clone());
self.__expand_blocking_impl(t, false);
}
}
fn __expand_blocking_impl(&mut self, path: std::path::PathBuf, flip_expanded: bool) {
use super::message::LoadPayload;
use std::sync::Arc;
let depth = depth_of(&self.config.root_path, &path);
let result = swdir::scan_dir(&path)
.as_ref()
.map(|e| super::walker::normalize_entries(e))
.map_err(crate::Error::from);
self.generation = self.generation.wrapping_add(1);
let payload = LoadPayload {
path: path.clone(),
generation: self.generation,
depth,
result: Arc::new(result),
};
if flip_expanded
&& let Some(node) = self.root.find_mut(&path)
&& node.is_dir
{
node.is_expanded = true;
}
let _targets = self.on_loaded(payload);
}
}
#[cfg(test)]
mod tests;