diff --git a/Cargo.lock b/Cargo.lock index 46d8086..5011439 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -91,6 +91,8 @@ dependencies = [ "gls", "gtk4", "libadwaita", + "serde", + "serde_json", ] [[package]] @@ -439,6 +441,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + [[package]] name = "khronos_api" version = "3.1.0" @@ -709,6 +717,12 @@ dependencies = [ "semver", ] +[[package]] +name = "ryu" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" + [[package]] name = "safe_arch" version = "0.6.0" @@ -738,24 +752,35 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.132" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.132" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "serde_json" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "simba" version = "0.7.0" diff --git a/Cargo.toml b/Cargo.toml index 47bad50..b955ebb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,9 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -adw = { version = "0.1.0", package = "libadwaita" } +adw = { version = "0.1", package = "libadwaita" } gtk = { version = "0.4", package = "gtk4" } -gls = { version = "0.1.6" } +gls = { version = "0.1" } +serde = { version = "1.0", features = ["derive"]} +serde_json = { version = "1.0" } diff --git a/src/main.rs b/src/main.rs index be10aab..121c5f9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,16 @@ use std::cell::Cell; use std::sync::Arc; +use std::fs; + +use serde::{Deserialize, Serialize}; use adw::{prelude::*, ApplicationWindow, HeaderBar, SplitButton}; use gio::SimpleAction; use glib::clone; use gtk::{gio, glib, FileChooserAction, FileChooserDialog, ResponseType}; use gtk::{ - ActionBar, Application, AspectFrame, Box, Button, Grid, Image, Orientation, PositionType, - Scale, Separator, ToggleButton, + ActionBar, Application, AspectFrame, Box, Button, FileFilter, Grid, Image, Orientation, + PositionType, Scale, Separator, ToggleButton, }; const MARGIN_TOP: i32 = 32; @@ -22,7 +25,7 @@ const TOGGLE_NEIGHBOURS_TEXT: &str = "Show Neighbours"; const SCALE_STEP: f64 = 1.0; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize, Deserialize)] struct AnnotationZStack { images: Vec, best_index: Option, @@ -44,7 +47,7 @@ impl AnnotationZStack { } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize, Deserialize)] struct AnnotationImage { image_path: String, neighbours: [Option; 8], @@ -178,9 +181,14 @@ fn previous_image( ); } -fn save_annotation(z_stack: AnnotationZStack) { +fn save_annotation(annotation_dataset: &Vec) { // TODO: implement saving - eprintln!("Saving is not implemented yet!") + 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() { @@ -434,15 +442,32 @@ fn main() { .content(&application_vertical_widget) .build(); + let file_chooser_action = FileChooserAction::Open; + let buttons = [("Open", ResponseType::Ok), ("Cancel", ResponseType::Cancel)]; + let filter = FileFilter::new(); + filter.add_pattern(r"*.json"); + + let file_chooser = FileChooserDialog::new(Some("Chose a data file!"), Some(&window), file_chooser_action, &buttons); + file_chooser.set_select_multiple(false); + file_chooser.set_filter(&filter); + + file_chooser.connect_response(clone!(@strong annotaion_dataset => move |dialog: &FileChooserDialog, response: ResponseType| { + if response == ResponseType::Ok { + let file = dialog.file().expect("Couldn't get file"); + eprintln!("Open"); + 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 dataset : Vec = serde_json::from_str(&contents).unwrap(); + // TODO: update data after loading + } + dialog.close(); + })); open_button.connect_clicked(clone!(@weak window => move |_| { - let file_chooser_action = FileChooserAction::Open; - // TODO: actually open and load data - - let buttons = [("Open", ResponseType::Accept)]; - let file_chooser = FileChooserDialog::new(Some("Chose a data file!"), Some(&window), file_chooser_action, &buttons); file_chooser.show(); + })); //////////////////////// @@ -469,9 +494,7 @@ fn main() { eprintln! {"Focus Set!"}; let index = current_z_stack_index.as_ref().get(); - let mut z_stack = annotaion_dataset.get(index).unwrap().clone(); - z_stack.best_index = Some(focus_scale.value() as usize); - save_annotation(z_stack); + save_annotation(&annotaion_dataset); next_image(current_z_stack_index.clone().as_ref(), annotaion_dataset.clone(), focus_scale.as_ref(), image_ui.as_ref()); }));