eframe work
This commit is contained in:
parent
dc3ef4830a
commit
2b1792c2ae
|
@ -6,10 +6,28 @@ use eframe::egui::{self};
|
||||||
use plate_tool_lib::plate::PlateFormat;
|
use plate_tool_lib::plate::PlateFormat;
|
||||||
|
|
||||||
use crate::plate::{add_grid, PlateUiState};
|
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 {
|
pub struct PlateToolEframe {
|
||||||
format: PlateFormat,
|
format: PlateFormat,
|
||||||
source_plate_state: Mutex<PlateUiState>,
|
source_plate_state: Mutex<PlateUiState>,
|
||||||
|
destination_plate_state: Mutex<PlateUiState>,
|
||||||
|
main_window_state: MainWindowState,
|
||||||
|
transfer_menu_state: TransferMenuState,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for PlateToolEframe {
|
impl Default for PlateToolEframe {
|
||||||
|
@ -17,6 +35,9 @@ impl Default for PlateToolEframe {
|
||||||
Self {
|
Self {
|
||||||
format: PlateFormat::W96,
|
format: PlateFormat::W96,
|
||||||
source_plate_state: Mutex::new(PlateUiState::default()),
|
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) {
|
fn update(&mut self, ctx: &eframe::egui::Context, _frame: &mut eframe::Frame) {
|
||||||
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
|
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| {
|
egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
ui.heading("lobster");
|
ui.vertical(|ui| {
|
||||||
|
let available_size = ui.available_size();
|
||||||
|
let half_height = {
|
||||||
|
let mut x = available_size;
|
||||||
|
x.y /= 2.0;
|
||||||
|
x
|
||||||
|
};
|
||||||
add_grid(
|
add_grid(
|
||||||
|
half_height,
|
||||||
PlateFormat::W1536,
|
PlateFormat::W1536,
|
||||||
ui,
|
ui,
|
||||||
self.source_plate_state.lock().unwrap().deref_mut(),
|
self.source_plate_state.lock().unwrap().deref_mut(),
|
||||||
);
|
);
|
||||||
|
add_grid(
|
||||||
|
half_height,
|
||||||
|
PlateFormat::W1536,
|
||||||
|
ui,
|
||||||
|
self.destination_plate_state.lock().unwrap().deref_mut(),
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
mod app;
|
mod app;
|
||||||
mod plate;
|
mod plate;
|
||||||
|
mod tree;
|
||||||
|
mod transfer_menu;
|
||||||
pub use app::PlateToolEframe;
|
pub use app::PlateToolEframe;
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
use eframe::egui::{self, pos2, Color32, Rounding};
|
use eframe::egui::{self, pos2, Color32, Rounding};
|
||||||
use plate_tool_lib::plate::PlateFormat;
|
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 struct PlateUiState {
|
||||||
pub drag_start_position: Option<egui::Pos2>,
|
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(
|
fn calculate_grid_params(
|
||||||
ul_origin: (f32, f32),
|
ul_origin: (f32, f32),
|
||||||
tw: 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) {
|
fn calculate_shading_for_wells(
|
||||||
let available_size = ui.available_size();
|
rows: u8,
|
||||||
let (response, painter) =
|
columns: u8,
|
||||||
ui.allocate_painter(available_size, egui::Sense::click_and_drag());
|
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;
|
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);
|
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 {
|
match pf {
|
||||||
PlateFormat::W96 => add_grid_sub(8, 12, ui, state),
|
PlateFormat::W96 => add_grid_sub(size, 8, 12, transfers, ui, state),
|
||||||
PlateFormat::W384 => add_grid_sub(16, 24, ui, state),
|
PlateFormat::W384 => add_grid_sub(size, 16, 24, transfers, ui, state),
|
||||||
PlateFormat::W1536 => add_grid_sub(32, 48, ui, state),
|
PlateFormat::W1536 => add_grid_sub(size, 32, 48, transfers, ui, state),
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue