Error modals

This commit is contained in:
Connor Slade
2024-07-24 19:41:28 -04:00
parent eedcf5929d
commit ff33b0d599
4 changed files with 48 additions and 7 deletions

10
Cargo.lock generated
View File

@@ -1476,6 +1476,15 @@ dependencies = [
"nohash-hasher",
]
[[package]]
name = "egui-modal"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "738cdffefd15dbb6a5fff75d118eee82a9e894bbfa45e41c24d7de42519fa673"
dependencies = [
"egui",
]
[[package]]
name = "egui-phosphor"
version = "0.5.0"
@@ -2710,6 +2719,7 @@ dependencies = [
"const_format",
"eframe",
"egui",
"egui-modal",
"egui-phosphor",
"egui-wgpu",
"egui_dock",

View File

@@ -11,6 +11,7 @@ const_format = "0.2.32"
eframe = { version = "0.27.2", features = ["wgpu"] }
egui = "0.27.2"
egui_dock = "0.12.0"
egui-modal = "0.3.6"
egui-phosphor = "0.5.0"
egui-wgpu = "0.27.2"
encase = { version = "0.8.0", features = ["nalgebra"] }

View File

@@ -3,6 +3,7 @@ use std::{sync::Arc, thread, time::Instant};
use clone_macro::clone;
use eframe::Theme;
use egui_dock::{DockState, NodeIndex};
use egui_modal::{DialogBuilder, Icon, Modal};
use image::imageops::FilterType;
use nalgebra::{Vector2, Vector3};
use parking_lot::RwLock;
@@ -19,11 +20,11 @@ use goo_format::{File as GooFile, LayerEncoder, PreviewImage};
pub struct App {
pub dock_state: DockState<Tab>,
modal: Option<Modal>,
pub camera: Camera,
pub slice_config: SliceConfig,
pub meshes: Arc<RwLock<Vec<RenderedMesh>>>,
pub slice_operation: Option<SliceOperation>,
pub render_style: RenderStyle,
@@ -39,6 +40,16 @@ pub struct FpsTracker {
impl App {
pub fn slice(&mut self) {
if self.meshes.read().is_empty() {
const NO_MODELS_ERROR: &str = "There are no models to slice. Add one by going to File → Open Model or drag and drop a model file into the workspace.";
self.dialog_builder()
.with_title("Slicing Error")
.with_body(NO_MODELS_ERROR)
.with_icon(Icon::Error)
.open();
return;
}
info!("Starting slicing operation");
let slice_config = self.slice_config.clone();
@@ -104,6 +115,10 @@ impl App {
}
));
}
pub fn dialog_builder(&mut self) -> DialogBuilder {
self.modal.as_mut().unwrap().dialog()
}
}
impl eframe::App for App {
@@ -111,6 +126,11 @@ impl eframe::App for App {
ctx.request_repaint();
self.fps.update();
match &mut self.modal {
Some(modal) => modal.show_dialog(),
None => self.modal = Some(Modal::new(ctx, "modal")),
}
windows::ui(self, ctx);
}
}
@@ -145,6 +165,8 @@ impl Default for App {
Self {
dock_state,
modal: None,
camera: Camera::default(),
slice_config: SliceConfig {
platform_resolution: Vector2::new(11_520, 5_120),
@@ -164,10 +186,9 @@ impl Default for App {
fps: FpsTracker::new(),
meshes: Arc::new(RwLock::new(Vec::new())),
render_style: RenderStyle::Normals,
render_style: RenderStyle::Rended,
theme: Theme::Dark,
grid_size: 12.16,
slice_operation: None,
}
}

View File

@@ -1,6 +1,7 @@
use std::{fs::File, io::BufReader};
use egui::{Align, Context, Layout, TopBottomPanel};
use egui_modal::Icon;
use rfd::FileDialog;
use tracing::info;
@@ -22,13 +23,21 @@ pub fn ui(app: &mut App, ctx: &Context) {
{
let name = path.file_name().unwrap().to_str().unwrap().to_string();
let ext = path.extension();
let format = ext
.expect("Selected file has no extension")
.to_string_lossy();
let format = ext.unwrap_or_default().to_string_lossy();
let file = File::open(&path).unwrap();
let mut buf = BufReader::new(file);
let model = slicer::mesh::load_mesh(&mut buf, &format).unwrap();
let model = match slicer::mesh::load_mesh(&mut buf, &format) {
Ok(model) => model,
Err(err) => {
app.dialog_builder()
.with_title("Import Error")
.with_body(format!("Failed to import model.\n{err}"))
.with_icon(Icon::Error)
.open();
return;
}
};
info!("Loaded model `{name}` with {} faces", model.faces.len());
app.meshes.write().push(