mirror of
https://github.com/13hannes11/focus_annotator.git
synced 2024-09-03 23:21:01 +02:00
refactor program and ui to be in separate structs
This commit is contained in:
289
src/main.rs
289
src/main.rs
@@ -5,9 +5,9 @@ pub use crate::state::AnnotationImage;
|
|||||||
pub use crate::constants::MARGIN_BOTTOM;
|
pub use crate::constants::MARGIN_BOTTOM;
|
||||||
|
|
||||||
|
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{RefCell};
|
||||||
use std::sync::{Arc};
|
use std::sync::{Arc};
|
||||||
use std::fs;
|
use std::{fs};
|
||||||
|
|
||||||
use adw::{prelude::*, ApplicationWindow, HeaderBar, SplitButton};
|
use adw::{prelude::*, ApplicationWindow, HeaderBar, SplitButton};
|
||||||
use constants::{MARGIN_TOP, MARGIN_LEFT, MARGIN_RIGHT_SCALE_ADDITIONAL, TOGGLE_NEIGHBOURS_TEXT, TOGGLE_NEIGHBOURS_TEXT_TOGGLED, SCALE_STEP};
|
use constants::{MARGIN_TOP, MARGIN_LEFT, MARGIN_RIGHT_SCALE_ADDITIONAL, TOGGLE_NEIGHBOURS_TEXT, TOGGLE_NEIGHBOURS_TEXT_TOGGLED, SCALE_STEP};
|
||||||
@@ -18,13 +18,14 @@ use gtk::{
|
|||||||
ActionBar, Application, AspectFrame, Box, Button, FileFilter, Grid, Image, Orientation,
|
ActionBar, Application, AspectFrame, Box, Button, FileFilter, Grid, Image, Orientation,
|
||||||
PositionType, Scale, Separator, ToggleButton,
|
PositionType, Scale, Separator, ToggleButton,
|
||||||
};
|
};
|
||||||
use state::AnnotationZStack;
|
use state::{AnnotationZStack, State};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct ImageUI {
|
struct ImageUI {
|
||||||
individual: Arc<Image>,
|
individual: Arc<Image>,
|
||||||
center: Arc<Image>,
|
center: Arc<Image>,
|
||||||
neighbours: [Arc<Image>; 8],
|
neighbours: [Arc<Image>; 8],
|
||||||
|
focus_scale: Arc<Scale>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ImageUI {
|
impl ImageUI {
|
||||||
@@ -41,14 +42,34 @@ impl ImageUI {
|
|||||||
Arc::new(Image::builder().vexpand(true).hexpand(true).build()),
|
Arc::new(Image::builder().vexpand(true).hexpand(true).build()),
|
||||||
Arc::new(Image::builder().vexpand(true).hexpand(true).build()),
|
Arc::new(Image::builder().vexpand(true).hexpand(true).build()),
|
||||||
];
|
];
|
||||||
|
let focus_scale = Arc::new(
|
||||||
|
Scale::builder()
|
||||||
|
.orientation(Orientation::Vertical)
|
||||||
|
.vexpand(true)
|
||||||
|
.margin_top(MARGIN_TOP)
|
||||||
|
.margin_bottom(MARGIN_BOTTOM)
|
||||||
|
.margin_start(MARGIN_LEFT)
|
||||||
|
.draw_value(true)
|
||||||
|
.inverted(true)
|
||||||
|
.round_digits(0)
|
||||||
|
.digits(0)
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
|
||||||
ImageUI {
|
ImageUI {
|
||||||
individual,
|
individual,
|
||||||
center,
|
center,
|
||||||
neighbours,
|
neighbours,
|
||||||
|
focus_scale,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn update_image(&self, annotation_image: &AnnotationImage) {
|
pub fn update(&self, state : &State) {
|
||||||
|
if let Some(annotation_image) = state.get_current_annotation_image() {
|
||||||
|
self.update_image(&annotation_image);
|
||||||
|
}
|
||||||
|
self.update_focus_scale(&state);
|
||||||
|
}
|
||||||
|
fn update_image(&self, annotation_image: &AnnotationImage) {
|
||||||
self.individual
|
self.individual
|
||||||
.set_from_file(Some(annotation_image.image_path.clone()));
|
.set_from_file(Some(annotation_image.image_path.clone()));
|
||||||
self.center
|
self.center
|
||||||
@@ -58,92 +79,32 @@ impl ImageUI {
|
|||||||
self.neighbours[index].set_from_file(annotation_image.neighbours[index].clone());
|
self.neighbours[index].set_from_file(annotation_image.neighbours[index].clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn update_focus_scale(focus_scale: &Scale, z_stack: AnnotationZStack) {
|
fn update_focus_scale(&self, state: &State) {
|
||||||
let max = (z_stack.images.len() - 1) as f64;
|
let max = state.get_current_foucs_stack_max().unwrap_or(0) as f64;
|
||||||
focus_scale.set_range(0.0, max);
|
self.focus_scale.set_range(0.0, max);
|
||||||
focus_scale.set_value(f64::floor(max / 2.0));
|
|
||||||
|
|
||||||
if z_stack.best_index.is_some() {
|
if let Some(best_index) = state.get_current_foucs_stack_best_index() {
|
||||||
focus_scale.add_mark(
|
self.focus_scale.clear_marks();
|
||||||
z_stack.best_index.unwrap() as f64,
|
self.focus_scale.add_mark(
|
||||||
PositionType::Right,
|
best_index as f64,
|
||||||
Some("focus"),
|
PositionType::Right,
|
||||||
);
|
Some("focus"),
|
||||||
focus_scale.set_margin_end(0);
|
);
|
||||||
} else {
|
self.focus_scale.set_margin_end(0);
|
||||||
focus_scale.clear_marks();
|
} else {
|
||||||
focus_scale.set_margin_end(MARGIN_RIGHT_SCALE_ADDITIONAL);
|
self.focus_scale.clear_marks();
|
||||||
|
self.focus_scale.set_margin_end(MARGIN_RIGHT_SCALE_ADDITIONAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(current_value) = state.image_index {
|
||||||
|
self.focus_scale.set_value(current_value as f64);
|
||||||
|
} else {
|
||||||
|
self.focus_scale.set_value(f64::floor(max / 2.0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn change_image(
|
|
||||||
direction: i32,
|
|
||||||
current_z_stack_index: &Cell<usize>,
|
|
||||||
annotaion_dataset: &Vec<AnnotationZStack>,
|
|
||||||
focus_scale: &Scale,
|
|
||||||
image_ui: &ImageUI,
|
|
||||||
) {
|
|
||||||
let index = current_z_stack_index.get() as i32 + direction;
|
|
||||||
|
|
||||||
eprintln!("Index after {index}");
|
|
||||||
// Makes sure we are not overstepping bounds
|
|
||||||
let index = if index < annotaion_dataset.len() as i32 && index >= 0 {
|
|
||||||
current_z_stack_index.set(index.try_into().unwrap_or(0));
|
|
||||||
index as usize
|
|
||||||
} else {
|
|
||||||
current_z_stack_index.get()
|
|
||||||
};
|
|
||||||
eprintln!("Index after {index}");
|
|
||||||
|
|
||||||
let z_stack = annotaion_dataset[index].clone();
|
|
||||||
update_focus_scale(&focus_scale, z_stack);
|
|
||||||
|
|
||||||
let img = annotaion_dataset[index].images[focus_scale.value() as usize].clone();
|
|
||||||
image_ui.update_image(&img);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn next_image(
|
|
||||||
current_z_stack_index: &Cell<usize>,
|
|
||||||
annotaion_dataset: &Vec<AnnotationZStack>,
|
|
||||||
focus_scale: &Scale,
|
|
||||||
image_ui: &ImageUI,
|
|
||||||
) {
|
|
||||||
change_image(
|
|
||||||
1,
|
|
||||||
current_z_stack_index,
|
|
||||||
annotaion_dataset,
|
|
||||||
focus_scale,
|
|
||||||
image_ui,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn previous_image(
|
|
||||||
current_z_stack_index: &Cell<usize>,
|
|
||||||
annotaion_dataset: &Vec<AnnotationZStack>,
|
|
||||||
focus_scale: &Scale,
|
|
||||||
image_ui: &ImageUI,
|
|
||||||
) {
|
|
||||||
change_image(
|
|
||||||
-1,
|
|
||||||
current_z_stack_index,
|
|
||||||
annotaion_dataset,
|
|
||||||
focus_scale,
|
|
||||||
image_ui,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn save_annotation(annotation_dataset: &Vec<AnnotationZStack>) {
|
|
||||||
// TODO: implement saving
|
|
||||||
eprintln!("Saving is not implemented yet!");
|
|
||||||
// Serialize it to a JSON string.
|
|
||||||
let j = serde_json::to_string(&annotation_dataset).unwrap();
|
|
||||||
|
|
||||||
// Print, write to a file, or send to an HTTP server.
|
|
||||||
eprintln!("{}", &j);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let application = Application::builder()
|
let application = Application::builder()
|
||||||
.application_id("org.kuchelmeister.FocusAnnotator")
|
.application_id("org.kuchelmeister.FocusAnnotator")
|
||||||
@@ -170,94 +131,15 @@ fn setup_shortcuts(app: &Application) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn build_ui(app: &Application) {
|
fn build_ui(app: &Application) {
|
||||||
let current_z_stack_index = Arc::new(Cell::new(0));
|
|
||||||
let annotaion_dataset = Arc::new(RefCell::new(Vec::<AnnotationZStack>::new()));
|
|
||||||
|
|
||||||
let mut z_stack = AnnotationZStack::new();
|
let state = Arc::new(RefCell::new(State::new()));
|
||||||
|
|
||||||
let path = "/var/home/hannes/Documents/toolbox/python/thesis/focus_metrics_test/img/31/I03987/I03987_X008_Y026_Z5498_0_1200.jpg";
|
|
||||||
z_stack.push(AnnotationImage::from_vec(
|
|
||||||
path.to_string(),
|
|
||||||
vec![
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
Some("/var/home/hannes/Documents/toolbox/python/thesis/focus_metrics_test/img/31/I03987/I03987_X008_Y026_Z5498_0_1125.jpg".to_string()),
|
|
||||||
None,
|
|
||||||
Some("/var/home/hannes/Documents/toolbox/python/thesis/focus_metrics_test/img/31/I03987/I03987_X008_Y026_Z5498_75_1125.jpg".to_string()),
|
|
||||||
Some("/var/home/hannes/Documents/toolbox/python/thesis/focus_metrics_test/img/31/I03987/I03987_X008_Y026_Z5498_75_1200.jpg".to_string()),
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
],
|
|
||||||
));
|
|
||||||
|
|
||||||
let path = "/var/home/hannes/Documents/toolbox/python/thesis/focus_metrics_test/img/31/I03988/I03988_X008_Y026_Z5566_0_1200.jpg";
|
|
||||||
z_stack.push(AnnotationImage::from_vec(
|
|
||||||
path.to_string(),
|
|
||||||
vec![
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
Some("/var/home/hannes/Documents/toolbox/python/thesis/focus_metrics_test/img/31/I03988/I03988_X008_Y026_Z5566_0_1125.jpg".to_string()),
|
|
||||||
None,
|
|
||||||
Some("/var/home/hannes/Documents/toolbox/python/thesis/focus_metrics_test/img/31/I03988/I03988_X008_Y026_Z5566_75_1125.jpg".to_string()),
|
|
||||||
Some("/var/home/hannes/Documents/toolbox/python/thesis/focus_metrics_test/img/31/I03988/I03988_X008_Y026_Z5566_75_1200.jpg".to_string()),
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
],
|
|
||||||
));
|
|
||||||
|
|
||||||
let path = "/var/home/hannes/Documents/toolbox/python/thesis/focus_metrics_test/img/31/I03989/I03989_X008_Y026_Z5703_0_1200.jpg";
|
|
||||||
z_stack.push(AnnotationImage::from_vec(
|
|
||||||
path.to_string(),
|
|
||||||
vec![
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
Some("/var/home/hannes/Documents/toolbox/python/thesis/focus_metrics_test/img/31/I03989/I03989_X008_Y026_Z5703_0_1125.jpg".to_string()),
|
|
||||||
None,
|
|
||||||
Some("/var/home/hannes/Documents/toolbox/python/thesis/focus_metrics_test/img/31/I03989/I03989_X008_Y026_Z5703_75_1125.jpg".to_string()),
|
|
||||||
Some("/var/home/hannes/Documents/toolbox/python/thesis/focus_metrics_test/img/31/I03989/I03989_X008_Y026_Z5703_75_1200.jpg".to_string()),
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
],
|
|
||||||
));
|
|
||||||
|
|
||||||
annotaion_dataset.borrow_mut().push(z_stack.clone());
|
|
||||||
|
|
||||||
{
|
|
||||||
let mut z_stack = AnnotationZStack::new();
|
|
||||||
|
|
||||||
z_stack.best_index = Some(0);
|
|
||||||
|
|
||||||
let path = "/var/home/hannes/Documents/toolbox/python/thesis/focus_metrics_test/img/30_753da05d-cd1e-45c5-8593-003323e0bb69_I00243_X013_Y003_Z4648.jpg";
|
|
||||||
z_stack.push(AnnotationImage::from_vec(
|
|
||||||
path.to_string(),
|
|
||||||
vec![
|
|
||||||
Some("/var/home/hannes/Documents/toolbox/python/thesis/focus_metrics_test/img/30_753da05d-cd1e-45c5-8593-003323e0bb69_I00243_X013_Y003_Z4648.jpg".to_string()),
|
|
||||||
Some("/var/home/hannes/Documents/toolbox/python/thesis/focus_metrics_test/img/30_753da05d-cd1e-45c5-8593-003323e0bb69_I00243_X013_Y003_Z4648.jpg".to_string()),
|
|
||||||
Some("/var/home/hannes/Documents/toolbox/python/thesis/focus_metrics_test/img/30_753da05d-cd1e-45c5-8593-003323e0bb69_I00243_X013_Y003_Z4648.jpg".to_string()),
|
|
||||||
Some("/var/home/hannes/Documents/toolbox/python/thesis/focus_metrics_test/img/30_753da05d-cd1e-45c5-8593-003323e0bb69_I00243_X013_Y003_Z4648.jpg".to_string()),
|
|
||||||
Some("/var/home/hannes/Documents/toolbox/python/thesis/focus_metrics_test/img/30_753da05d-cd1e-45c5-8593-003323e0bb69_I00243_X013_Y003_Z4648.jpg".to_string()),
|
|
||||||
Some("/var/home/hannes/Documents/toolbox/python/thesis/focus_metrics_test/img/30_753da05d-cd1e-45c5-8593-003323e0bb69_I00243_X013_Y003_Z4648.jpg".to_string()),
|
|
||||||
Some("/var/home/hannes/Documents/toolbox/python/thesis/focus_metrics_test/img/30_753da05d-cd1e-45c5-8593-003323e0bb69_I00243_X013_Y003_Z4648.jpg".to_string()),
|
|
||||||
Some("/var/home/hannes/Documents/toolbox/python/thesis/focus_metrics_test/img/30_753da05d-cd1e-45c5-8593-003323e0bb69_I00243_X013_Y003_Z4648.jpg".to_string()),
|
|
||||||
Some("/var/home/hannes/Documents/toolbox/python/thesis/focus_metrics_test/img/30_753da05d-cd1e-45c5-8593-003323e0bb69_I00243_X013_Y003_Z4648.jpg".to_string()),
|
|
||||||
],
|
|
||||||
));
|
|
||||||
|
|
||||||
annotaion_dataset.borrow_mut().push(z_stack.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////
|
//////////////////
|
||||||
// MAIN CONTENT //
|
// MAIN CONTENT //
|
||||||
//////////////////
|
//////////////////
|
||||||
|
|
||||||
let image_ui = Arc::new(ImageUI::new());
|
let image_ui = Arc::new(ImageUI::new());
|
||||||
|
image_ui.update(&(state.as_ref().borrow()));
|
||||||
image_ui
|
|
||||||
.as_ref()
|
|
||||||
.update_image(&z_stack.clone().first().unwrap());
|
|
||||||
|
|
||||||
let focus_neighbours_grid = Arc::new(
|
let focus_neighbours_grid = Arc::new(
|
||||||
Grid::builder()
|
Grid::builder()
|
||||||
@@ -288,21 +170,9 @@ fn build_ui(app: &Application) {
|
|||||||
eprintln!("{column} {row}");
|
eprintln!("{column} {row}");
|
||||||
}
|
}
|
||||||
|
|
||||||
let focus_scale = Arc::new(
|
//let focus_scale = image_ui.focus_scale.clone();
|
||||||
Scale::builder()
|
|
||||||
.orientation(Orientation::Vertical)
|
|
||||||
.vexpand(true)
|
|
||||||
.margin_top(MARGIN_TOP)
|
|
||||||
.margin_bottom(MARGIN_BOTTOM)
|
|
||||||
.margin_start(MARGIN_LEFT)
|
|
||||||
.draw_value(true)
|
|
||||||
.inverted(true)
|
|
||||||
.round_digits(0)
|
|
||||||
.digits(0)
|
|
||||||
.build(),
|
|
||||||
);
|
|
||||||
|
|
||||||
update_focus_scale(focus_scale.as_ref(), z_stack.clone());
|
// update_focus_scale(focus_scale.as_ref(), z_stack.clone());
|
||||||
|
|
||||||
let center_content_seperator = Separator::new(Orientation::Vertical);
|
let center_content_seperator = Separator::new(Orientation::Vertical);
|
||||||
let center_content = Box::builder()
|
let center_content = Box::builder()
|
||||||
@@ -311,14 +181,14 @@ fn build_ui(app: &Application) {
|
|||||||
.spacing(0)
|
.spacing(0)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
center_content.append(focus_scale.as_ref());
|
center_content.append(image_ui.focus_scale.as_ref());
|
||||||
center_content.append(¢er_content_seperator);
|
center_content.append(¢er_content_seperator);
|
||||||
center_content.append(&focus_neighbours_aspect_frame);
|
center_content.append(&focus_neighbours_aspect_frame);
|
||||||
|
|
||||||
focus_scale.connect_value_changed(clone!(@strong image_ui, @strong z_stack => move |x| {
|
image_ui.focus_scale.connect_value_changed(clone!(@strong image_ui, @strong state => move |x| {
|
||||||
let index = x.value() as usize;
|
let index = x.value() as usize;
|
||||||
let img = z_stack.images[index].clone();
|
state.borrow_mut().set_image_index(Some(index));
|
||||||
image_ui.update_image(&img);
|
image_ui.update(&state.borrow());
|
||||||
}));
|
}));
|
||||||
|
|
||||||
////////////
|
////////////
|
||||||
@@ -411,7 +281,7 @@ fn build_ui(app: &Application) {
|
|||||||
.content(&application_vertical_widget)
|
.content(&application_vertical_widget)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
open_button.connect_clicked(clone!(@weak window, @weak annotaion_dataset => move |_| {
|
open_button.connect_clicked(clone!(@weak window, @strong image_ui, @strong state => move |_| {
|
||||||
// TODO: actually open and load data
|
// TODO: actually open and load data
|
||||||
|
|
||||||
|
|
||||||
@@ -424,19 +294,19 @@ fn build_ui(app: &Application) {
|
|||||||
file_chooser.set_select_multiple(false);
|
file_chooser.set_select_multiple(false);
|
||||||
file_chooser.set_filter(&filter);
|
file_chooser.set_filter(&filter);
|
||||||
|
|
||||||
file_chooser.connect_response(clone!(@weak window, @weak annotaion_dataset => move |dialog: &FileChooserDialog, response: ResponseType| {
|
file_chooser.connect_response(clone!(@weak window, @strong image_ui, @weak state => move |dialog: &FileChooserDialog, response: ResponseType| {
|
||||||
if response == ResponseType::Ok {
|
if response == ResponseType::Ok {
|
||||||
let file = dialog.file().expect("Couldn't get file");
|
let file = dialog.file().expect("Couldn't get file");
|
||||||
eprintln!("Open");
|
eprintln!("Open");
|
||||||
let filename = file.path().expect("Couldn't get file path");
|
let filename = file.path().expect("Couldn't get file path");
|
||||||
let contents = fs::read_to_string(filename).expect("Something went wrong reading the file");
|
let contents = fs::read_to_string(filename).expect("Something went wrong reading the file");
|
||||||
|
|
||||||
let mut new_dataset : Vec<AnnotationZStack> = serde_json::from_str(&contents).unwrap();
|
|
||||||
eprintln!("{}", contents);
|
eprintln!("{}", contents);
|
||||||
|
|
||||||
let mut dataset = annotaion_dataset.borrow_mut();
|
let new_dataset : Vec<AnnotationZStack> = serde_json::from_str(&contents).unwrap();
|
||||||
dataset.clear();
|
let mut state = state.borrow_mut();
|
||||||
dataset.append(&mut new_dataset);
|
|
||||||
|
state.replace_foucs_stacks(new_dataset);
|
||||||
|
image_ui.update(&state);
|
||||||
}
|
}
|
||||||
dialog.close();
|
dialog.close();
|
||||||
}));
|
}));
|
||||||
@@ -455,36 +325,37 @@ fn build_ui(app: &Application) {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
let action_focus_scale_increment = SimpleAction::new("increment_focus_scale", None);
|
let action_focus_scale_increment = SimpleAction::new("increment_focus_scale", None);
|
||||||
action_focus_scale_increment.connect_activate(clone!(@strong focus_scale => move |_, _| {
|
action_focus_scale_increment.connect_activate(clone!(@strong image_ui => move |_, _| {
|
||||||
focus_scale.set_value(focus_scale.value() + SCALE_STEP);
|
image_ui.focus_scale.set_value(image_ui.focus_scale.value() + SCALE_STEP);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let action_focus_scale_decrement = SimpleAction::new("decrement_focus_scale", None);
|
let action_focus_scale_decrement = SimpleAction::new("decrement_focus_scale", None);
|
||||||
action_focus_scale_decrement.connect_activate(clone!(@strong focus_scale => move |_, _| {
|
action_focus_scale_decrement.connect_activate(clone!(@strong image_ui => move |_, _| {
|
||||||
focus_scale.set_value(focus_scale.value() - SCALE_STEP);
|
image_ui.focus_scale.set_value(image_ui.focus_scale.value() - SCALE_STEP);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let mark_focus = SimpleAction::new("mark_focus", None);
|
let mark_focus = SimpleAction::new("mark_focus", None);
|
||||||
mark_focus.connect_activate(clone!(@strong image_ui, @strong focus_scale, @strong current_z_stack_index, @strong annotaion_dataset => move |_, _| {
|
mark_focus.connect_activate(clone!(@strong image_ui, @strong state => move |_, _| {
|
||||||
eprintln! {"Focus Set!"};
|
eprintln! {"Focus Set!"};
|
||||||
let index = current_z_stack_index.as_ref().get();
|
|
||||||
let mut dataset = annotaion_dataset.borrow_mut();
|
let mut state = state.borrow_mut();
|
||||||
dataset[index].best_index = Some(focus_scale.value() as usize);
|
state.mark_focus();
|
||||||
|
state.skip();
|
||||||
save_annotation(&dataset);
|
image_ui.update(&state);
|
||||||
next_image(current_z_stack_index.clone().as_ref(), &dataset, focus_scale.as_ref(), image_ui.as_ref());
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let skip_focus = SimpleAction::new("skip_focus", None);
|
let skip_focus = SimpleAction::new("skip_focus", None);
|
||||||
skip_focus.connect_activate(clone!(@strong image_ui, @strong focus_scale, @strong current_z_stack_index, @strong annotaion_dataset => move |_, _| {
|
skip_focus.connect_activate(clone!(@strong image_ui, @strong state => move |_, _| {
|
||||||
let dataset = annotaion_dataset.borrow_mut();
|
let mut state = state.borrow_mut();
|
||||||
next_image(current_z_stack_index.clone().as_ref(), &dataset, focus_scale.as_ref(), image_ui.as_ref());
|
state.skip();
|
||||||
|
image_ui.update(&state);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let back_focus = SimpleAction::new("back_focus", None);
|
let back_focus = SimpleAction::new("back_focus", None);
|
||||||
back_focus.connect_activate(clone!(@strong image_ui, @strong focus_scale, @strong current_z_stack_index, @strong annotaion_dataset => move |_, _| {
|
back_focus.connect_activate(clone!(@strong image_ui, @strong state => move |_, _| {
|
||||||
let dataset = annotaion_dataset.borrow_mut();
|
let mut state = state.borrow_mut();
|
||||||
previous_image(current_z_stack_index.clone().as_ref(), &dataset, focus_scale.as_ref(), image_ui.as_ref());
|
state.previous();
|
||||||
|
image_ui.update(&state);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
window.add_action(&action_toggle_neighbour);
|
window.add_action(&action_toggle_neighbour);
|
||||||
|
|||||||
115
src/state/mod.rs
115
src/state/mod.rs
@@ -1,6 +1,105 @@
|
|||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
use crate::constants::NONE_STRING_OPTION;
|
use crate::constants::NONE_STRING_OPTION;
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct State{
|
||||||
|
stacks: Vec<AnnotationZStack>,
|
||||||
|
stack_index: Option<usize>,
|
||||||
|
pub image_index: Option<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl State {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
State{
|
||||||
|
stacks: Vec::new(),
|
||||||
|
stack_index: None,
|
||||||
|
image_index: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn set_image_index(&mut self, image_index : Option<usize>) {
|
||||||
|
self.image_index = image_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_current_annotation_image(&self) -> Option<AnnotationImage>{
|
||||||
|
match self.image_index {
|
||||||
|
Some(image_index) => {
|
||||||
|
let stack = self.get_current_focus_stack();
|
||||||
|
match stack {
|
||||||
|
Some(stack) => {
|
||||||
|
stack.images.get(image_index).map(|x| x.clone())
|
||||||
|
},
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_current_focus_stack(&self) -> Option<&AnnotationZStack> {
|
||||||
|
match self.stack_index {
|
||||||
|
Some(stack_index) => {
|
||||||
|
self.stacks.get(stack_index)
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn replace_foucs_stacks(&mut self, mut stacks : Vec<AnnotationZStack>){
|
||||||
|
self.stacks.clear();
|
||||||
|
self.stacks.append(&mut stacks);
|
||||||
|
eprintln!("{}", stacks.len());
|
||||||
|
|
||||||
|
if let Some(z_stack) = self.stacks.first() {
|
||||||
|
self.stack_index = Some(0);
|
||||||
|
self.image_index = if let Some(_) = z_stack.images.first() {
|
||||||
|
Some(0)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.stack_index = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn get_current_foucs_stack_max(&self) -> Option<usize> {
|
||||||
|
self.get_current_focus_stack().map(|x| x.images.len() - 1)
|
||||||
|
}
|
||||||
|
pub fn get_current_foucs_stack_best_index(&self) -> Option<usize> {
|
||||||
|
match self.get_current_focus_stack() {
|
||||||
|
Some(stack) => stack.best_index,
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn skip(&mut self) {
|
||||||
|
let len = self.stacks.len();
|
||||||
|
if len == 0 {
|
||||||
|
self.stack_index = None;
|
||||||
|
} else if self.stack_index.map_or_else(|| false, |x| {x + 1 < len}) {
|
||||||
|
self.stack_index = self.stack_index.map(|x| x+1)
|
||||||
|
}
|
||||||
|
|
||||||
|
eprintln!("{:?}", self.stack_index)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mark_focus(&mut self) {
|
||||||
|
match (self.stack_index, self.image_index) {
|
||||||
|
(Some(stack_index), Some(_)) => {
|
||||||
|
self.stacks[stack_index].best_index = self.image_index;
|
||||||
|
}
|
||||||
|
(_, _) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn previous(&mut self) {
|
||||||
|
let len = self.stacks.len();
|
||||||
|
if len == 0 {
|
||||||
|
self.stack_index = None;
|
||||||
|
} else if self.stack_index.map_or_else(|| false, |x| x > 0) {
|
||||||
|
self.stack_index = self.stack_index.map(|x| x-1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct AnnotationZStack {
|
pub struct AnnotationZStack {
|
||||||
@@ -8,22 +107,6 @@ use crate::constants::NONE_STRING_OPTION;
|
|||||||
pub best_index: Option<usize>,
|
pub best_index: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AnnotationZStack {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
AnnotationZStack {
|
|
||||||
images: Vec::<AnnotationImage>::new(),
|
|
||||||
best_index: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn push(&mut self, image: AnnotationImage) -> &mut Self {
|
|
||||||
self.images.push(image);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
pub fn first(self) -> Option<AnnotationImage> {
|
|
||||||
self.images.first().map(|x| x.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct AnnotationImage {
|
pub struct AnnotationImage {
|
||||||
pub image_path: String,
|
pub image_path: String,
|
||||||
|
|||||||
Reference in New Issue
Block a user