eframe work

This commit is contained in:
Emilia Allison 2025-01-01 14:37:36 -05:00
parent dc3ef4830a
commit 2b1792c2ae
Signed by: emilia
GPG Key ID: 05D5D1107E5100A1
5 changed files with 214 additions and 16 deletions

View File

@ -6,10 +6,28 @@ use eframe::egui::{self};
use plate_tool_lib::plate::PlateFormat;
use crate::plate::{add_grid, PlateUiState};
use crate::transfer_menu::{self, transfer_menu, TransferMenuState};
#[non_exhaustive]
struct MainWindowState {
show_side_panel: bool,
}
impl Default for MainWindowState {
fn default() -> Self {
Self {
show_side_panel: true,
}
}
}
#[non_exhaustive]
pub struct PlateToolEframe {
format: PlateFormat,
source_plate_state: Mutex<PlateUiState>,
destination_plate_state: Mutex<PlateUiState>,
main_window_state: MainWindowState,
transfer_menu_state: TransferMenuState,
}
impl Default for PlateToolEframe {
@ -17,6 +35,9 @@ impl Default for PlateToolEframe {
Self {
format: PlateFormat::W96,
source_plate_state: Mutex::new(PlateUiState::default()),
destination_plate_state: Mutex::new(PlateUiState::default()),
main_window_state: MainWindowState::default(),
transfer_menu_state: TransferMenuState::default(),
}
}
}
@ -39,16 +60,72 @@ impl eframe::App for PlateToolEframe {
fn update(&mut self, ctx: &eframe::egui::Context, _frame: &mut eframe::Frame) {
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
ui.label("shrimp");
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| {
transfer_menu(ui, &mut self.transfer_menu_state);
});
});
}
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("lobster");
add_grid(
PlateFormat::W1536,
ui,
self.source_plate_state.lock().unwrap().deref_mut(),
);
ui.vertical(|ui| {
let available_size = ui.available_size();
let half_height = {
let mut x = available_size;
x.y /= 2.0;
x
};
add_grid(
half_height,
PlateFormat::W1536,
ui,
self.source_plate_state.lock().unwrap().deref_mut(),
);
add_grid(
half_height,
PlateFormat::W1536,
ui,
self.destination_plate_state.lock().unwrap().deref_mut(),
);
});
});
}
}

View File

@ -1,3 +1,5 @@
mod app;
mod plate;
mod tree;
mod transfer_menu;
pub use app::PlateToolEframe;

View File

@ -1,7 +1,9 @@
use eframe::egui::{self, pos2, Color32, Rounding};
use plate_tool_lib::plate::PlateFormat;
#[derive(Clone, Copy, Debug)]
const PALETTE: plate_tool_lib::util::ColorPalette = plate_tool_lib::util::Palettes::RAINBOW;
#[derive(Clone, Debug)]
pub struct PlateUiState {
pub drag_start_position: Option<egui::Pos2>,
}
@ -14,7 +16,15 @@ impl Default for PlateUiState {
}
}
pub fn add_grid(pf: PlateFormat, ui: &mut egui::Ui, state: &mut PlateUiState) {
#[derive(Clone, Copy, Debug)]
struct WellInfo {
volume: f32,
color: [f32; 3],
}
pub fn add_grid(size: egui::Vec2, pf: PlateFormat,
transfers: &Vec<plate_tool_lib::transfer::Transfer>,
ui: &mut egui::Ui, state: &mut PlateUiState) {
fn calculate_grid_params(
ul_origin: (f32, f32),
tw: f32,
@ -66,10 +76,26 @@ pub fn add_grid(pf: PlateFormat, ui: &mut egui::Ui, state: &mut PlateUiState) {
})
}
fn add_grid_sub(rows: u8, columns: u8, ui: &mut egui::Ui, state: &mut PlateUiState) {
let available_size = ui.available_size();
let (response, painter) =
ui.allocate_painter(available_size, egui::Sense::click_and_drag());
fn calculate_shading_for_wells(
rows: u8,
columns: u8,
transfers: &Vec<plate_tool_lib::transfer::Transfer>,
) -> Box<[Option<WellInfo>]> {
let box_size: usize = rows as usize * columns as usize;
let mut well_infos: Box<[Option<WellInfo>]> = vec![None; box_size].into_boxed_slice();
well_infos
}
fn add_grid_sub(
size: egui::Vec2,
rows: u8,
columns: u8,
transfers: &Vec<plate_tool_lib::transfer::Transfer>,
ui: &mut egui::Ui,
state: &mut PlateUiState,
) {
let (response, painter) = ui.allocate_painter(size, egui::Sense::click_and_drag());
let rect = response.rect;
@ -135,12 +161,38 @@ pub fn add_grid(pf: PlateFormat, ui: &mut egui::Ui, state: &mut PlateUiState) {
painter.circle_stroke(center, radius - 2.0, stroke);
}
}
// Draw row/column labels
for c_row in 0..rows {
painter.text(
egui::pos2(
start_x - 10.0,
start_y + radius + 2.0 * radius * c_row as f32,
),
egui::Align2::CENTER_CENTER,
(c_row + 1).to_string(),
egui::FontId::monospace(f32::min(radius, 14.0)),
egui::Color32::from_gray(128),
);
}
for c_column in 0..columns {
painter.text(
egui::pos2(
start_x + radius + 2.0 * radius * c_column as f32,
start_y - 12.0,
),
egui::Align2::CENTER_CENTER,
plate_tool_lib::util::num_to_letters(c_column + 1).unwrap(),
egui::FontId::monospace(f32::min(radius, 14.0)),
egui::Color32::from_gray(128),
);
}
}
match pf {
PlateFormat::W96 => add_grid_sub(8, 12, ui, state),
PlateFormat::W384 => add_grid_sub(16, 24, ui, state),
PlateFormat::W1536 => add_grid_sub(32, 48, ui, state),
PlateFormat::W96 => add_grid_sub(size, 8, 12, transfers, ui, state),
PlateFormat::W384 => add_grid_sub(size, 16, 24, transfers, ui, state),
PlateFormat::W1536 => add_grid_sub(size, 32, 48, transfers, ui, state),
_ => unimplemented!(),
}
}

View File

@ -0,0 +1,67 @@
use eframe::egui::{self, pos2, Color32, Rounding};
pub struct TransferMenuState {
pub transfer_name: String,
pub source_region: String,
pub destination_region: String,
pub source_row_interleave: f32,
pub source_column_interleave: f32,
}
impl Default for TransferMenuState {
fn default() -> Self {
Self {
transfer_name: String::default(),
source_region: String::default(),
destination_region: String::default(),
source_row_interleave: 1.0,
source_column_interleave: 1.0,
}
}
}
pub fn transfer_menu(ui: &mut egui::Ui, state: &mut TransferMenuState) {
ui.horizontal(|ui| {
ui.add(egui::Label::new("Name"));
ui.add(
egui::TextEdit::singleline(&mut state.transfer_name)
.hint_text("Transfer Name")
.horizontal_align(egui::Align::Center),
);
});
ui.horizontal(|ui| {
ui.add(egui::Label::new("Source Region"));
ui.add(
egui::TextEdit::singleline(&mut state.source_region)
.hint_text("Source Region")
.char_limit(9)
.horizontal_align(egui::Align::Center),
);
});
ui.end_row();
ui.horizontal(|ui| {
ui.add(egui::Label::new("Destination Region"));
ui.add(
egui::TextEdit::singleline(&mut state.destination_region)
.hint_text("Destination Region")
.char_limit(9)
.horizontal_align(egui::Align::Center),
);
});
ui.vertical(|ui| {
ui.label("Source Interleave");
ui.horizontal(|ui| {
ui.label("Row: ");
ui.add(egui::DragValue::new(&mut state.source_row_interleave)
.fixed_decimals(0)
.range(0..=30));
ui.label("Col: ");
ui.add(egui::DragValue::new(&mut state.source_column_interleave)
.fixed_decimals(0)
.range(0..=30));
});
});
}

View File