Edit transfers

This commit is contained in:
Emilia Allison 2025-01-11 09:51:52 -05:00
parent 949822f26c
commit 2ea2963b22
Signed by: emilia
GPG Key ID: 05D5D1107E5100A1
3 changed files with 105 additions and 47 deletions

View File

@ -5,9 +5,9 @@ use eframe::egui::{self};
use plate_tool_lib::plate::PlateFormat; use plate_tool_lib::plate::PlateFormat;
use crate::main_state::{construct_fake_mainstate, MainState};
use crate::plate::{add_plate, PlateUiState}; use crate::plate::{add_plate, PlateUiState};
use crate::transfer_menu::{self, transfer_menu, CurrentTransferState, TransferMenuState}; use crate::transfer_menu::{self, transfer_menu, CurrentTransferState, TransferMenuState};
use crate::main_state::{MainState, construct_fake_mainstate};
use crate::tree::tree; use crate::tree::tree;
#[non_exhaustive] #[non_exhaustive]
@ -60,11 +60,11 @@ impl PlateToolEframe {
return eframe::get_value(storage, eframe::APP_KEY).unwrap_or_default(); return eframe::get_value(storage, eframe::APP_KEY).unwrap_or_default();
} else { } else {
let pte: PlateToolEframe = Default::default(); 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 pte
} }
} }
} }
@ -76,18 +76,6 @@ impl eframe::App for PlateToolEframe {
} }
fn update(&mut self, ctx: &eframe::egui::Context, _frame: &mut eframe::Frame) { fn update(&mut self, ctx: &eframe::egui::Context, _frame: &mut eframe::Frame) {
let ordered_ids: Vec<plate_tool_lib::uuid::Uuid> = {
let mut ids: Vec<plate_tool_lib::uuid::Uuid> = self
.main_state
.transfers
.clone()
.iter()
.map(|x| x.id)
.collect();
ids.sort_unstable();
ids
};
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| { egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
egui::menu::bar(ui, |ui| { egui::menu::bar(ui, |ui| {
ui.menu_button("File", |ui| { ui.menu_button("File", |ui| {
@ -125,11 +113,29 @@ impl eframe::App for PlateToolEframe {
ui.vertical(|ui| { ui.vertical(|ui| {
tree(ui, &mut self.main_state, &self.current_transfer_state); tree(ui, &mut self.main_state, &self.current_transfer_state);
ui.separator(); 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<plate_tool_lib::uuid::Uuid> = {
let mut ids: Vec<plate_tool_lib::uuid::Uuid> = self
.main_state
.transfers
.clone()
.iter()
.map(|x| x.id)
.collect();
ids.sort_unstable();
ids
};
egui::CentralPanel::default().show(ctx, |ui| { egui::CentralPanel::default().show(ctx, |ui| {
ui.vertical(|ui| { ui.vertical(|ui| {
let available_size = ui.available_size(); let available_size = ui.available_size();
@ -138,28 +144,32 @@ impl eframe::App for PlateToolEframe {
x.y /= 2.0; x.y /= 2.0;
x x
}; };
add_plate( if self.main_state.get_current_source().is_some() {
half_height, add_plate(
PlateFormat::W96, half_height,
&self.main_state.transfers, PlateFormat::W96,
plate_tool_lib::plate::PlateType::Source, &self.main_state.transfers,
&ordered_ids, plate_tool_lib::plate::PlateType::Source,
&self.transfer_region_cache, &ordered_ids,
Some(&self.current_transfer_state), &self.transfer_region_cache,
ui, Some(&self.current_transfer_state),
self.source_plate_state.lock().unwrap().deref_mut(), ui,
); self.source_plate_state.lock().unwrap().deref_mut(),
add_plate( );
half_height, }
PlateFormat::W96, if self.main_state.get_current_destination().is_some() {
&self.main_state.transfers, add_plate(
plate_tool_lib::plate::PlateType::Destination, half_height,
&ordered_ids, PlateFormat::W96,
&self.transfer_region_cache, &self.main_state.transfers,
Some(&self.current_transfer_state), plate_tool_lib::plate::PlateType::Destination,
ui, &ordered_ids,
self.destination_plate_state.lock().unwrap().deref_mut(), &self.transfer_region_cache,
); Some(&self.current_transfer_state),
ui,
self.destination_plate_state.lock().unwrap().deref_mut(),
);
}
}); });
}); });
} }

View File

@ -142,8 +142,8 @@ fn calculate_shading_for_wells(
}; };
if let Some(wells) = cache_result { if let Some(wells) = cache_result {
for well in wells.iter().filter(|x| x.row <= rows && x.col <= columns) { for well in wells.iter().filter(|x| x.row <= rows && x.col <= columns) {
if let Some(mut x) = if let Some(Some(mut x)) = well_infos
well_infos[(well.row - 1) as usize * columns as usize + (well.col - 1) as usize] .get_mut((well.row - 1) as usize * columns as usize + (well.col - 1) as usize)
{ {
x.volume += 5.0; x.volume += 5.0;
x.color = PALETTE.get_ordered(transfer.id, ordered_ids); x.color = PALETTE.get_ordered(transfer.id, ordered_ids);

View File

@ -1,9 +1,9 @@
use eframe::egui; use eframe::egui;
use plate_tool_lib::transfer_region::{self, Region, TransferRegion}; use plate_tool_lib::transfer_region::{self, Region, TransferRegion};
use std::sync::{Arc, Mutex};
use std::hash::{DefaultHasher, Hash, Hasher}; 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<Mutex<CurrentTransferStateInterior>>; pub type CurrentTransferState = Arc<Mutex<CurrentTransferStateInterior>>;
#[derive(Debug, serde::Serialize, serde::Deserialize)] #[derive(Debug, serde::Serialize, serde::Deserialize)]
@ -99,21 +99,27 @@ impl CurrentTransferStateInterior {
dest_plate: self.destination_plate, dest_plate: self.destination_plate,
dest_region: self.destination_region.clone(), dest_region: self.destination_region.clone(),
interleave_source: (self.source_row_interleave, self.source_column_interleave), 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<Self> { pub fn try_new_from_main_state_transfer(ms: &MainState) -> Option<Self> {
let transfer_id = ms.get_current_transfer(); 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 { if let Some(transfer) = transfer {
let volume: f32 = match transfer.volume { let volume: f32 = match transfer.volume {
plate_tool_lib::transfer_volume::TransferVolume::Single(x) => x, plate_tool_lib::transfer_volume::TransferVolume::Single(x) => x,
plate_tool_lib::transfer_volume::TransferVolume::WellMap(_) => { 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); 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!("It better not!");
}, }
_ => unreachable!() _ => unreachable!(),
}; };
return Some(Self { return Some(Self {
transfer_name: transfer.name.clone(), transfer_name: transfer.name.clone(),
@ -129,10 +135,24 @@ impl CurrentTransferStateInterior {
source_wells: None, source_wells: None,
destination_wells: None, destination_wells: None,
transfer_hash: None, transfer_hash: None,
}) });
} }
None None
} }
pub fn convert_to_transfer(&self, ms: &MainState) -> Option<plate_tool_lib::transfer::Transfer> {
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)] #[derive(Debug)]
@ -165,6 +185,8 @@ pub fn transfer_menu(
ui: &mut egui::Ui, ui: &mut egui::Ui,
state: &CurrentTransferState, state: &CurrentTransferState,
ui_state: &mut TransferMenuState, 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 // Can we reduce the length of this lock pls
let mut state = state.lock().unwrap(); 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();
}
});
} }