0 indexing is a blight
This commit is contained in:
parent
d296854580
commit
453ad9ed35
|
@ -69,8 +69,18 @@ fn get_hover_well(
|
||||||
start_x: f32,
|
start_x: f32,
|
||||||
start_y: f32,
|
start_y: f32,
|
||||||
radius: f32,
|
radius: f32,
|
||||||
|
rows: u8,
|
||||||
|
columns: u8,
|
||||||
) -> Option<(u8, u8)> {
|
) -> Option<(u8, u8)> {
|
||||||
get_well_from_pos(response.hover_pos(), start_x, start_y, radius)
|
get_well_from_pos(
|
||||||
|
response.hover_pos(),
|
||||||
|
start_x,
|
||||||
|
start_y,
|
||||||
|
radius,
|
||||||
|
rows,
|
||||||
|
columns,
|
||||||
|
true,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_well_from_pos(
|
fn get_well_from_pos(
|
||||||
|
@ -78,19 +88,35 @@ fn get_well_from_pos(
|
||||||
start_x: f32,
|
start_x: f32,
|
||||||
start_y: f32,
|
start_y: f32,
|
||||||
radius: f32,
|
radius: f32,
|
||||||
|
rows: u8,
|
||||||
|
columns: u8,
|
||||||
|
saturate: bool,
|
||||||
) -> Option<(u8, u8)> {
|
) -> Option<(u8, u8)> {
|
||||||
|
// cool fact: the bounds of our frame aren't actually the bounds of what counts
|
||||||
|
// as hovering. as a result, we have to make sure that we check these bounds here.
|
||||||
|
// yippee
|
||||||
|
let max_width = start_x + radius * 2.0 * columns as f32;
|
||||||
|
let max_height = start_y + radius * 2.0 * rows as f32;
|
||||||
|
|
||||||
// Some((row, column))
|
// Some((row, column))
|
||||||
position
|
position
|
||||||
.map(|p| Into::<(f32, f32)>::into(p))
|
.map(|p| Into::<(f32, f32)>::into(p))
|
||||||
.and_then(|(x, y)| {
|
.and_then(|(x, y)| {
|
||||||
// Check bounds
|
// Check bounds if no saturation
|
||||||
if x < start_x || y < start_y {
|
if !saturate && (x < start_x || y < start_y || x > max_width || y > max_height) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
// CHECK Bottom Right BOUND
|
|
||||||
|
|
||||||
let solved_column: u8 = (x - start_x).div_euclid(radius * 2.0) as u8;
|
let solved_column: u8 = match x {
|
||||||
let solved_row: u8 = (y - start_y).div_euclid(radius * 2.0) as u8;
|
x if (x < start_x) => 1,
|
||||||
|
x if (x > max_width) => columns,
|
||||||
|
_ => (x - start_x).div_euclid(radius * 2.0) as u8 + 1u8,
|
||||||
|
};
|
||||||
|
let solved_row: u8 = match y {
|
||||||
|
y if (y < start_y) => 1,
|
||||||
|
y if (y > max_height) => rows,
|
||||||
|
_ => (y - start_y).div_euclid(radius * 2.0) as u8 + 1u8,
|
||||||
|
};
|
||||||
|
|
||||||
Some((solved_row, solved_column))
|
Some((solved_row, solved_column))
|
||||||
})
|
})
|
||||||
|
@ -110,19 +136,24 @@ fn calculate_shading_for_wells(
|
||||||
for transfer in transfers {
|
for transfer in transfers {
|
||||||
let cache_result = match plate_type {
|
let cache_result = match plate_type {
|
||||||
plate_tool_lib::plate::PlateType::Source => cache.get_or_calculate_source(transfer),
|
plate_tool_lib::plate::PlateType::Source => cache.get_or_calculate_source(transfer),
|
||||||
plate_tool_lib::plate::PlateType::Destination => cache.get_or_calculate_destination(transfer),
|
plate_tool_lib::plate::PlateType::Destination => {
|
||||||
|
cache.get_or_calculate_destination(transfer)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
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(mut x) =
|
||||||
well_infos[well.row as usize * columns as usize + well.col as usize]
|
well_infos[(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);
|
||||||
} else {
|
} else {
|
||||||
well_infos[well.row as usize * columns as usize + well.col as usize] = Some(
|
well_infos
|
||||||
WellInfo::new(5.0, PALETTE.get_ordered(transfer.id, ordered_ids)),
|
[(well.row - 1) as usize * columns as usize + (well.col - 1) as usize] =
|
||||||
);
|
Some(WellInfo::new(
|
||||||
|
5.0,
|
||||||
|
PALETTE.get_ordered(transfer.id, ordered_ids),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,15 +197,20 @@ fn add_plate_sub(
|
||||||
state.drag_start_position = Some(response.hover_pos().unwrap());
|
state.drag_start_position = Some(response.hover_pos().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
let drag_start_well = get_well_from_pos(state.drag_start_position, start_x, start_y, radius);
|
let drag_start_well = get_well_from_pos(
|
||||||
let hovered_well = get_hover_well(&response, start_x, start_y, radius);
|
state.drag_start_position,
|
||||||
|
start_x,
|
||||||
|
start_y,
|
||||||
|
radius,
|
||||||
|
rows,
|
||||||
|
columns,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
let hovered_well = get_hover_well(&response, start_x, start_y, radius, rows, columns);
|
||||||
|
|
||||||
if response.clicked() {
|
if response.clicked() {
|
||||||
if let Some(cts) = current_transfer_state {
|
if let Some(cts) = current_transfer_state {
|
||||||
let end_well: Option<Well> = hovered_well.map(|(row, col)| Well {
|
let end_well: Option<Well> = hovered_well.map(|(row, col)| Well { row, col });
|
||||||
row: row + 1,
|
|
||||||
col: col + 1,
|
|
||||||
});
|
|
||||||
if let Some(end_well) = end_well {
|
if let Some(end_well) = end_well {
|
||||||
let new_region = Region::new_from_wells(end_well, None);
|
let new_region = Region::new_from_wells(end_well, None);
|
||||||
let mut cts = cts.lock().unwrap();
|
let mut cts = cts.lock().unwrap();
|
||||||
|
@ -189,17 +225,8 @@ fn add_plate_sub(
|
||||||
}
|
}
|
||||||
if response.drag_stopped() {
|
if response.drag_stopped() {
|
||||||
if let Some(cts) = current_transfer_state {
|
if let Some(cts) = current_transfer_state {
|
||||||
let start_well: Well = drag_start_well
|
if let Some(start_well) = drag_start_well.map(|(row, col)| Well { row, col }) {
|
||||||
.map(|(row, col)| Well {
|
let end_well: Option<Well> = hovered_well.map(|(row, col)| Well { row, col });
|
||||||
// Lib uses 1-indexing!
|
|
||||||
row: row + 1,
|
|
||||||
col: col + 1,
|
|
||||||
})
|
|
||||||
.unwrap();
|
|
||||||
let end_well: Option<Well> = hovered_well.map(|(row, col)| Well {
|
|
||||||
row: row + 1,
|
|
||||||
col: col + 1,
|
|
||||||
});
|
|
||||||
let new_region = Region::new_from_wells(start_well, end_well);
|
let new_region = Region::new_from_wells(start_well, end_well);
|
||||||
let mut cts = cts.lock().unwrap();
|
let mut cts = cts.lock().unwrap();
|
||||||
match plate_type {
|
match plate_type {
|
||||||
|
@ -209,6 +236,7 @@ fn add_plate_sub(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
state.drag_start_position = None;
|
state.drag_start_position = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +255,8 @@ fn add_plate_sub(
|
||||||
};
|
};
|
||||||
let well_infos = {
|
let well_infos = {
|
||||||
// Get non-active transfer info
|
// Get non-active transfer info
|
||||||
let mut well_infos = calculate_shading_for_wells(rows, columns, transfers, plate_type, ordered_ids, cache);
|
let mut well_infos =
|
||||||
|
calculate_shading_for_wells(rows, columns, transfers, plate_type, ordered_ids, cache);
|
||||||
|
|
||||||
// Get wells in the current transfer to tack on to well_infos separately
|
// Get wells in the current transfer to tack on to well_infos separately
|
||||||
let current_transfer_wells: Option<Box<[(usize, usize)]>> = {
|
let current_transfer_wells: Option<Box<[(usize, usize)]>> = {
|
||||||
|
@ -239,27 +268,30 @@ fn add_plate_sub(
|
||||||
.and_then(|x| x.lock().ok())
|
.and_then(|x| x.lock().ok())
|
||||||
.map(|mut x| x.get_destination_wells()),
|
.map(|mut x| x.get_destination_wells()),
|
||||||
})
|
})
|
||||||
// Drop back to 0-indexing here
|
.map(|xs| {
|
||||||
.map(|xs| xs.iter().map(|x| (x.row as usize - 1, x.col as usize - 1)).collect())
|
xs.iter()
|
||||||
|
.map(|x| (x.row as usize, x.col as usize))
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
};
|
};
|
||||||
if let Some(wells) = current_transfer_wells {
|
if let Some(wells) = current_transfer_wells {
|
||||||
for w in wells {
|
for w in wells {
|
||||||
let well_info = &mut well_infos[w.0 * columns as usize + w.1];
|
let well_info = &mut well_infos[(w.0 - 1) * columns as usize + (w.1 - 1)];
|
||||||
let volume = well_info.map(|x| x.volume).unwrap_or(0.0)
|
let volume = well_info.map(|x| x.volume).unwrap_or(0.0)
|
||||||
+ current_transfer_state.and_then(|x| x.lock().ok())
|
+ current_transfer_state
|
||||||
|
.and_then(|x| x.lock().ok())
|
||||||
.map(|x| x.volume)
|
.map(|x| x.volume)
|
||||||
.unwrap_or(0.0);
|
.unwrap_or(0.0);
|
||||||
|
|
||||||
*well_info = Some(WellInfo {
|
*well_info = Some(WellInfo {
|
||||||
color: [255.0, 255.0, 255.0],
|
color: [255.0, 255.0, 255.0],
|
||||||
volume: 1.0
|
volume: 1.0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
well_infos
|
well_infos
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Plate Frame
|
// Plate Frame
|
||||||
painter.rect_stroke(
|
painter.rect_stroke(
|
||||||
egui::Rect {
|
egui::Rect {
|
||||||
|
@ -274,11 +306,11 @@ fn add_plate_sub(
|
||||||
);
|
);
|
||||||
|
|
||||||
// Draw wells
|
// Draw wells
|
||||||
for c_row in 0..rows {
|
for c_row in 1..=rows {
|
||||||
for c_column in 0..columns {
|
for c_column in 1..=columns {
|
||||||
let center = egui::pos2(
|
let center = egui::pos2(
|
||||||
start_x + radius + 2.0 * radius * c_column as f32,
|
start_x + radius + 2.0 * radius * (c_column - 1) as f32,
|
||||||
start_y + radius + 2.0 * radius * c_row as f32,
|
start_y + radius + 2.0 * radius * (c_row - 1) as f32,
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -286,7 +318,7 @@ fn add_plate_sub(
|
||||||
//
|
//
|
||||||
|
|
||||||
if let Some(well_info) =
|
if let Some(well_info) =
|
||||||
well_infos[c_row as usize * columns as usize + c_column as usize]
|
well_infos[(c_row - 1) as usize * columns as usize + (c_column - 1) as usize]
|
||||||
{
|
{
|
||||||
painter.circle_filled(center, radius * 0.80, f64_to_color32(well_info.color));
|
painter.circle_filled(center, radius * 0.80, f64_to_color32(well_info.color));
|
||||||
}
|
}
|
||||||
|
@ -301,8 +333,8 @@ fn add_plate_sub(
|
||||||
if current_selection.as_ref().is_some_and(|x| {
|
if current_selection.as_ref().is_some_and(|x| {
|
||||||
x.contains_well(
|
x.contains_well(
|
||||||
&Well {
|
&Well {
|
||||||
row: c_row + 1,
|
row: c_row,
|
||||||
col: c_column + 1,
|
col: c_column,
|
||||||
},
|
},
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
@ -364,11 +396,10 @@ pub fn add_plate(
|
||||||
ui: &mut egui::Ui,
|
ui: &mut egui::Ui,
|
||||||
state: &mut PlateUiState,
|
state: &mut PlateUiState,
|
||||||
) {
|
) {
|
||||||
match pf {
|
add_plate_sub(
|
||||||
PlateFormat::W96 => add_plate_sub(
|
|
||||||
size,
|
size,
|
||||||
8,
|
pf.rows(),
|
||||||
12,
|
pf.columns(),
|
||||||
transfers,
|
transfers,
|
||||||
plate_type,
|
plate_type,
|
||||||
ordered_ids,
|
ordered_ids,
|
||||||
|
@ -376,31 +407,5 @@ pub fn add_plate(
|
||||||
current_transfer_state,
|
current_transfer_state,
|
||||||
ui,
|
ui,
|
||||||
state,
|
state,
|
||||||
),
|
);
|
||||||
PlateFormat::W384 => add_plate_sub(
|
|
||||||
size,
|
|
||||||
16,
|
|
||||||
24,
|
|
||||||
transfers,
|
|
||||||
plate_type,
|
|
||||||
ordered_ids,
|
|
||||||
cache,
|
|
||||||
current_transfer_state,
|
|
||||||
ui,
|
|
||||||
state,
|
|
||||||
),
|
|
||||||
PlateFormat::W1536 => add_plate_sub(
|
|
||||||
size,
|
|
||||||
32,
|
|
||||||
48,
|
|
||||||
transfers,
|
|
||||||
plate_type,
|
|
||||||
ordered_ids,
|
|
||||||
cache,
|
|
||||||
current_transfer_state,
|
|
||||||
ui,
|
|
||||||
state,
|
|
||||||
),
|
|
||||||
_ => unimplemented!(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,4 +114,10 @@ impl PlateFormat {
|
||||||
PlateFormat::W3456 => (48, 72),
|
PlateFormat::W3456 => (48, 72),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn rows(&self) -> u8 {
|
||||||
|
self.size().0
|
||||||
|
}
|
||||||
|
pub fn columns(&self) -> u8 {
|
||||||
|
self.size().1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue