ultimate_nag52/config_app/src/window.rs

131 lines
4.0 KiB
Rust
Raw Normal View History

2022-11-14 09:23:07 -08:00
use std::{
borrow::BorrowMut,
collections::VecDeque,
ops::Add,
time::{Duration, Instant},
};
2022-01-27 13:53:52 -08:00
2022-11-14 09:23:07 -08:00
use crate::ui::{
main,
status_bar::{self},
};
use eframe::{
2022-12-04 03:34:55 -08:00
egui::{self, Direction, WidgetText, RichText},
2022-11-14 09:23:07 -08:00
epaint::Pos2,
};
use egui_toast::{Toast, ToastKind, ToastOptions, Toasts};
2022-01-27 13:53:52 -08:00
pub struct MainWindow {
pages: VecDeque<Box<dyn InterfacePage>>,
curr_title: String,
bar: Option<Box<dyn StatusBar>>,
show_back: bool,
}
impl MainWindow {
pub fn new() -> Self {
Self {
pages: VecDeque::new(),
curr_title: "OpenVehicleDiag".into(),
bar: None,
2022-11-14 09:23:07 -08:00
show_back: true,
2022-01-27 13:53:52 -08:00
}
}
pub fn add_new_page(&mut self, p: Box<dyn InterfacePage>) {
if let Some(bar) = p.get_status_bar() {
self.bar = Some(bar)
}
self.pages.push_front(p)
}
pub fn pop_page(&mut self) {
self.pages.pop_front();
if let Some(bar) = self.pages.get_mut(0).map(|x| x.get_status_bar()) {
self.bar = bar
}
}
}
2022-08-01 08:08:19 -07:00
impl eframe::App for MainWindow {
fn update(&mut self, ctx: &eframe::egui::Context, frame: &mut eframe::Frame) {
2022-01-27 13:53:52 -08:00
let stack_size = self.pages.len();
2022-09-19 07:28:31 -07:00
let mut s_bar_height = 0.0;
2022-01-27 13:53:52 -08:00
if stack_size > 0 {
let mut pop_page = false;
if let Some(status_bar) = self.bar.borrow_mut() {
2022-11-14 09:23:07 -08:00
egui::TopBottomPanel::bottom("NAV").show(ctx, |nav| {
nav.horizontal(|row| {
status_bar.draw(row, ctx);
if stack_size > 1 && self.show_back {
if row.button("Back").clicked() {
pop_page = true;
2022-01-27 13:53:52 -08:00
}
2022-11-14 09:23:07 -08:00
}
2022-01-27 13:53:52 -08:00
});
2022-11-14 09:23:07 -08:00
s_bar_height = nav.available_height()
});
2022-01-27 13:53:52 -08:00
}
if pop_page {
self.pop_page();
}
2022-12-04 03:34:55 -08:00
let mut toasts = Toasts::new()
2022-11-14 09:23:07 -08:00
.anchor(Pos2::new(
5.0,
ctx.available_rect().height() - s_bar_height - 5.0,
))
2022-09-19 07:28:31 -07:00
.align_to_end(false)
.direction(Direction::BottomUp);
2022-01-27 13:53:52 -08:00
egui::CentralPanel::default().show(ctx, |main_win_ui| {
match self.pages[0].make_ui(main_win_ui, frame) {
PageAction::None => {}
PageAction::Destroy => self.pop_page(),
PageAction::Add(p) => self.add_new_page(p),
PageAction::Overwrite(p) => {
self.pages[0] = p;
self.bar = self.pages[0].get_status_bar();
}
PageAction::RePaint => ctx.request_repaint(),
PageAction::SetBackButtonState(state) => {
self.show_back = state;
2022-11-14 09:23:07 -08:00
}
2022-09-19 07:28:31 -07:00
PageAction::SendNotification { text, kind } => {
println!("Pushing notification {}", text);
2022-12-04 03:34:55 -08:00
toasts.add(Toast {
2022-11-14 09:23:07 -08:00
kind,
2022-12-04 03:34:55 -08:00
text: WidgetText::RichText(RichText::new(text)),
options: ToastOptions {
2022-11-14 09:23:07 -08:00
show_icon: true,
expires_at: Some(Instant::now().add(Duration::from_secs(5))),
2022-12-04 03:34:55 -08:00
}
});
2022-01-27 13:53:52 -08:00
}
}
});
2022-12-04 03:34:55 -08:00
toasts.show(&ctx);
2022-01-27 13:53:52 -08:00
}
2022-09-19 07:28:31 -07:00
ctx.request_repaint();
2022-01-27 13:53:52 -08:00
}
}
2022-09-19 07:28:31 -07:00
2022-01-27 13:53:52 -08:00
pub enum PageAction {
None,
Destroy,
Add(Box<dyn InterfacePage>),
Overwrite(Box<dyn InterfacePage>),
SetBackButtonState(bool),
RePaint,
2022-09-19 07:28:31 -07:00
SendNotification { text: String, kind: ToastKind },
2022-01-27 13:53:52 -08:00
}
pub trait InterfacePage {
2022-08-01 08:08:19 -07:00
fn make_ui(&mut self, ui: &mut egui::Ui, frame: &eframe::Frame) -> PageAction;
2022-01-27 13:53:52 -08:00
fn get_title(&self) -> &'static str;
fn get_status_bar(&self) -> Option<Box<dyn StatusBar>>;
}
pub trait StatusBar {
2022-04-06 21:34:52 -07:00
fn draw(&mut self, ui: &mut egui::Ui, ctx: &egui::Context);
2022-01-27 13:53:52 -08:00
}