reworked file tree
This commit is contained in:
parent
5f3b199684
commit
297f53198f
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "calcifer"
|
||||
version = "1.3.2"
|
||||
version = "1.4.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"categories":[{"name":"to do","content":[{"name":"bug project","description":"when switching tabs between two project file, if item window is open it crashes","id":1},{"name":"update workflow .yml","description":"make a workflow compiling the calcifer and put the linux in calcifer-{version}\nand the windows in calcifer_windows_{version}\n\nupdate nix\nupdate jiji","id":5},{"name":"open dir in tree ?","description":"// Hello there","id":2},{"name":"fix tab title","description":"// Hello there","id":2}]},{"name":"in progress","content":[{"name":"export copy paste fix","description":"// Hello there","id":1}]},{"name":"done","content":[{"name":"move .project file","description":"// Hello there","id":4},{"name":"move config","description":"config from .calcifer/save.json\nto .config/calcifer/state.json","id":1},{"name":"add id to textarea per tab","description":"to improve undo, make each code area of each tab have a unique id (no more undo into another tab)","id":1},{"name":"file tree id ?","description":"// Hello there","id":1}]},{"name":"+","content":[]}]}
|
||||
{"categories":[{"name":"to do","content":[{"name":"bug project","description":"when switching tabs between two project file, if item window is open it crashes","id":1},{"name":"update workflow .yml","description":"make a workflow compiling the calcifer and put the linux in calcifer-{version}\nand the windows in calcifer_windows_{version}\n\nupdate nix\nupdate jiji","id":5},{"name":"fix tab title","description":"// Hello there","id":2}]},{"name":"in progress","content":[{"name":"export copy paste fix","description":"// Hello there","id":1}]},{"name":"done","content":[{"name":"move .project file","description":"// Hello there","id":4},{"name":"move config","description":"config from .calcifer/save.json\nto .config/calcifer/state.json","id":1},{"name":"add id to textarea per tab","description":"to improve undo, make each code area of each tab have a unique id (no more undo into another tab)","id":1},{"name":"file tree id ?","description":"// Hello there","id":1},{"name":"open dir in tree ?","description":"// Hello there","id":2}]},{"name":"+","content":[]}]}
|
|
@ -209,13 +209,13 @@ impl Calcifer {
|
|||
|
||||
if let Some(folder_content) = &file.folder_content {
|
||||
let mut check_for_update: bool = false;
|
||||
let file_id = panels::get_file_id(&file);
|
||||
let file_path_id = panels::get_file_path_id(&file.path);
|
||||
|
||||
let collapsing_response = egui::CollapsingHeader::new(&file.name.clone())
|
||||
.id_source(&file_id)
|
||||
.default_open(self.tree_dir_opened.contains(&file_id))
|
||||
let collapsing_response = egui::CollapsingHeader::new(file.name.clone())
|
||||
.id_source(&file.id)
|
||||
.default_open(self.tree_dir_opened.contains(&file_path_id))
|
||||
.show(ui, |ui| {
|
||||
if !self.tree_dir_opened.contains(&file_id) {
|
||||
if !self.tree_dir_opened.contains(&file_path_id) {
|
||||
return;
|
||||
}
|
||||
for deeper_file in folder_content {
|
||||
|
@ -225,9 +225,9 @@ impl Calcifer {
|
|||
}
|
||||
});
|
||||
if collapsing_response.fully_closed() {
|
||||
self.tree_dir_opened.retain(|s| s != &file_id);
|
||||
} else if !self.tree_dir_opened.contains(&file_id) {
|
||||
self.tree_dir_opened.push(file_id);
|
||||
self.tree_dir_opened.retain(|s| s != &file_path_id);
|
||||
} else if !self.tree_dir_opened.contains(&file_path_id) {
|
||||
self.tree_dir_opened.push(file_path_id);
|
||||
return !file.content_checked;
|
||||
}
|
||||
return check_for_update;
|
||||
|
|
|
@ -53,19 +53,26 @@ impl Calcifer {
|
|||
if !self.tree_visible {
|
||||
return;
|
||||
}
|
||||
egui::SidePanel::left("file_tree_panel").show(ctx, |ui| {
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(format!("Bookshelf ({} files) ", self.n_file_displayed));
|
||||
if ui.button("↺").clicked() {
|
||||
self.file_tree = None;
|
||||
}
|
||||
if ui.button("🗙").clicked() {
|
||||
self.file_tree = None;
|
||||
self.tree_dir_opened = vec![];
|
||||
}
|
||||
});
|
||||
ui.separator();
|
||||
|
||||
let mut init_update : bool = false;
|
||||
if self.file_tree.is_none() {
|
||||
self.file_tree = Some(panels::generate_folder_entry(self.home.as_path()));
|
||||
init_update = true
|
||||
}
|
||||
let mut n_files: usize = 0;
|
||||
egui::SidePanel::left("file_tree_panel").show(ctx, |ui| {
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("Bookshelf ");
|
||||
});
|
||||
ui.separator();
|
||||
ui.label(format!("{} files displayed", self.n_file_displayed));
|
||||
ui.separator();
|
||||
|
||||
egui::ScrollArea::vertical().show(ui, |ui| {
|
||||
if let Some(file_tree) = self.file_tree.clone() {
|
||||
let update_requested = self.list_files(ui, &file_tree, &mut n_files);
|
||||
|
@ -80,8 +87,9 @@ impl Calcifer {
|
|||
}
|
||||
ui.separator();
|
||||
});
|
||||
});
|
||||
|
||||
self.n_file_displayed = n_files;
|
||||
});
|
||||
}
|
||||
|
||||
pub fn draw_bottom_tray(&mut self, ctx: &egui::Context) {
|
||||
|
@ -211,7 +219,7 @@ impl Calcifer {
|
|||
if ui
|
||||
.add(
|
||||
egui::Label::new(
|
||||
egui::RichText::new(" X ").color(color),
|
||||
egui::RichText::new(" ❌ ").color(color),
|
||||
)
|
||||
.sense(egui::Sense::click()),
|
||||
)
|
||||
|
@ -282,6 +290,25 @@ impl Calcifer {
|
|||
panels::send_command(format!("cd {}", path.display()));
|
||||
}
|
||||
|
||||
if ui
|
||||
.add(egui::Button::new("expand tree"))
|
||||
.clicked()
|
||||
{
|
||||
let mut current_path = self.tabs[self.selected_tab].path.clone();
|
||||
current_path.pop();
|
||||
|
||||
while let Some(parent) = current_path.parent() {
|
||||
let dir_id = panels::get_file_path_id(¤t_path);
|
||||
if !self.tree_dir_opened.contains(&dir_id) {
|
||||
self.tree_dir_opened.push(dir_id);
|
||||
}
|
||||
current_path = parent.to_path_buf();
|
||||
}
|
||||
|
||||
self.tree_visible = true;
|
||||
self.file_tree = None;
|
||||
}
|
||||
|
||||
ui.label("Picked file:");
|
||||
ui.monospace(
|
||||
self.tabs[self.selected_tab]
|
||||
|
|
|
@ -211,11 +211,6 @@ impl eframe::App for Calcifer {
|
|||
self.handle_save_file(self.save_tab());
|
||||
}
|
||||
|
||||
if ctx.input(|i| i.key_pressed(egui::Key::T) && i.modifiers.ctrl) {
|
||||
self.file_tree = None;
|
||||
self.tree_dir_opened = vec![];
|
||||
}
|
||||
|
||||
if ctx.input(|i| i.key_pressed(egui::Key::S) && i.modifiers.ctrl && i.modifiers.shift) {
|
||||
self.handle_save_file(self.save_tab_as());
|
||||
}
|
||||
|
|
|
@ -4,6 +4,11 @@ use std::{
|
|||
fs, io,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
use std::hash::DefaultHasher;
|
||||
use std::time::UNIX_EPOCH;
|
||||
use std::time::SystemTime;
|
||||
use std::hash::Hasher;
|
||||
use std::hash::Hash;
|
||||
|
||||
//use crate::ALLOWED_FILE_EXTENSIONS;
|
||||
|
||||
|
@ -13,53 +18,72 @@ pub struct FileEntry {
|
|||
pub path: PathBuf,
|
||||
pub folder_content: Option<Vec<FileEntry>>,
|
||||
pub content_checked: bool,
|
||||
pub id: String,
|
||||
}
|
||||
|
||||
impl FileEntry {
|
||||
pub fn new_entry(name: String, path: PathBuf) -> Self {
|
||||
Self {
|
||||
name,
|
||||
path,
|
||||
path: path.clone(),
|
||||
folder_content: None,
|
||||
content_checked: true,
|
||||
id: Self::generate_unique_id(path),
|
||||
}
|
||||
}
|
||||
pub fn end_of_branch(name: String, path: PathBuf) -> Self {
|
||||
Self {
|
||||
name,
|
||||
path,
|
||||
path: path.clone(),
|
||||
folder_content: Some(vec![]),
|
||||
content_checked: false,
|
||||
id: Self::generate_unique_id(path),
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_unique_id(path: PathBuf) -> String {
|
||||
let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs();
|
||||
|
||||
let mut hasher = DefaultHasher::new();
|
||||
now.hash(&mut hasher);
|
||||
|
||||
let hash = hasher.finish();
|
||||
|
||||
format!("{}#{}", path.display(), hash)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_file_tree(file: FileEntry, opened_dirs: Vec<String>) -> FileEntry {
|
||||
if opened_dirs.contains(&get_file_id(&file)) {
|
||||
if let Some(folder_content) = &file.folder_content {
|
||||
if !file.content_checked {
|
||||
return generate_folder_entry(&file.path);
|
||||
if !opened_dirs.contains(&get_file_path_id(&file.path)) {
|
||||
return file;
|
||||
}
|
||||
|
||||
if !file.content_checked {
|
||||
let folder = generate_folder_entry(&file.path);
|
||||
return update_file_tree(folder, opened_dirs);
|
||||
}
|
||||
|
||||
if file.folder_content.is_none() {
|
||||
return file;
|
||||
}
|
||||
|
||||
let folder_content = file.folder_content.expect("should have checked if none");
|
||||
|
||||
let updated_content: Vec<FileEntry> = folder_content
|
||||
.iter()
|
||||
.map(|entry| update_file_tree(entry.clone(), opened_dirs.clone()))
|
||||
.collect();
|
||||
FileEntry {
|
||||
name: file.name,
|
||||
path: file.path,
|
||||
path: file.path.clone(),
|
||||
folder_content: Some(updated_content),
|
||||
content_checked: true,
|
||||
}
|
||||
} else {
|
||||
file
|
||||
}
|
||||
} else {
|
||||
file
|
||||
id: FileEntry::generate_unique_id(file.path),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_file_id(file: &FileEntry) -> String {
|
||||
format!("#{}",file.path.clone().display())
|
||||
pub fn get_file_path_id(path: &PathBuf) -> String {
|
||||
format!("#{}", path.clone().display())
|
||||
}
|
||||
|
||||
pub fn generate_folder_entry(path: &Path) -> FileEntry {
|
||||
|
@ -106,6 +130,7 @@ pub fn generate_folder_entry(path: &Path) -> FileEntry {
|
|||
path: path.to_path_buf(),
|
||||
folder_content: Some(folder_content),
|
||||
content_checked: true,
|
||||
id: FileEntry::generate_unique_id(path.to_path_buf()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue