added notes, improved other features and removed most bugs

This commit is contained in:
2025-07-15 00:40:12 +01:00
parent 35ab726206
commit 76ec44d4e6
18 changed files with 777 additions and 488 deletions
+159
View File
@@ -0,0 +1,159 @@
use egui::RichText;
use crate::{
PROJECT_FOLDER, RightPanelContent,
note::Note,
object::ObjectInstance,
template::{FieldType, Template},
};
pub struct Explorer {}
impl Explorer {
pub fn new() -> Self {
Self {}
}
pub fn ui(&mut self, to_load: &mut Option<RightPanelContent>, ui: &mut egui::Ui) {
let (templates, objects) = match Self::load_templates() {
Ok((templates, objects)) => (templates, objects),
Err(e) => {
eprintln!("Failed to load project: {e}");
ui.label(RichText::new("Failed to load project").color(egui::Color32::RED));
return;
}
};
ui.vertical(|ui| {
egui::collapsing_header::CollapsingState::load_with_default_open(
ui.ctx(),
ui.make_persistent_id("templates"),
true,
)
.show_header(ui, |ui| {
ui.horizontal(|ui| {
ui.label("Templates");
if ui.button("+").clicked() {
*to_load = Some(RightPanelContent::Template {
template: Box::new(Template::default()),
new_field_name: Default::default(),
new_field_type: FieldType::SingleLine,
new_field_required: false,
new_field_description: Default::default(),
});
}
});
})
.body(|ui| {
for template in &templates {
let id = ui.make_persistent_id(template.name.clone());
egui::collapsing_header::CollapsingState::load_with_default_open(
ui.ctx(),
id,
true,
)
.show_header(ui, |ui| {
// load the template
if ui.selectable_label(false, template.name.clone()).clicked() {
*to_load = Some(RightPanelContent::template(Some(template.clone())));
}
// create a new object based on this template
if ui.button("+").clicked() {
*to_load = Some(RightPanelContent::Object {
object: Box::new(ObjectInstance::new(template)),
});
}
})
.body(|ui| {
for object in &objects {
if object.template_id == template.id {
ui.horizontal(|ui| {
ui.add_space(10.0);
// load the object
if ui.selectable_label(false, &object.name).clicked() {
*to_load = Some(RightPanelContent::Object {
object: Box::new(object.clone()),
});
}
});
}
}
});
}
});
let notes = Self::load_notes().unwrap();
egui::collapsing_header::CollapsingState::load_with_default_open(
ui.ctx(),
ui.make_persistent_id("notes"),
true,
)
.show_header(ui, |ui| {
ui.horizontal(|ui| {
ui.label("Notes");
if ui.button("+").clicked() {
*to_load = Some(RightPanelContent::Note {
note: Box::new(Note::default()),
});
}
});
})
.body(|ui| {
for note in &notes {
ui.horizontal(|ui| {
ui.add_space(10.0);
// load the note
if ui.selectable_label(false, &note.name).clicked() {
*to_load = Some(RightPanelContent::Note {
note: Box::new(note.clone()),
});
}
});
}
});
egui::CollapsingHeader::new("Projects").show(ui, |ui| {});
});
}
fn load_templates() -> std::io::Result<(Vec<Template>, Vec<ObjectInstance>)> {
let mut templates = Vec::new();
let mut objects = Vec::new();
for entry in std::fs::read_dir(PROJECT_FOLDER.join("templates")).unwrap() {
let path = entry.unwrap().path();
match Template::load(path.file_stem().unwrap().to_str().unwrap()) {
Ok(t) => templates.push(t),
Err(err) => eprintln!("Could not parse file {path:?}: {err}"),
}
}
for entry in std::fs::read_dir(PROJECT_FOLDER.join("objects")).unwrap() {
let path = entry.unwrap().path();
match ObjectInstance::load(path.file_stem().unwrap().to_str().unwrap()) {
Ok(o) => objects.push(o),
Err(err) => eprintln!("Could not parse file {path:?}: {err}"),
}
}
Ok((templates, objects))
}
fn load_notes() -> std::io::Result<Vec<Note>> {
let mut notes = Vec::new();
for entry in std::fs::read_dir(PROJECT_FOLDER.join("notes")).unwrap() {
let path = entry.unwrap().path();
match Note::load(path.file_stem().unwrap().to_str().unwrap()) {
Ok(note) => notes.push(note),
Err(err) => eprintln!("Could not parse file {path:?}: {err}"),
}
}
Ok(notes)
}
}