use std::ops::DerefMut; use std::sync::Mutex; use eframe::egui::{self}; use plate_tool_lib::plate::PlateFormat; use crate::main_state::{construct_fake_mainstate, MainState}; use crate::plate::{add_plate, PlateUiState}; use crate::transfer_menu::{self, transfer_menu, CurrentTransferState, TransferMenuState}; use crate::tree::tree; #[non_exhaustive] #[derive(Debug, serde::Serialize, serde::Deserialize)] struct MainWindowState { show_side_panel: bool, } impl Default for MainWindowState { fn default() -> Self { Self { show_side_panel: true, } } } #[non_exhaustive] #[derive(Debug, serde::Serialize, serde::Deserialize)] pub struct PlateToolEframe { source_plate_state: Mutex, destination_plate_state: Mutex, main_window_state: MainWindowState, current_transfer_state: CurrentTransferState, #[serde(skip)] transfer_menu_state: TransferMenuState, #[serde(skip)] transfer_region_cache: plate_tool_lib::transfer_region_cache::TransferRegionCache, main_state: MainState, } impl Default for PlateToolEframe { fn default() -> Self { Self { source_plate_state: Mutex::new(PlateUiState::default()), destination_plate_state: Mutex::new(PlateUiState::default()), main_window_state: MainWindowState::default(), current_transfer_state: CurrentTransferState::default(), transfer_menu_state: TransferMenuState::default(), transfer_region_cache: plate_tool_lib::transfer_region_cache::TransferRegionCache::new( ), main_state: construct_fake_mainstate(), } } } impl PlateToolEframe { pub fn new(cc: &eframe::CreationContext<'_>) -> Self { // Would load state here if let Some(storage) = cc.storage { return eframe::get_value(storage, eframe::APP_KEY).unwrap_or_default(); } else { let pte: PlateToolEframe = Default::default(); pte.transfer_region_cache .generate_cache(&pte.main_state.transfers); pte } } } impl eframe::App for PlateToolEframe { // State storage fn save(&mut self, storage: &mut dyn eframe::Storage) { log::info!("Saving state"); eframe::set_value(storage, eframe::APP_KEY, self); } fn update(&mut self, ctx: &eframe::egui::Context, _frame: &mut eframe::Frame) { egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { egui::menu::bar(ui, |ui| { ui.menu_button("File", |ui| { if ui.button("New").clicked() {} ui.menu_button("Export", |ui| { if ui.button("Export as CSV").clicked() {} if ui.button("Export as JSON").clicked() {} }); ui.menu_button("Import", |ui| { if ui.button("Import from JSON").clicked() {} if ui.button("Import transfer from CSV").clicked() {} }); }); ui.menu_button("Options", |ui| { ui.menu_button("Styles", |ui| { if ui.button("Toggle transfer hashes").clicked() {} if ui.button("Toggle volume heatmap").clicked() {} if ui.button("Toggle current coordinates view").clicked() {} }); ui.menu_button("Exports", |ui| { if ui.button("Change CSV export type").clicked() {} }); ui.menu_button("Windows", |ui| { ui.toggle_value( &mut self.main_window_state.show_side_panel, "Toggle side panel", ); }); }); }); }); if self.main_window_state.show_side_panel { egui::SidePanel::left("side_menus").show(ctx, |ui| { ui.vertical(|ui| { tree(ui, &mut self.main_state, &self.current_transfer_state); ui.separator(); transfer_menu( ui, &self.current_transfer_state, &mut self.transfer_menu_state, &mut self.main_state, &self.transfer_region_cache, ); }); }); } // This MUST happen after the menu calls as they can mutate main state let ordered_ids: Vec = { let mut ids: Vec = self .main_state .transfers .clone() .iter() .map(|x| x.id) .collect(); ids.sort_unstable(); ids }; egui::CentralPanel::default().show(ctx, |ui| { ui.vertical(|ui| { let available_size = ui.available_size(); let half_height = { let mut x = available_size; x.y /= 2.0; x }; if self.main_state.get_current_source().is_some() { add_plate( half_height, PlateFormat::W96, &self.main_state.transfers, plate_tool_lib::plate::PlateType::Source, &ordered_ids, &self.transfer_region_cache, Some(&self.current_transfer_state), ui, self.source_plate_state.lock().unwrap().deref_mut(), ); } if self.main_state.get_current_destination().is_some() { add_plate( half_height, PlateFormat::W96, &self.main_state.transfers, plate_tool_lib::plate::PlateType::Destination, &ordered_ids, &self.transfer_region_cache, Some(&self.current_transfer_state), ui, self.destination_plate_state.lock().unwrap().deref_mut(), ); } }); }); } }