Implement modal function, e.g. for the loading progress
This commit is contained in:
parent
710c9400a6
commit
3c340ef714
|
@ -282,9 +282,9 @@ checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524"
|
|||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.63"
|
||||
version = "0.1.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eff18d764974428cf3a9328e23fc5c986f5fbed46e6cd4cdf42544df5d297ec1"
|
||||
checksum = "1cd7fce9ba8c3c042128ce72d8b2ddbf3a05747efb67ea0313c635e10bda47a2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -395,9 +395,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
|||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.3.0"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c"
|
||||
checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
|
||||
|
||||
[[package]]
|
||||
name = "cairo-sys-rs"
|
||||
|
@ -439,9 +439,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.78"
|
||||
version = "1.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
|
||||
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
|
||||
|
||||
[[package]]
|
||||
name = "cesu8"
|
||||
|
@ -1281,15 +1281,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.25"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
|
||||
checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608"
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.25"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb"
|
||||
checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531"
|
||||
|
||||
[[package]]
|
||||
name = "futures-lite"
|
||||
|
@ -1308,21 +1308,21 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.25"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
|
||||
checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.25"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
|
||||
checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.25"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
|
||||
checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
|
@ -2059,9 +2059,9 @@ checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
|
|||
|
||||
[[package]]
|
||||
name = "ordered-stream"
|
||||
version = "0.1.3"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4eb9ba3f3e42dbdd3b7b122de5ca169c81e93d561eb900da3a8c99bcfcf381a"
|
||||
checksum = "360a24bdacdb7801a1a6af8500392864791c130ebe8bd9a063158cab00040c90"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"pin-project-lite",
|
||||
|
@ -2075,9 +2075,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
|
|||
|
||||
[[package]]
|
||||
name = "owned_ttf_parser"
|
||||
version = "0.18.0"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a5f3c7ca08b6879e7965fb25e24d1f5eeb32ea73f9ad99b3854778a38c57e93"
|
||||
checksum = "e25e9fb15717794fae58ab55c26e044103aad13186fbb625893f9a3bbcc24228"
|
||||
dependencies = [
|
||||
"ttf-parser",
|
||||
]
|
||||
|
@ -2265,15 +2265,6 @@ dependencies = [
|
|||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "poll-promise"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcf2a02372dfae23c9c01267fb296b8a3413bb4e45fbd589c3ac73c6dcfbb305"
|
||||
dependencies = [
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polling"
|
||||
version = "2.5.2"
|
||||
|
@ -2481,7 +2472,6 @@ dependencies = [
|
|||
"notify-rust",
|
||||
"palette",
|
||||
"plotly",
|
||||
"poll-promise",
|
||||
"rfd",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -2982,9 +2972,9 @@ checksum = "4553f467ac8e3d374bc9a177a26801e5d0f9b211aa1673fb137a403afd1c9cf5"
|
|||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.18.0"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "729bfd096e40da9c001f778f5cdecbd2957929a24e10e5883d9392220a751581"
|
||||
checksum = "56c59d8dd7d0dcbc6428bf7aa2f0e823e26e43b3c9aca15bbc9475d23e5fa12b"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"nom8",
|
||||
|
@ -3114,9 +3104,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.10.0"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a"
|
||||
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
|
@ -3351,9 +3341,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "webbrowser"
|
||||
version = "0.8.6"
|
||||
version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "769f1a8831de12cad7bd6f9693b15b1432d93a151557810f617f626af823acae"
|
||||
checksum = "97d1fa1e5c829b2bf9eb1e28fb950248b797cd6a04866fbdfa8bc31e5eef4c78"
|
||||
dependencies = [
|
||||
"core-foundation",
|
||||
"dirs",
|
||||
|
@ -3720,9 +3710,9 @@ checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
|
|||
|
||||
[[package]]
|
||||
name = "zbus"
|
||||
version = "3.7.0"
|
||||
version = "3.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "379d587c0ccb632d1179cf44082653f682842f0535f0fdfaefffc34849cc855e"
|
||||
checksum = "23eaeb1859a3cd5c5f780b101dfe626bf250a5f34873c3c0226d6d9f7a4d107c"
|
||||
dependencies = [
|
||||
"async-broadcast",
|
||||
"async-executor",
|
||||
|
@ -3758,9 +3748,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zbus_macros"
|
||||
version = "3.7.0"
|
||||
version = "3.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66492a2e90c0df7190583eccb8424aa12eb7ff06edea415a4fff6688fae18cf8"
|
||||
checksum = "e83c1c6d669caa4773ebe8cb2ebea2a8d0c6ea27fc6c5c8916c7308cbf1db3b1"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
|
|
|
@ -139,7 +139,7 @@ pub fn database_plot_entries(
|
|||
if let Some(progress) = &progress {
|
||||
let mut progress_lock = progress.lock().unwrap();
|
||||
(*progress_lock).curr_name = brew.date_time_with_bean(&database);
|
||||
(*progress_lock).current = i;
|
||||
(*progress_lock).current = i+1;
|
||||
(*progress_lock).total = brews.len();
|
||||
(*progress_lock).percentage += step_size;
|
||||
}
|
||||
|
|
628
src/ui.rs
628
src/ui.rs
|
@ -6,6 +6,7 @@ use egui::{
|
|||
plot::{Legend, Line, Plot},
|
||||
Align, Layout, ProgressBar,
|
||||
};
|
||||
use plotly::layout::Center;
|
||||
use rfd::FileDialog;
|
||||
|
||||
use crate::{
|
||||
|
@ -35,11 +36,9 @@ struct LoadingData {
|
|||
#[derive(Default)]
|
||||
pub struct Ui {
|
||||
allowed_to_close: bool,
|
||||
show_confirmation_dialog: bool,
|
||||
|
||||
side_panel_expanded: bool,
|
||||
|
||||
continuous_mode: bool,
|
||||
loading_progress: Arc<Mutex<LoadingProgress>>,
|
||||
loader_thread: Option<JoinHandle<()>>,
|
||||
loading_data: Arc<Mutex<Option<LoadingData>>>,
|
||||
|
@ -57,6 +56,11 @@ pub struct Ui {
|
|||
picked_path: Option<String>,
|
||||
|
||||
plot_entries: HashMap<String, PlotEntry>,
|
||||
|
||||
continuous_mode: bool,
|
||||
modal: bool,
|
||||
show_confirmation_dialog: bool,
|
||||
show_loading_screen: bool,
|
||||
}
|
||||
|
||||
impl Ui {
|
||||
|
@ -91,6 +95,7 @@ impl Ui {
|
|||
|
||||
impl eframe::App for Ui {
|
||||
fn on_close_event(&mut self) -> bool {
|
||||
self.modal = true;
|
||||
self.show_confirmation_dialog = true;
|
||||
self.allowed_to_close
|
||||
}
|
||||
|
@ -101,353 +106,352 @@ impl eframe::App for Ui {
|
|||
}
|
||||
|
||||
self.allowed_to_close = true;
|
||||
|
||||
egui::TopBottomPanel::bottom("status_bar").show(ctx, |ui| {
|
||||
ui.columns(2, |_columns| {});
|
||||
});
|
||||
|
||||
egui::TopBottomPanel::top("dark_light").show(ctx, |ui| {
|
||||
ui.vertical(|ui| {
|
||||
egui::menu::bar(ui, |ui| {
|
||||
if ui
|
||||
.button(match self.side_panel_expanded {
|
||||
true => "<",
|
||||
false => ">",
|
||||
})
|
||||
.clicked()
|
||||
{
|
||||
self.side_panel_expanded = !self.side_panel_expanded;
|
||||
ui.vertical(|ui| {
|
||||
egui::menu::bar(ui, |ui| {
|
||||
let reload_button = ui.button("Reload");
|
||||
|
||||
if reload_button.clicked() {
|
||||
self.reload(ctx);
|
||||
}
|
||||
|
||||
if reload_button.hovered() {
|
||||
if let Some(loader_thread) = &self.loader_thread {
|
||||
if !loader_thread.is_finished() {
|
||||
egui::show_tooltip(ctx, egui::Id::new("reload_tooltip"), |ui| {
|
||||
ui.label("Loading is still in progress.\nTo reload, please wait until previous loading has finished!");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let reload_button = ui.button("Reload");
|
||||
|
||||
if reload_button.clicked() {
|
||||
self.reload(ctx);
|
||||
}
|
||||
|
||||
if reload_button.hovered() {
|
||||
if let Some(loader_thread) = &self.loader_thread {
|
||||
if !loader_thread.is_finished() {
|
||||
egui::show_tooltip(ctx, egui::Id::new("reload_tooltip"), |ui| {
|
||||
ui.label("Loading is still in progress.\nTo reload, please wait until previous loading has finished!");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ui.with_layout(Layout::right_to_left(Align::Min), |ui| {
|
||||
egui::widgets::global_dark_light_mode_buttons(ui);
|
||||
ui.heading("RustyBeans");
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
egui::SidePanel::left("selection_panel")
|
||||
.resizable(true)
|
||||
.show_animated(ctx, self.side_panel_expanded, |ui| {
|
||||
ui.vertical_centered_justified(|ui| {
|
||||
let total_height = ui.available_height();
|
||||
|
||||
ui.horizontal_centered(|ui| {
|
||||
ui.vertical(|ui| {
|
||||
if self.data_loaded {
|
||||
ui.heading("Beans");
|
||||
|
||||
egui::ScrollArea::vertical()
|
||||
.id_source("beans_scroll")
|
||||
.max_height(total_height / 2.0)
|
||||
.show(ui, |ui| {
|
||||
for bean in &self.database.beans {
|
||||
ui.horizontal(|ui| {
|
||||
if ui
|
||||
.radio_value(
|
||||
&mut self.selected_bean,
|
||||
bean.config.uuid.to_owned(),
|
||||
bean.name_with_date(),
|
||||
)
|
||||
.clicked_by(egui::PointerButton::Primary)
|
||||
{
|
||||
if ctx.input(|i| i.modifiers.ctrl) {
|
||||
self.select_all = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
ui.with_layout(Layout::right_to_left(Align::Min), |ui| {
|
||||
egui::widgets::global_dark_light_mode_buttons(ui);
|
||||
ui.heading("RustyBeans");
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
if self.modal {
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
ui.centered_and_justified(|ui| {
|
||||
if self.show_loading_screen {
|
||||
let loading_progress_arc = self.loading_progress.clone();
|
||||
let loading_progress_lock = loading_progress_arc.lock().unwrap();
|
||||
|
||||
ui.add(
|
||||
ProgressBar::new(loading_progress_lock.percentage.to_owned()).text(
|
||||
format!(
|
||||
"{:.0}% | Brew [{}/{}]",
|
||||
loading_progress_lock.percentage * 100.0,
|
||||
loading_progress_lock.current,
|
||||
loading_progress_lock.total
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if let Some(loader_thread) = &self.loader_thread {
|
||||
if loader_thread.is_finished() {
|
||||
self.continuous_mode = false;
|
||||
self.modal = false;
|
||||
self.show_loading_screen = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if self.show_confirmation_dialog {
|
||||
// Show confirmation dialog:
|
||||
ui.separator();
|
||||
ui.vertical(|ui| {
|
||||
if self.data_loaded {
|
||||
if let Some(bean) =
|
||||
&self.database.bean_for_uuid(&self.selected_bean)
|
||||
{
|
||||
let brews = self.database.brews_for_bean(&bean);
|
||||
ui.heading("Brews");
|
||||
ui.label("Really quit?");
|
||||
ui.horizontal(|ui| {
|
||||
if ui.button("Yes").clicked() {
|
||||
self.allowed_to_close = true;
|
||||
frame.close();
|
||||
}
|
||||
|
||||
if ui.button("No").clicked() {
|
||||
self.modal = false;
|
||||
self.show_confirmation_dialog = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
egui::SidePanel::left("selection_panel")
|
||||
.resizable(true)
|
||||
.show_animated(ctx, self.side_panel_expanded, |ui| {
|
||||
ui.vertical_centered_justified(|ui| {
|
||||
let total_height = ui.available_height();
|
||||
|
||||
ui.horizontal_centered(|ui| {
|
||||
ui.vertical(|ui| {
|
||||
if self.data_loaded {
|
||||
ui.heading("Beans");
|
||||
|
||||
egui::ScrollArea::vertical()
|
||||
.id_source("brews_scroll")
|
||||
.id_source("beans_scroll")
|
||||
.max_height(total_height / 2.0)
|
||||
.show(ui, |ui| {
|
||||
for brew in &brews {
|
||||
for bean in &self.database.beans {
|
||||
ui.horizontal(|ui| {
|
||||
if let Some(checked) = self
|
||||
.brew_checkboxes
|
||||
.get_mut(&brew.config.uuid)
|
||||
if ui
|
||||
.radio_value(
|
||||
&mut self.selected_bean,
|
||||
bean.config.uuid.to_owned(),
|
||||
bean.name_with_date(),
|
||||
)
|
||||
.clicked_by(egui::PointerButton::Primary)
|
||||
{
|
||||
if self.select_all {
|
||||
*checked = !*checked;
|
||||
if ctx.input(|i| i.modifiers.ctrl) {
|
||||
self.select_all = true;
|
||||
}
|
||||
|
||||
ui.checkbox(
|
||||
checked,
|
||||
brew.date_time(&self.database),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
self.select_all = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
ui.horizontal_centered(|ui| {
|
||||
ui.vertical(|ui| {
|
||||
if self.data_loaded {
|
||||
ui.heading("Selected Brews");
|
||||
|
||||
egui::ScrollArea::vertical()
|
||||
.id_source("selected_brews_scroll")
|
||||
.max_height(total_height / 2.0)
|
||||
.show(ui, |ui| {
|
||||
if self.clear_all {
|
||||
self.brew_checkboxes.iter_mut().for_each(
|
||||
|brew_checkbox| {
|
||||
*brew_checkbox.1 = false;
|
||||
},
|
||||
);
|
||||
|
||||
self.clear_all = false;
|
||||
} else {
|
||||
for brew in &self.database.brews {
|
||||
if let Some(checked) =
|
||||
self.brew_checkboxes.get_mut(&brew.config.uuid)
|
||||
{
|
||||
if *checked {
|
||||
ui.horizontal(|ui| {
|
||||
if ui
|
||||
.checkbox(
|
||||
checked,
|
||||
brew.date_time_with_bean(
|
||||
&self.database,
|
||||
),
|
||||
)
|
||||
.clicked_by(
|
||||
egui::PointerButton::Primary,
|
||||
)
|
||||
{
|
||||
if ctx.input(|i| i.modifiers.ctrl) {
|
||||
self.clear_all = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
ui.with_layout(Layout::left_to_right(Align::Center), |ui| {
|
||||
ui.with_layout(
|
||||
Layout::left_to_right(Align::Center)
|
||||
.with_cross_align(Align::Center)
|
||||
.with_cross_justify(true),
|
||||
|ui| {
|
||||
if ui
|
||||
.button(match self.side_panel_expanded {
|
||||
true => "<",
|
||||
false => ">",
|
||||
})
|
||||
.clicked()
|
||||
{
|
||||
self.side_panel_expanded = !self.side_panel_expanded;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
ui.with_layout(
|
||||
Layout::top_down(Align::Center).with_main_align(egui::Align::Center),
|
||||
|ui| {
|
||||
if let Some(picked_path) = &self.picked_path {
|
||||
let thread_handle = self.loader_thread.get_or_insert_with(|| {
|
||||
self.continuous_mode = true;
|
||||
|
||||
let loading_data_arc = self.loading_data.clone();
|
||||
let loading_progress_arc = self.loading_progress.clone();
|
||||
let picked_path_owned = picked_path.to_owned();
|
||||
let ctx_clone = ctx.clone();
|
||||
|
||||
thread::spawn(move || {
|
||||
let ctx = ctx_clone;
|
||||
|
||||
let mut loading_data = LoadingData::default();
|
||||
|
||||
loading_data.config = Config::from_file(&picked_path_owned);
|
||||
|
||||
loading_data.database =
|
||||
Database::from_config(&loading_data.config);
|
||||
|
||||
let mut checkboxes = HashMap::new();
|
||||
|
||||
for brew in &loading_data.database.brews {
|
||||
checkboxes.insert(brew.config.uuid.to_owned(), false);
|
||||
}
|
||||
|
||||
loading_data.brew_checkboxes = checkboxes;
|
||||
|
||||
if !&loading_data.database.beans.is_empty() {
|
||||
loading_data.selected_bean =
|
||||
loading_data.database.beans[0].config.uuid.to_owned();
|
||||
}
|
||||
|
||||
loading_data.plot_entries = plot::database_plot_entries(
|
||||
loading_data
|
||||
.database
|
||||
.brews
|
||||
.iter()
|
||||
.map(|brew| brew)
|
||||
.collect(),
|
||||
&loading_data.config,
|
||||
&loading_data.database,
|
||||
Some(loading_progress_arc),
|
||||
);
|
||||
|
||||
let mut loading_data_lock = loading_data_arc.lock().unwrap();
|
||||
*loading_data_lock = Some(loading_data);
|
||||
|
||||
ctx.request_repaint();
|
||||
})
|
||||
});
|
||||
|
||||
if !thread_handle.is_finished() {
|
||||
egui::Window::new("Loading resources")
|
||||
.collapsible(false)
|
||||
.resizable(false)
|
||||
.show(ctx, |ui| {
|
||||
let loading_progress_arc = self.loading_progress.clone();
|
||||
let loading_progress_lock =
|
||||
loading_progress_arc.lock().unwrap();
|
||||
ui.vertical(|ui| {
|
||||
if self.data_loaded {
|
||||
if let Some(bean) =
|
||||
&self.database.bean_for_uuid(&self.selected_bean)
|
||||
{
|
||||
let brews = self.database.brews_for_bean(&bean);
|
||||
ui.heading("Brews");
|
||||
|
||||
ui.add(
|
||||
ProgressBar::new(
|
||||
loading_progress_lock.percentage.to_owned(),
|
||||
)
|
||||
.text(
|
||||
format!(
|
||||
"{:.0}% | Brew [{}/{}]",
|
||||
loading_progress_lock.percentage * 100.0,
|
||||
loading_progress_lock.current,
|
||||
loading_progress_lock.total
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
} else {
|
||||
if self.continuous_mode {
|
||||
self.continuous_mode = false;
|
||||
egui::ScrollArea::vertical()
|
||||
.id_source("brews_scroll")
|
||||
.max_height(total_height / 2.0)
|
||||
.show(ui, |ui| {
|
||||
for brew in &brews {
|
||||
ui.horizontal(|ui| {
|
||||
if let Some(checked) = self
|
||||
.brew_checkboxes
|
||||
.get_mut(&brew.config.uuid)
|
||||
{
|
||||
if self.select_all {
|
||||
*checked = !*checked;
|
||||
}
|
||||
|
||||
ui.checkbox(
|
||||
checked,
|
||||
brew.date_time(&self.database),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
self.select_all = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if !self.data_loaded {
|
||||
self.side_panel_expanded = true;
|
||||
ui.horizontal_centered(|ui| {
|
||||
ui.vertical(|ui| {
|
||||
if self.data_loaded {
|
||||
ui.heading("Selected Brews");
|
||||
|
||||
// println!("loading_data: {:?}", &self.loading_data);
|
||||
let mut loading_data_lock = self.loading_data.lock().unwrap();
|
||||
// println!("loading_data_lock: {:?}", loading_data_lock);
|
||||
let loading_data = loading_data_lock.take().unwrap();
|
||||
egui::ScrollArea::vertical()
|
||||
.id_source("selected_brews_scroll")
|
||||
.max_height(total_height / 2.0)
|
||||
.show(ui, |ui| {
|
||||
if self.clear_all {
|
||||
self.brew_checkboxes.iter_mut().for_each(
|
||||
|brew_checkbox| {
|
||||
*brew_checkbox.1 = false;
|
||||
},
|
||||
);
|
||||
|
||||
self.config = loading_data.config;
|
||||
self.database = loading_data.database;
|
||||
self.brew_checkboxes = loading_data.brew_checkboxes;
|
||||
self.selected_bean = loading_data.selected_bean;
|
||||
self.plot_entries = loading_data.plot_entries;
|
||||
|
||||
self.data_loaded = true;
|
||||
} else {
|
||||
Plot::new("Combined Chart of selected brews")
|
||||
.legend(Legend::default())
|
||||
.show(ui, |plot_ui| {
|
||||
for brew_checkbox in &self.brew_checkboxes {
|
||||
if *brew_checkbox.1 {
|
||||
if let Some(plot_points) =
|
||||
self.plot_entries.get(brew_checkbox.0)
|
||||
self.clear_all = false;
|
||||
} else {
|
||||
for brew in &self.database.brews {
|
||||
if let Some(checked) =
|
||||
self.brew_checkboxes.get_mut(&brew.config.uuid)
|
||||
{
|
||||
plot_ui.line(
|
||||
Line::new(plot_points_to_owned(
|
||||
&plot_points.1,
|
||||
))
|
||||
.name(plot_points.0.to_owned()),
|
||||
);
|
||||
if *checked {
|
||||
ui.horizontal(|ui| {
|
||||
if ui
|
||||
.checkbox(
|
||||
checked,
|
||||
brew.date_time_with_bean(
|
||||
&self.database,
|
||||
),
|
||||
)
|
||||
.clicked_by(
|
||||
egui::PointerButton::Primary,
|
||||
)
|
||||
{
|
||||
if ctx.input(|i| i.modifiers.ctrl) {
|
||||
self.clear_all = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ui.label("Select the config.toml to start");
|
||||
|
||||
if ui.button("Open file").clicked() {
|
||||
if let Some(path) = FileDialog::new()
|
||||
.add_filter("toml", &["toml"])
|
||||
.set_directory(
|
||||
match &env::current_dir() {
|
||||
Ok(path) => path.to_str(),
|
||||
Err(_) => None,
|
||||
}
|
||||
.unwrap_or_default(),
|
||||
)
|
||||
.pick_file()
|
||||
{
|
||||
self.picked_path = Some(path.display().to_string());
|
||||
}
|
||||
}
|
||||
|
||||
if ui.button("Open default config.toml").clicked() {
|
||||
self.picked_path = Some(String::from("config.toml"));
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
if self.show_confirmation_dialog {
|
||||
// Show confirmation dialog:
|
||||
egui::Window::new("Really quit?")
|
||||
.collapsible(false)
|
||||
.resizable(false)
|
||||
.show(ctx, |ui| {
|
||||
ui.horizontal(|ui| {
|
||||
if ui.button("Yes").clicked() {
|
||||
self.allowed_to_close = true;
|
||||
frame.close();
|
||||
}
|
||||
|
||||
if ui.button("No").clicked() {
|
||||
self.show_confirmation_dialog = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
ui.with_layout(Layout::left_to_right(Align::Center), |ui| {
|
||||
ui.with_layout(
|
||||
Layout::left_to_right(Align::Center)
|
||||
.with_cross_align(Align::Center)
|
||||
.with_cross_justify(true),
|
||||
|ui| {
|
||||
if ui
|
||||
.button(match self.side_panel_expanded {
|
||||
true => "<",
|
||||
false => ">",
|
||||
})
|
||||
.clicked()
|
||||
{
|
||||
self.side_panel_expanded = !self.side_panel_expanded;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
ui.with_layout(
|
||||
Layout::top_down(Align::Center).with_main_align(egui::Align::Center),
|
||||
|ui| {
|
||||
if let Some(picked_path) = &self.picked_path {
|
||||
let thread_handle = self.loader_thread.get_or_insert_with(|| {
|
||||
self.continuous_mode = true;
|
||||
self.modal = true;
|
||||
self.show_loading_screen = true;
|
||||
|
||||
let loading_data_arc = self.loading_data.clone();
|
||||
let loading_progress_arc = self.loading_progress.clone();
|
||||
let picked_path_owned = picked_path.to_owned();
|
||||
let ctx_clone = ctx.clone();
|
||||
|
||||
thread::spawn(move || {
|
||||
let ctx = ctx_clone;
|
||||
|
||||
let mut loading_data = LoadingData::default();
|
||||
|
||||
loading_data.config = Config::from_file(&picked_path_owned);
|
||||
|
||||
loading_data.database =
|
||||
Database::from_config(&loading_data.config);
|
||||
|
||||
let mut checkboxes = HashMap::new();
|
||||
|
||||
for brew in &loading_data.database.brews {
|
||||
checkboxes.insert(brew.config.uuid.to_owned(), false);
|
||||
}
|
||||
|
||||
loading_data.brew_checkboxes = checkboxes;
|
||||
|
||||
if !&loading_data.database.beans.is_empty() {
|
||||
loading_data.selected_bean =
|
||||
loading_data.database.beans[0]
|
||||
.config
|
||||
.uuid
|
||||
.to_owned();
|
||||
}
|
||||
|
||||
loading_data.plot_entries = plot::database_plot_entries(
|
||||
loading_data
|
||||
.database
|
||||
.brews
|
||||
.iter()
|
||||
.map(|brew| brew)
|
||||
.collect(),
|
||||
&loading_data.config,
|
||||
&loading_data.database,
|
||||
Some(loading_progress_arc),
|
||||
);
|
||||
|
||||
let mut loading_data_lock =
|
||||
loading_data_arc.lock().unwrap();
|
||||
*loading_data_lock = Some(loading_data);
|
||||
|
||||
ctx.request_repaint();
|
||||
})
|
||||
});
|
||||
|
||||
if thread_handle.is_finished() {
|
||||
if !self.data_loaded {
|
||||
self.side_panel_expanded = true;
|
||||
|
||||
// println!("loading_data: {:?}", &self.loading_data);
|
||||
let mut loading_data_lock =
|
||||
self.loading_data.lock().unwrap();
|
||||
// println!("loading_data_lock: {:?}", loading_data_lock);
|
||||
let loading_data = loading_data_lock.take().unwrap();
|
||||
|
||||
self.config = loading_data.config;
|
||||
self.database = loading_data.database;
|
||||
self.brew_checkboxes = loading_data.brew_checkboxes;
|
||||
self.selected_bean = loading_data.selected_bean;
|
||||
self.plot_entries = loading_data.plot_entries;
|
||||
|
||||
self.data_loaded = true;
|
||||
} else {
|
||||
Plot::new("Combined Chart of selected brews")
|
||||
.legend(Legend::default())
|
||||
.show(ui, |plot_ui| {
|
||||
for brew_checkbox in &self.brew_checkboxes {
|
||||
if *brew_checkbox.1 {
|
||||
if let Some(plot_points) =
|
||||
self.plot_entries.get(brew_checkbox.0)
|
||||
{
|
||||
plot_ui.line(
|
||||
Line::new(plot_points_to_owned(
|
||||
&plot_points.1,
|
||||
))
|
||||
.name(plot_points.0.to_owned()),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ui.label("Select the config.toml to start");
|
||||
|
||||
if ui.button("Open file").clicked() {
|
||||
if let Some(path) = FileDialog::new()
|
||||
.add_filter("toml", &["toml"])
|
||||
.set_directory(
|
||||
match &env::current_dir() {
|
||||
Ok(path) => path.to_str(),
|
||||
Err(_) => None,
|
||||
}
|
||||
.unwrap_or_default(),
|
||||
)
|
||||
.pick_file()
|
||||
{
|
||||
self.picked_path = Some(path.display().to_string());
|
||||
}
|
||||
}
|
||||
|
||||
if ui.button("Open default config.toml").clicked() {
|
||||
self.picked_path = Some(String::from("config.toml"));
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
use yew::prelude::*;
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::database::Database;
|
||||
use crate::plot::database_plot_selected;
|
||||
use crate::plot::database_plot_selected_tui;
|
||||
|
||||
use std::process::Command;
|
||||
|
||||
#[function_component(App)]
|
||||
pub fn plot_component() -> Html {
|
||||
let config = Config::from_default();
|
||||
let database = Database::from_config(&config);
|
||||
|
||||
let plots = database_plot_selected(
|
||||
database
|
||||
.brews
|
||||
.iter()
|
||||
.map(|brew| brew.config.uuid.clone())
|
||||
.collect(),
|
||||
true,
|
||||
);
|
||||
let plot_names: Vec<String> = plots.clone().into_iter().map(|plot| plot.0.clone()).collect();
|
||||
|
||||
let p = yew_hooks::use_async::<_, _, ()>({
|
||||
async move {
|
||||
for plot in &plots {
|
||||
plotly::bindings::new_plot(&plot.0, &plot.1).await;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
});
|
||||
|
||||
use_effect_with_deps(
|
||||
move |_| {
|
||||
p.run();
|
||||
|| ()
|
||||
},
|
||||
(),
|
||||
);
|
||||
|
||||
html! {
|
||||
{
|
||||
for plot_names.into_iter().map(|name| {
|
||||
html!{<div id={name}></div>}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue