diff --git a/plate-tool-eframe/src/app.rs b/plate-tool-eframe/src/app.rs index 05eda8c..d660ebf 100644 --- a/plate-tool-eframe/src/app.rs +++ b/plate-tool-eframe/src/app.rs @@ -5,9 +5,9 @@ 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::main_state::{MainState, construct_fake_mainstate}; use crate::tree::tree; #[non_exhaustive] @@ -60,11 +60,11 @@ impl PlateToolEframe { 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.transfer_region_cache + .generate_cache(&pte.main_state.transfers); pte } - } } @@ -76,18 +76,6 @@ impl eframe::App for PlateToolEframe { } fn update(&mut self, ctx: &eframe::egui::Context, _frame: &mut eframe::Frame) { - let ordered_ids: Vec = { - let mut ids: Vec = self - .main_state - .transfers - .clone() - .iter() - .map(|x| x.id) - .collect(); - ids.sort_unstable(); - ids - }; - egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { egui::menu::bar(ui, |ui| { ui.menu_button("File", |ui| { @@ -125,11 +113,29 @@ impl eframe::App for PlateToolEframe { 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); + 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(); @@ -138,28 +144,32 @@ impl eframe::App for PlateToolEframe { x.y /= 2.0; x }; - 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(), - ); - 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(), - ); + 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(), + ); + } }); }); } diff --git a/plate-tool-eframe/src/plate.rs b/plate-tool-eframe/src/plate.rs index 382b912..b2d40ad 100644 --- a/plate-tool-eframe/src/plate.rs +++ b/plate-tool-eframe/src/plate.rs @@ -142,8 +142,8 @@ fn calculate_shading_for_wells( }; if let Some(wells) = cache_result { for well in wells.iter().filter(|x| x.row <= rows && x.col <= columns) { - if let Some(mut x) = - well_infos[(well.row - 1) as usize * columns as usize + (well.col - 1) as usize] + if let Some(Some(mut x)) = well_infos + .get_mut((well.row - 1) as usize * columns as usize + (well.col - 1) as usize) { x.volume += 5.0; x.color = PALETTE.get_ordered(transfer.id, ordered_ids); diff --git a/plate-tool-eframe/src/transfer_menu.rs b/plate-tool-eframe/src/transfer_menu.rs index b92a6a9..5797cd5 100644 --- a/plate-tool-eframe/src/transfer_menu.rs +++ b/plate-tool-eframe/src/transfer_menu.rs @@ -1,9 +1,9 @@ use eframe::egui; use plate_tool_lib::transfer_region::{self, Region, TransferRegion}; -use std::sync::{Arc, Mutex}; use std::hash::{DefaultHasher, Hash, Hasher}; +use std::sync::{Arc, Mutex}; -use crate::main_state::MainState; +use crate::main_state::{self, MainState}; pub type CurrentTransferState = Arc>; #[derive(Debug, serde::Serialize, serde::Deserialize)] @@ -99,21 +99,27 @@ impl CurrentTransferStateInterior { dest_plate: self.destination_plate, dest_region: self.destination_region.clone(), interleave_source: (self.source_row_interleave, self.source_column_interleave), - interleave_dest: (self.destination_row_interleave, self.destination_column_interleave), + interleave_dest: ( + self.destination_row_interleave, + self.destination_column_interleave, + ), } } pub fn try_new_from_main_state_transfer(ms: &MainState) -> Option { let transfer_id = ms.get_current_transfer(); - let transfer = ms.transfers.iter().find(|x| Some(x.get_uuid()) == transfer_id); + let transfer = ms + .transfers + .iter() + .find(|x| Some(x.get_uuid()) == transfer_id); if let Some(transfer) = transfer { let volume: f32 = match transfer.volume { plate_tool_lib::transfer_volume::TransferVolume::Single(x) => x, plate_tool_lib::transfer_volume::TransferVolume::WellMap(_) => { log::debug!("COOL BUG: I genuinely don't know when this variant is used and honestly assume that it just never is constructed! Anyway, here's main state:\n{:?}", ms); unreachable!("It better not!"); - }, - _ => unreachable!() + } + _ => unreachable!(), }; return Some(Self { transfer_name: transfer.name.clone(), @@ -129,10 +135,24 @@ impl CurrentTransferStateInterior { source_wells: None, destination_wells: None, transfer_hash: None, - }) + }); } None } + + pub fn convert_to_transfer(&self, ms: &MainState) -> Option { + let source_plate_uuid = ms.get_current_source()?; + let destination_plate_uuid = ms.get_current_destination()?; + let source_plate_instance = ms.source_plates.iter().find(|x| x.get_uuid() == source_plate_uuid)?; + let destination_plate_instance = ms.destination_plates.iter().find(|x| x.get_uuid() == destination_plate_uuid)?; + let transfer = Some(plate_tool_lib::transfer::Transfer::new( + source_plate_instance.clone(), + destination_plate_instance.clone(), + self.generate_transfer_region(), + self.transfer_name.clone(), + )); + transfer.map(|mut x| {x.volume = plate_tool_lib::transfer_volume::TransferVolume::Single(self.volume); x}) + } } #[derive(Debug)] @@ -165,6 +185,8 @@ pub fn transfer_menu( ui: &mut egui::Ui, state: &CurrentTransferState, ui_state: &mut TransferMenuState, + main_state: &mut MainState, + transfer_region_cache: &plate_tool_lib::transfer_region_cache::TransferRegionCache, ) { // Can we reduce the length of this lock pls let mut state = state.lock().unwrap(); @@ -258,4 +280,30 @@ pub fn transfer_menu( ); }); }); + + ui.horizontal(|ui| { + if ui.button("Save").clicked() { + if let Some(transfer_uuid) = main_state.get_current_transfer() { + log::info!("should change transfer"); + if let Some(mut transfer) = main_state.transfers.iter_mut().find(|x| x.id == transfer_uuid) { + transfer.transfer_region = state.generate_transfer_region(); + transfer.name = state.transfer_name.clone(); + transfer_region_cache.invalidate(&transfer); + } + } else { + let new_transfer = state.convert_to_transfer(main_state); + log::info!("{:?}", new_transfer); + if let Some(new_transfer) = new_transfer { + main_state.transfers.push(new_transfer); + let new_transfer = main_state.transfers.last() + .expect("Cannot be empty, just added a transfer"); + transfer_region_cache.add_overwrite(new_transfer); + } + } + } + if ui.button("New").clicked() { + *state = CurrentTransferStateInterior::default(); + main_state.set_no_current_transfer(); + } + }); }