Recent project and clean shutdowns
This commit is contained in:
4
TODO.md
4
TODO.md
@@ -78,6 +78,8 @@
|
||||
- [ ] Undo / Redo
|
||||
- [x] Close file menu if button clicked
|
||||
- [ ] Allow dragging in project to load them?
|
||||
- [ ] Compress meshes when stored as a project
|
||||
- [ ] Compress meshes when stored as a project?
|
||||
- [ ] Remember the file that was opened for future save operations
|
||||
- [ ] Save on remote thread
|
||||
- [ ] Printer profiles
|
||||
- [x] Save config on quit
|
||||
|
@@ -22,6 +22,26 @@ pub struct ExposureConfig {
|
||||
pub retract_speed: f32,
|
||||
}
|
||||
|
||||
impl Default for SliceConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
platform_resolution: Vector2::new(11_520, 5_120),
|
||||
platform_size: Vector3::new(218.88, 122.904, 260.0),
|
||||
slice_height: 0.05,
|
||||
exposure_config: ExposureConfig {
|
||||
exposure_time: 3.0,
|
||||
..Default::default()
|
||||
},
|
||||
first_exposure_config: ExposureConfig {
|
||||
exposure_time: 30.0,
|
||||
..Default::default()
|
||||
},
|
||||
first_layers: 3,
|
||||
transition_layers: 10,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ExposureConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
|
@@ -1,6 +1,7 @@
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{BufRead, Seek},
|
||||
iter,
|
||||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
thread,
|
||||
@@ -16,9 +17,9 @@ use egui_dock::{DockState, NodeIndex};
|
||||
use egui_phosphor::regular::CARET_RIGHT;
|
||||
use egui_tracing::EventCollector;
|
||||
use image::imageops::FilterType;
|
||||
use nalgebra::{Vector2, Vector3};
|
||||
use itertools::Itertools;
|
||||
use nalgebra::Vector2;
|
||||
use parking_lot::RwLock;
|
||||
use slicer::{slicer::Slicer, Pos};
|
||||
use tracing::{info, warn};
|
||||
|
||||
use crate::{
|
||||
@@ -34,8 +35,9 @@ use crate::{
|
||||
},
|
||||
windows::{self, Tab},
|
||||
};
|
||||
use common::config::{ExposureConfig, SliceConfig};
|
||||
use common::config::SliceConfig;
|
||||
use goo_format::{File as GooFile, LayerEncoder, PreviewImage};
|
||||
use slicer::{slicer::Slicer, Pos};
|
||||
|
||||
pub mod config;
|
||||
pub mod project;
|
||||
@@ -97,21 +99,7 @@ impl App {
|
||||
},
|
||||
config,
|
||||
camera: Camera::default(),
|
||||
slice_config: SliceConfig {
|
||||
platform_resolution: Vector2::new(11_520, 5_120),
|
||||
platform_size: Vector3::new(218.88, 122.904, 260.0),
|
||||
slice_height: 0.05,
|
||||
exposure_config: ExposureConfig {
|
||||
exposure_time: 3.0,
|
||||
..Default::default()
|
||||
},
|
||||
first_exposure_config: ExposureConfig {
|
||||
exposure_time: 30.0,
|
||||
..Default::default()
|
||||
},
|
||||
first_layers: 3,
|
||||
transition_layers: 10,
|
||||
},
|
||||
slice_config: SliceConfig::default(),
|
||||
plugin_manager: PluginManager {
|
||||
plugins: vec![elephant_foot_fixer::get_plugin()],
|
||||
},
|
||||
@@ -235,6 +223,14 @@ impl App {
|
||||
);
|
||||
}
|
||||
|
||||
fn add_recent_project(&mut self, path: PathBuf) {
|
||||
self.config.recent_projects = iter::once(path)
|
||||
.chain(self.config.recent_projects.iter().cloned())
|
||||
.unique()
|
||||
.take(5)
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn save_project(&self, path: &Path) -> Result<()> {
|
||||
let meshes = self.meshes.read();
|
||||
let project = BorrowedProject::new(&meshes, &self.slice_config);
|
||||
@@ -248,8 +244,7 @@ impl App {
|
||||
let mut file = File::open(path)?;
|
||||
let project = OwnedProject::deserialize(&mut file)?;
|
||||
|
||||
self.config.recent_projects.push(path.to_path_buf());
|
||||
|
||||
self.add_recent_project(path.to_path_buf());
|
||||
project.apply(self);
|
||||
Ok(())
|
||||
}
|
||||
|
@@ -1,11 +1,11 @@
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{BufReader, Cursor},
|
||||
process,
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
use const_format::concatcp;
|
||||
use egui::{Button, Context, Key, KeyboardShortcut, Modifiers, TopBottomPanel};
|
||||
use egui::{Button, Context, Key, KeyboardShortcut, Modifiers, TopBottomPanel, ViewportCommand};
|
||||
use egui_phosphor::regular::STACK;
|
||||
use rfd::FileDialog;
|
||||
use tracing::error;
|
||||
@@ -32,7 +32,7 @@ pub fn ui(app: &mut App, ctx: &Context) {
|
||||
ctx.input_mut(|x| x.consume_shortcut(&LOAD_PROJECT_SHORTCUT))
|
||||
.then(|| load(app));
|
||||
ctx.input_mut(|x| x.consume_shortcut(&QUIT_SHORTCUT))
|
||||
.then(quit);
|
||||
.then(|| quit(ctx));
|
||||
ctx.input_mut(|x| x.consume_shortcut(&SLICE_SHORTCUT))
|
||||
.then(|| app.slice());
|
||||
|
||||
@@ -71,11 +71,28 @@ pub fn ui(app: &mut App, ctx: &Context) {
|
||||
);
|
||||
load_project_button.clicked().then(|| load(app));
|
||||
|
||||
ui.add_enabled_ui(!app.config.recent_projects.is_empty(), |ui| {
|
||||
ui.menu_button("Recent Projects", |ui| {
|
||||
let mut load = None;
|
||||
for path in app.config.recent_projects.iter() {
|
||||
let name = path.file_name().unwrap().to_string_lossy();
|
||||
if ui.button(name).clicked() {
|
||||
ui.close_menu();
|
||||
load = Some(path.clone());
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(load) = load {
|
||||
load_project(app, load);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
ui.separator();
|
||||
|
||||
let quit_button =
|
||||
ui.add(Button::new("Quit").shortcut_text(ctx.format_shortcut(&QUIT_SHORTCUT)));
|
||||
quit_button.clicked().then(quit);
|
||||
quit_button.clicked().then(|| quit(ctx));
|
||||
|
||||
// Close the menu if a button is clicked
|
||||
for button in [
|
||||
@@ -146,17 +163,21 @@ fn load(app: &mut App) {
|
||||
.add_filter("mslicer project", &["mslicer"])
|
||||
.pick_file()
|
||||
{
|
||||
if let Err(error) = app.load_project(&path) {
|
||||
error!("Error loading project: {:?}", error);
|
||||
app.popup.open(Popup::simple(
|
||||
"Error Loading Project",
|
||||
PopupIcon::Error,
|
||||
error.to_string(),
|
||||
));
|
||||
}
|
||||
load_project(app, path);
|
||||
}
|
||||
}
|
||||
|
||||
fn quit() {
|
||||
process::exit(0);
|
||||
fn load_project(app: &mut App, path: PathBuf) {
|
||||
if let Err(error) = app.load_project(&path) {
|
||||
error!("Error loading project: {:?}", error);
|
||||
app.popup.open(Popup::simple(
|
||||
"Error Loading Project",
|
||||
PopupIcon::Error,
|
||||
error.to_string(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
fn quit(ctx: &Context) {
|
||||
ctx.send_viewport_cmd(ViewportCommand::Close)
|
||||
}
|
||||
|
Reference in New Issue
Block a user