You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
postsack/ps-gui/src/app_state/main.rs

130 lines
4.1 KiB
Rust

use eframe::egui::{self, Stroke};
use ps_core::eyre::{Report, Result};
use super::super::widgets::{FilterState, Spinner};
use super::Textures;
use super::{StateUIAction, StateUIVariant};
use ps_core::{model::Engine, Config, DatabaseLike};
#[derive(Default)]
pub struct UIState {
pub show_emails: bool,
pub show_filters: bool,
pub show_export: bool,
pub action_close: bool,
}
pub struct MainUI {
config: Config,
engine: Engine,
error: Option<Report>,
state: UIState,
filter_state: FilterState,
total: usize,
}
impl MainUI {
pub fn new<Database: DatabaseLike>(config: Config, total: usize) -> Result<Self> {
let mut engine = Engine::new::<Database>(&config)?;
engine.start()?;
Ok(Self {
config,
engine,
error: None,
state: UIState::default(),
filter_state: FilterState::new(),
total,
})
}
}
impl StateUIVariant for MainUI {
fn update_panel(
&mut self,
ctx: &egui::CtxRef,
_textures: &Option<Textures>,
) -> super::StateUIAction {
// Avoid any processing if there is an unhandled error.
if self.error.is_none() {
self.error = self.engine.process().err();
}
let platform_colors = super::super::platform::platform_colors();
let frame = egui::containers::Frame::none()
.fill(platform_colors.window_background)
.stroke(Stroke::none());
egui::TopBottomPanel::top("panel")
.frame(frame)
.show(ctx, |ui| {
ui.add(super::super::navigation_bar::NavigationBar::new(
&mut self.engine,
&mut self.error,
&mut self.state,
&mut self.filter_state,
self.total,
));
});
if self.state.show_emails {
egui::SidePanel::right("left_panel")
.default_width(500.0)
.show(ctx, |ui| {
ui.add(super::super::mail_panel::MailPanel::new(
&mut self.engine,
&mut self.error,
));
});
}
egui::CentralPanel::default()
.frame(egui::containers::Frame::none())
.show(ctx, |ui| {
if self.engine.segmentations().is_empty() {
ui.centered_and_justified(|ui| {
ui.add(Spinner::new(egui::vec2(50.0, 50.0)));
});
} else {
let stroke = Stroke::none();
let fill = platform_colors.content_background;
super::super::widgets::background::color_background(
ui,
15.0,
stroke,
fill,
|ui| {
ui.vertical(|ui: &mut egui::Ui| {
ui.add(super::super::segmentation_bar::SegmentationBar::new(
&mut self.engine,
&mut self.error,
));
ui.add(super::super::widgets::Rectangles::new(
&mut self.engine,
&mut self.error,
));
})
.response
},
);
}
});
// If we're waiting for a computation to succeed, we re-render again.
if self.engine.is_busy() {
ctx.request_repaint();
}
match (self.state.action_close, self.error.take()) {
(_, Some(error)) => StateUIAction::Error {
report: error,
config: self.config.clone(),
},
(true, _) => StateUIAction::Close {
config: self.config.clone(),
},
_ => StateUIAction::Nothing,
}
}
}