Edit plates

This commit is contained in:
Emilia Allison 2025-01-12 17:25:46 -05:00
parent 1d2028959d
commit e6d80ab8a3
Signed by: emilia
GPG Key ID: 05D5D1107E5100A1
5 changed files with 351 additions and 51 deletions

View File

@ -3,12 +3,10 @@ use std::sync::Mutex;
use eframe::egui::{self}; use eframe::egui::{self};
use plate_tool_lib::plate::PlateFormat;
use crate::main_state::{construct_fake_mainstate, MainState}; use crate::main_state::{construct_fake_mainstate, MainState};
use crate::modals::{self, ModalState}; use crate::modals::{self, ModalState};
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::{transfer_menu, CurrentTransferState, TransferMenuState};
use crate::tree::tree; use crate::tree::tree;
#[non_exhaustive] #[non_exhaustive]
@ -57,10 +55,13 @@ impl PlateToolEframe {
pub fn new(cc: &eframe::CreationContext<'_>) -> Self { pub fn new(cc: &eframe::CreationContext<'_>) -> Self {
// Would load state here // Would load state here
if let Some(storage) = cc.storage { if let Some(storage) = cc.storage {
return eframe::get_value(storage, eframe::APP_KEY).unwrap_or_default(); let out: PlateToolEframe =
eframe::get_value(storage, eframe::APP_KEY).unwrap_or_default();
return out;
} else { } else {
let pte: PlateToolEframe = Default::default(); let pte: PlateToolEframe = Default::default();
pte.main_state.transfer_region_cache pte.main_state
.transfer_region_cache
.generate_cache(&pte.main_state.transfers); .generate_cache(&pte.main_state.transfers);
pte pte
@ -80,7 +81,7 @@ impl eframe::App for PlateToolEframe {
egui::menu::bar(ui, |ui| { egui::menu::bar(ui, |ui| {
ui.menu_button("File", |ui| { ui.menu_button("File", |ui| {
if ui.button("New Plate").clicked() { if ui.button("New Plate").clicked() {
crate::modals::open_new_plate_modal(ctx, &mut self.modal_state); crate::modals::open_new_plate_modal(&mut self.modal_state);
} }
ui.menu_button("Export", |ui| { ui.menu_button("Export", |ui| {
if ui.button("Export as CSV").clicked() {} if ui.button("Export as CSV").clicked() {}
@ -90,7 +91,13 @@ impl eframe::App for PlateToolEframe {
if ui.button("Import from JSON").clicked() {} if ui.button("Import from JSON").clicked() {}
if ui.button("Import transfer from CSV").clicked() {} if ui.button("Import transfer from CSV").clicked() {}
}); });
if ui.button("Reset All").clicked() {} if ui.button("Reset All").clicked() {
self.main_state = MainState::default();
self.current_transfer_state = CurrentTransferState::default();
}
if ui.button("Dump State").clicked() {
log::warn!("{:?}\n{:?}", self.main_state, self.current_transfer_state);
}
}); });
ui.menu_button("Options", |ui| { ui.menu_button("Options", |ui| {
ui.menu_button("Styles", |ui| { ui.menu_button("Styles", |ui| {
@ -114,7 +121,12 @@ impl eframe::App for PlateToolEframe {
if self.main_window_state.show_side_panel { if self.main_window_state.show_side_panel {
egui::SidePanel::left("side_menus").show(ctx, |ui| { egui::SidePanel::left("side_menus").show(ctx, |ui| {
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,
&mut self.modal_state,
);
ui.separator(); ui.separator();
transfer_menu( transfer_menu(
ui, ui,
@ -150,7 +162,7 @@ impl eframe::App for PlateToolEframe {
add_plate( add_plate(
half_height, half_height,
source_pi.plate.plate_format, source_pi.plate.plate_format,
self.main_state.get_current_transfers(), self.main_state.get_current_source_transfers(),
plate_tool_lib::plate::PlateType::Source, plate_tool_lib::plate::PlateType::Source,
&ordered_ids, &ordered_ids,
&self.main_state.transfer_region_cache, &self.main_state.transfer_region_cache,
@ -159,11 +171,13 @@ impl eframe::App for PlateToolEframe {
self.source_plate_state.lock().unwrap().deref_mut(), self.source_plate_state.lock().unwrap().deref_mut(),
); );
} }
if let Some(destination_pi) = self.main_state.get_current_destination_plateinstance() { if let Some(destination_pi) =
self.main_state.get_current_destination_plateinstance()
{
add_plate( add_plate(
half_height, half_height,
destination_pi.plate.plate_format, destination_pi.plate.plate_format,
self.main_state.get_current_transfers(), self.main_state.get_current_destination_transfers(),
plate_tool_lib::plate::PlateType::Destination, plate_tool_lib::plate::PlateType::Destination,
&ordered_ids, &ordered_ids,
&self.main_state.transfer_region_cache, &self.main_state.transfer_region_cache,
@ -177,19 +191,47 @@ impl eframe::App for PlateToolEframe {
// Modal processing // Modal processing
modals::show_modal_if_open(ctx, &mut self.modal_state); modals::show_modal_if_open(ctx, &mut self.modal_state);
if let modals::ModalState::NewPlateComplete(modals::NewPlateModalComplete(Some(pi))) = match &self.modal_state {
&self.modal_state modals::ModalState::NewPlateComplete(modals::NewPlateModalComplete(Some(pi))) => {
{
let plate_type = pi.plate.plate_type; let plate_type = pi.plate.plate_type;
match plate_type { match plate_type {
plate_tool_lib::plate::PlateType::Source => { plate_tool_lib::plate::PlateType::Source => {
self.main_state.source_plates.push(pi.clone()); self.main_state.source_plates.push(pi.clone());
}, }
plate_tool_lib::plate::PlateType::Destination => { plate_tool_lib::plate::PlateType::Destination => {
self.main_state.destination_plates.push(pi.clone()); self.main_state.destination_plates.push(pi.clone());
}, }
} }
self.modal_state = modals::ModalState::None; self.modal_state = modals::ModalState::None;
} }
modals::ModalState::EditPlateComplete(modals::EditPlateModalStateComplete(Some(x))) => {
let pi = {
match x.plate_type {
plate_tool_lib::plate::PlateType::Source => self
.main_state
.source_plates
.iter_mut()
.find(|y| y.get_uuid() == x.id),
plate_tool_lib::plate::PlateType::Destination => self
.main_state
.destination_plates
.iter_mut()
.find(|y| y.get_uuid() == x.id),
}
};
if let Some(pi) = pi {
pi.name = x.name.to_owned();
pi.change_format(&x.plate_format);
}
self.modal_state = modals::ModalState::None;
}
ModalState::NewPlateComplete(modals::NewPlateModalComplete(None)) => {
self.modal_state = modals::ModalState::None;
}
ModalState::EditPlateComplete(modals::EditPlateModalStateComplete(None)) => {
self.modal_state = modals::ModalState::None;
}
_ => (),
}
} }
} }

View File

@ -1,8 +1,10 @@
use core::fmt;
use plate_tool_lib::plate::PlateFormat; use plate_tool_lib::plate::PlateFormat;
use plate_tool_lib::plate_instances; use plate_tool_lib::plate_instances::{self, PlateInstance};
use plate_tool_lib::transfer_region_cache::TransferRegionCache; use plate_tool_lib::transfer_region_cache::TransferRegionCache;
#[derive(Default, Debug, serde::Serialize, serde::Deserialize)] #[derive(Default, serde::Serialize, serde::Deserialize)]
pub struct MainState { pub struct MainState {
/// Stores all plates and transfers /// Stores all plates and transfers
/// ///
@ -55,14 +57,28 @@ impl MainState {
None None
} }
} }
pub fn get_current_transfers(&self) -> Option<Vec<&plate_tool_lib::transfer::Transfer>> { pub fn get_current_source_transfers(&self) -> Option<Vec<&plate_tool_lib::transfer::Transfer>> {
let source_uuid = self.get_current_source_uuid(); let source_uuid = self.get_current_source_uuid();
let destination_uuid = self.get_current_destination_uuid(); if let Some(source_uuid) = source_uuid {
if let (Some(source_uuid), Some(destination_uuid)) = (source_uuid, destination_uuid) { Some(
Some(self.transfers self.transfers
.iter() .iter()
.filter(|tr| tr.source_id == source_uuid && tr.dest_id == destination_uuid) .filter(|tr| tr.source_id == source_uuid)
.collect()) .collect(),
)
} else {
None
}
}
pub fn get_current_destination_transfers(&self) -> Option<Vec<&plate_tool_lib::transfer::Transfer>> {
let destination_uuid = self.get_current_destination_uuid();
if let Some(destination_uuid) = destination_uuid {
Some(
self.transfers
.iter()
.filter(|tr| tr.dest_id == destination_uuid)
.collect(),
)
} else { } else {
None None
} }
@ -117,6 +133,12 @@ impl MainState {
.find(|x| *x == id) .find(|x| *x == id)
.is_some() .is_some()
} }
pub fn get_source_by_uuid(&self, id: plate_tool_lib::uuid::Uuid) -> Option<&PlateInstance> {
self.source_plates
.iter()
.find(|x| x.get_uuid() == id)
}
fn check_destination_exists(&self, id: plate_tool_lib::uuid::Uuid) -> bool { fn check_destination_exists(&self, id: plate_tool_lib::uuid::Uuid) -> bool {
self.destination_plates self.destination_plates
.iter() .iter()
@ -124,6 +146,45 @@ impl MainState {
.find(|x| *x == id) .find(|x| *x == id)
.is_some() .is_some()
} }
pub fn get_destination_by_uuid(&self, id: plate_tool_lib::uuid::Uuid) -> Option<&PlateInstance> {
self.destination_plates
.iter()
.find(|x| x.get_uuid() == id)
}
}
impl fmt::Debug for MainState {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
#[derive(Debug)]
#[allow(dead_code)]
struct SelectedFields<'a> {
pub source_plates: &'a Vec<plate_tool_lib::plate_instances::PlateInstance>,
pub destination_plates: &'a Vec<plate_tool_lib::plate_instances::PlateInstance>,
pub transfers: &'a Vec<plate_tool_lib::transfer::Transfer>,
current_source: &'a Option<plate_tool_lib::uuid::Uuid>,
current_destination: &'a Option<plate_tool_lib::uuid::Uuid>,
current_transfer: &'a Option<plate_tool_lib::uuid::Uuid>,
}
let Self {
source_plates,
destination_plates,
transfers,
current_source,
current_destination,
current_transfer,
transfer_region_cache: _,
} = self;
fmt::Debug::fmt(
&SelectedFields {
source_plates,
destination_plates,
transfers,
current_source,
current_destination,
current_transfer,
},
f,
)
}
} }
pub fn construct_fake_mainstate() -> MainState { pub fn construct_fake_mainstate() -> MainState {

View File

@ -5,6 +5,8 @@ use eframe::egui;
pub enum ModalState { pub enum ModalState {
NewPlate(NewPlateModalState), NewPlate(NewPlateModalState),
NewPlateComplete(NewPlateModalComplete), NewPlateComplete(NewPlateModalComplete),
EditPlate(EditPlateModalState),
EditPlateComplete(EditPlateModalStateComplete),
None, None,
} }
impl Default for ModalState { impl Default for ModalState {
@ -14,11 +16,22 @@ impl Default for ModalState {
} }
#[non_exhaustive] #[non_exhaustive]
#[derive(Debug, Default)] #[derive(Debug)]
pub struct NewPlateModalState { pub struct NewPlateModalState {
pub name: String, pub name: String,
pub plate_type: plate_tool_lib::plate::PlateType, pub plate_type: plate_tool_lib::plate::PlateType,
pub plate_format: plate_tool_lib::plate::PlateFormat, pub plate_format: plate_tool_lib::plate::PlateFormat,
window_open: bool,
}
impl Default for NewPlateModalState {
fn default() -> Self {
Self {
name: String::default(),
plate_type: plate_tool_lib::plate::PlateType::default(),
plate_format: plate_tool_lib::plate::PlateFormat::default(),
window_open: true,
}
}
} }
#[non_exhaustive] #[non_exhaustive]
@ -28,6 +41,7 @@ pub struct NewPlateModalComplete(pub Option<plate_tool_lib::plate_instances::Pla
pub fn show_modal_if_open(ctx: &egui::Context, modal_state: &mut ModalState) { pub fn show_modal_if_open(ctx: &egui::Context, modal_state: &mut ModalState) {
match modal_state { match modal_state {
ModalState::NewPlate(_) => show_new_plate_modal(ctx, modal_state), ModalState::NewPlate(_) => show_new_plate_modal(ctx, modal_state),
ModalState::EditPlate(_) => show_edit_plate_modal(ctx, modal_state),
_ => (), _ => (),
} }
} }
@ -50,6 +64,7 @@ fn show_new_plate_modal(ctx: &egui::Context, modal_state: &mut ModalState) {
.order(egui::Order::Foreground) .order(egui::Order::Foreground)
.collapsible(false) .collapsible(false)
.resizable(false) .resizable(false)
.open(&mut state.window_open)
.show(ctx, |ui| { .show(ctx, |ui| {
ui.vertical(|ui| { ui.vertical(|ui| {
ui.add(egui::TextEdit::singleline(&mut state.name).hint_text("Plate Name")); ui.add(egui::TextEdit::singleline(&mut state.name).hint_text("Plate Name"));
@ -87,21 +102,134 @@ fn show_new_plate_modal(ctx: &egui::Context, modal_state: &mut ModalState) {
); );
}); });
if ui.button("Add").clicked() { if ui.button("Add").clicked() {
output = Some(plate_tool_lib::plate_instances::PlateInstance::new(state.plate_type, state.plate_format, state.name.clone())); output = Some(plate_tool_lib::plate_instances::PlateInstance::new(
state.plate_type,
state.plate_format,
state.name.clone(),
));
} }
}); });
}); });
if state.window_open == false {
*modal_state = ModalState::NewPlateComplete(NewPlateModalComplete(None));
return;
}
if output.is_some() { if output.is_some() {
*modal_state = ModalState::NewPlateComplete(NewPlateModalComplete(output)); *modal_state = ModalState::NewPlateComplete(NewPlateModalComplete(output));
} }
} }
pub fn open_new_plate_modal(modal_state: &mut ModalState) {
pub fn open_new_plate_modal(
ctx: &egui::Context,
modal_state: &mut ModalState,
) {
// Do not close another modal // Do not close another modal
if matches!(modal_state, ModalState::None) { if matches!(modal_state, ModalState::None) {
*modal_state = ModalState::NewPlate(NewPlateModalState::default()); *modal_state = ModalState::NewPlate(NewPlateModalState::default());
} }
} }
#[non_exhaustive]
#[derive(Debug, Clone)]
pub struct EditPlateModalState {
pub name: String,
pub plate_type: plate_tool_lib::plate::PlateType,
pub plate_format: plate_tool_lib::plate::PlateFormat,
pub id: plate_tool_lib::uuid::Uuid,
window_open: bool,
}
impl EditPlateModalState {
fn new(
name: &str,
plate_type: plate_tool_lib::plate::PlateType,
plate_format: plate_tool_lib::plate::PlateFormat,
id: plate_tool_lib::uuid::Uuid,
) -> Self {
Self {
name: name.to_owned(),
plate_type,
plate_format,
id,
window_open: true,
}
}
}
#[non_exhaustive]
#[derive(Debug)]
pub struct EditPlateModalStateComplete(pub Option<EditPlateModalState>);
fn show_edit_plate_modal(ctx: &egui::Context, modal_state: &mut ModalState) {
let state: &mut EditPlateModalState = {
if let ModalState::EditPlate(x) = modal_state {
x
} else {
return;
}
};
let mut should_complete: bool = false;
egui::Window::new("Edit Plate")
.order(egui::Order::Foreground)
.collapsible(false)
.resizable(false)
.open(&mut state.window_open)
.show(ctx, |ui| {
ui.vertical(|ui| {
ui.add(egui::TextEdit::singleline(&mut state.name).hint_text("Plate Name"));
egui::ComboBox::from_label("Plate Format")
.selected_text(format!("{:?}", state.plate_format))
.show_ui(ui, |ui| {
ui.selectable_value(
&mut state.plate_format,
plate_tool_lib::plate::PlateFormat::W96,
"96W",
);
ui.selectable_value(
&mut state.plate_format,
plate_tool_lib::plate::PlateFormat::W384,
"384W",
);
ui.selectable_value(
&mut state.plate_format,
plate_tool_lib::plate::PlateFormat::W1536,
"1536W",
);
});
if ui.button("Save").clicked() {
should_complete = true;
}
});
});
if state.window_open == false {
*modal_state = ModalState::EditPlateComplete(EditPlateModalStateComplete(None));
return;
}
if should_complete {
*modal_state =
ModalState::EditPlateComplete(EditPlateModalStateComplete(Some(state.to_owned())));
return;
}
}
pub fn open_edit_plate_modal(
modal_state: &mut ModalState,
name: &str,
plate_type: plate_tool_lib::plate::PlateType,
plate_format: plate_tool_lib::plate::PlateFormat,
id: plate_tool_lib::uuid::Uuid,
) {
// Do not close another modal
if matches!(modal_state, ModalState::None) {
*modal_state =
ModalState::EditPlate(EditPlateModalState::new(name, plate_type, plate_format, id))
}
}
pub fn open_edit_plate_modal_plateinstance(
modal_state: &mut ModalState,
plate_instance: &plate_tool_lib::plate_instances::PlateInstance,
) {
// Do not close another modal
if matches!(modal_state, ModalState::None) {
*modal_state = ModalState::EditPlate(EditPlateModalState::new(
&plate_instance.name,
plate_instance.plate.plate_type,
plate_instance.plate.plate_format,
plate_instance.get_uuid(),
));
}
}

View File

@ -116,7 +116,7 @@ impl CurrentTransferStateInterior {
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::warn!("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!(),
@ -188,6 +188,7 @@ pub fn transfer_menu(
main_state: &mut MainState, main_state: &mut MainState,
) { ) {
// Can we reduce the length of this lock pls // Can we reduce the length of this lock pls
let cts = state;
let mut state = state.lock().unwrap(); let mut state = state.lock().unwrap();
ui.horizontal(|ui| { ui.horizontal(|ui| {
@ -289,7 +290,10 @@ pub fn transfer_menu(
transfer.name = state.transfer_name.clone(); transfer.name = state.transfer_name.clone();
main_state.transfer_region_cache.invalidate(&transfer); main_state.transfer_region_cache.invalidate(&transfer);
} }
} else { } else { // Need to make a new transfer
if state.transfer_name.is_empty() {
state.transfer_name = "New Transfer".to_string();
}
let new_transfer = state.convert_to_transfer(main_state); let new_transfer = state.convert_to_transfer(main_state);
log::info!("{:?}", new_transfer); log::info!("{:?}", new_transfer);
if let Some(new_transfer) = new_transfer { if let Some(new_transfer) = new_transfer {
@ -297,12 +301,23 @@ pub fn transfer_menu(
let new_transfer = main_state.transfers.last() let new_transfer = main_state.transfers.last()
.expect("Cannot be empty, just added a transfer"); .expect("Cannot be empty, just added a transfer");
main_state.transfer_region_cache.add_overwrite(new_transfer); main_state.transfer_region_cache.add_overwrite(new_transfer);
main_state.set_current_transfer(new_transfer.id);
} }
} }
} }
if ui.button("New").clicked() { if ui.button("New").clicked() {
*state = CurrentTransferStateInterior::default(); *state = CurrentTransferStateInterior::default();
set_plates(main_state, &mut state);
main_state.set_no_current_transfer(); main_state.set_no_current_transfer();
} }
}); });
} }
fn set_plates(ms: &MainState, cts: &mut CurrentTransferStateInterior) {
if let Some(source_plate) = ms.get_current_source_plateinstance() {
cts.source_plate = source_plate.plate;
}
if let Some(destination_plate) = ms.get_current_destination_plateinstance() {
cts.destination_plate = destination_plate.plate;
}
}

View File

@ -1,13 +1,22 @@
use eframe::egui; use eframe::egui;
use crate::{main_state::MainState, transfer_menu::{CurrentTransferState, CurrentTransferStateInterior}}; use crate::{
main_state::MainState,
modals::ModalState,
transfer_menu::{CurrentTransferState, CurrentTransferStateInterior},
};
use std::sync::LazyLock; use std::sync::LazyLock;
static SELECT_COLOR: LazyLock<egui::Color32> = static SELECT_COLOR: LazyLock<egui::Color32> =
LazyLock::new(|| egui::Color32::from_hex("#aa0000").unwrap()); LazyLock::new(|| egui::Color32::from_hex("#aa0000").unwrap());
pub fn tree(ui: &mut egui::Ui, ms: &mut MainState, cts: &CurrentTransferState) { pub fn tree(
ui: &mut egui::Ui,
ms: &mut MainState,
cts: &CurrentTransferState,
modal_state: &mut ModalState,
) {
// Add all source plates // Add all source plates
ui.vertical(|ui| { ui.vertical(|ui| {
ui.heading("Source Plates"); ui.heading("Source Plates");
@ -29,14 +38,24 @@ pub fn tree(ui: &mut egui::Ui, ms: &mut MainState, cts: &CurrentTransferState) {
if r.clicked() { if r.clicked() {
new_uuid = Some(uuid); new_uuid = Some(uuid);
} }
if r.double_clicked() {
let pi = ms.get_source_by_uuid(uuid);
if let Some(pi) = pi {
crate::modals::open_edit_plate_modal_plateinstance(modal_state, &pi);
}
}
}); });
} }
if let Some(uuid) = new_uuid { if let Some(uuid) = new_uuid {
let current_source_uuid = ms.get_current_source_uuid();
if current_source_uuid.is_some_and(|x| x != uuid) || current_source_uuid.is_none() {
ms.set_current_source(uuid); ms.set_current_source(uuid);
ms.set_no_current_transfer(); ms.set_no_current_transfer();
if let Some(mut cts) = cts.lock().ok() { if let Some(mut cts) = cts.lock().ok() {
*cts = CurrentTransferStateInterior::default(); *cts = CurrentTransferStateInterior::default();
} }
set_plates(ms, cts);
}
} }
}); });
@ -65,13 +84,34 @@ pub fn tree(ui: &mut egui::Ui, ms: &mut MainState, cts: &CurrentTransferState) {
if r.clicked() { if r.clicked() {
new_uuid = Some(uuid); new_uuid = Some(uuid);
} }
if r.double_clicked() {
let pi = ms.get_destination_by_uuid(uuid);
if let Some(pi) = pi {
crate::modals::open_edit_plate_modal_plateinstance(modal_state, &pi);
}
}
}); });
} }
if let Some(uuid) = new_uuid { if let Some(uuid) = new_uuid {
let current_destination_uuid = ms.get_current_destination_uuid();
if current_destination_uuid.is_some_and(|x| x != uuid)
|| current_destination_uuid.is_none()
{
ms.set_current_destination(uuid); ms.set_current_destination(uuid);
ms.set_no_current_transfer(); ms.set_no_current_transfer();
if let Some(mut cts) = cts.lock().ok() { if let Some(mut cts) = cts.lock().ok() {
*cts = CurrentTransferStateInterior::default(); *cts = CurrentTransferStateInterior::default();
cts.destination_plate = ms
.get_current_destination_plateinstance()
.expect("Just set destination")
.plate;
}
set_plates(ms, cts);
log::warn!(
"{:?}\n{:?}",
cts,
ms.get_current_destination_plateinstance()
);
} }
} }
}); });
@ -101,9 +141,23 @@ pub fn tree(ui: &mut egui::Ui, ms: &mut MainState, cts: &CurrentTransferState) {
} }
if let Some(uuid) = new_uuid { if let Some(uuid) = new_uuid {
ms.set_current_transfer(uuid); ms.set_current_transfer(uuid);
if let Some(new_cts) = CurrentTransferStateInterior::try_new_from_main_state_transfer(ms) { if let Some(new_cts) =
CurrentTransferStateInterior::try_new_from_main_state_transfer(ms)
{
*cts.lock().unwrap() = new_cts; *cts.lock().unwrap() = new_cts;
} }
set_plates(ms, cts);
} }
}); });
} }
fn set_plates(ms: &MainState, cts: &CurrentTransferState) {
if let Some(mut cts) = cts.lock().ok() {
if let Some(source_plate) = ms.get_current_source_plateinstance() {
cts.source_plate = source_plate.plate;
}
if let Some(destination_plate) = ms.get_current_destination_plateinstance() {
cts.destination_plate = destination_plate.plate;
}
}
}