lapce/lapce-data/src/explorer.rs

185 lines
5.4 KiB
Rust
Raw Normal View History

2022-03-21 10:53:55 +00:00
use std::collections::HashMap;
use std::path::Path;
use std::path::PathBuf;
use std::sync::Arc;
use druid::ExtEventSink;
use druid::{Target, WidgetId};
use include_dir::{include_dir, Dir};
use lapce_proxy::dispatch::FileNodeItem;
use crate::proxy::LapceProxy;
use crate::state::LapceWorkspace;
use crate::{command::LapceUICommand, command::LAPCE_UI_COMMAND};
#[allow(dead_code)]
const ICONS_DIR: Dir = include_dir!("../icons");
#[derive(Clone)]
pub struct FileExplorerData {
pub tab_id: WidgetId,
pub widget_id: WidgetId,
pub workspace: Option<FileNodeItem>,
pub index: usize,
#[allow(dead_code)]
count: usize,
}
impl FileExplorerData {
pub fn new(
tab_id: WidgetId,
workspace: LapceWorkspace,
proxy: Arc<LapceProxy>,
event_sink: ExtEventSink,
) -> Self {
let mut items = Vec::new();
let widget_id = WidgetId::next();
if let Some(path) = workspace.path.as_ref() {
items.push(FileNodeItem {
path_buf: path.clone(),
is_dir: true,
read: false,
open: false,
children: HashMap::new(),
children_open_count: 0,
});
let index = 0;
let path = path.clone();
std::thread::spawn(move || {
proxy.read_dir(
&path.clone(),
Box::new(move |result| {
if let Ok(res) = result {
let resp: Result<Vec<FileNodeItem>, serde_json::Error> =
serde_json::from_value(res);
if let Ok(items) = resp {
let _ = event_sink.submit_command(
LAPCE_UI_COMMAND,
LapceUICommand::UpdateExplorerItems(
index,
path.clone(),
items,
),
Target::Widget(tab_id),
);
}
}
}),
);
});
}
Self {
tab_id,
widget_id,
workspace: workspace.path.as_ref().map(|p| FileNodeItem {
path_buf: p.clone(),
is_dir: true,
read: false,
open: false,
children: HashMap::new(),
children_open_count: 0,
}),
index: 0,
count: 0,
}
}
pub fn update_node_count(&mut self, path: &Path) -> Option<()> {
let node = self.get_node_mut(path)?;
if node.is_dir {
if node.open {
node.children_open_count = node
.children
.iter()
.map(|(_, item)| item.children_open_count + 1)
.sum::<usize>();
} else {
node.children_open_count = 0;
}
}
None
}
pub fn node_tree(&mut self, path: &Path) -> Option<Vec<PathBuf>> {
let root = &self.workspace.as_ref()?.path_buf;
let path = path.strip_prefix(root).ok()?;
Some(
path.ancestors()
.map(|p| root.join(p))
.collect::<Vec<PathBuf>>(),
)
}
pub fn get_node_by_index(&mut self, index: usize) -> Option<&mut FileNodeItem> {
let (_, node) = get_item_children_mut(0, index, self.workspace.as_mut()?);
node
}
pub fn get_node_mut(&mut self, path: &Path) -> Option<&mut FileNodeItem> {
let mut node = self.workspace.as_mut()?;
if node.path_buf == path {
return Some(node);
}
let root = node.path_buf.clone();
let path = path.strip_prefix(&root).ok()?;
for path in path.ancestors().collect::<Vec<&Path>>().iter().rev() {
if path.to_str()?.is_empty() {
continue;
}
node = node.children.get_mut(&root.join(path))?;
}
Some(node)
}
}
pub fn get_item_children(
i: usize,
index: usize,
item: &FileNodeItem,
) -> (usize, Option<&FileNodeItem>) {
if i == index {
return (i, Some(item));
}
let mut i = i;
if item.open {
for child in item.sorted_children() {
let count = child.children_open_count;
if i + count + 1 >= index {
let (new_index, node) = get_item_children(i + 1, index, child);
if new_index == index {
return (new_index, node);
}
}
i += count + 1;
}
}
(i, None)
}
pub fn get_item_children_mut(
i: usize,
index: usize,
item: &mut FileNodeItem,
) -> (usize, Option<&mut FileNodeItem>) {
if i == index {
return (i, Some(item));
}
let mut i = i;
if item.open {
for child in item.sorted_children_mut() {
let count = child.children_open_count;
if i + count + 1 >= index {
let (new_index, node) = get_item_children_mut(i + 1, index, child);
if new_index == index {
return (new_index, node);
}
}
i += count + 1;
}
}
(i, None)
}