diff --git a/Cargo.lock b/Cargo.lock index 4ba15bf..9c5c6db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -218,6 +218,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "anyhow" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74f37166d7d48a0284b99dd824694c26119c700b53bf0d1540cdb147dbdaaf13" + [[package]] name = "arboard" version = "3.4.1" @@ -648,10 +654,12 @@ dependencies = [ name = "circle-cipher" version = "0.1.0" dependencies = [ + "anyhow", "clap", "eframe", "egui", "egui_plot", + "rand", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 8830cda..2b51af1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,9 @@ version = "0.1.0" edition = "2021" [dependencies] +anyhow = "1.0.92" clap = { version = "4.5.20", features = ["derive"] } eframe = "0.29.1" egui = "0.29.1" egui_plot = "0.29.0" +rand = "0.8.5" diff --git a/src/cli.rs b/src/cli.rs index e69de29..3b2626b 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -0,0 +1,3 @@ +mod display; + +pub use display::display_plot; diff --git a/src/cli/display.rs b/src/cli/display.rs new file mode 100644 index 0000000..3357f11 --- /dev/null +++ b/src/cli/display.rs @@ -0,0 +1,50 @@ +use rand::Rng; + +pub fn display_plot(circles: Vec) -> anyhow::Result<()> { //TODO: Save Button + let options = eframe::NativeOptions::default(); + eframe::run_native( + "Encoded Message", + options, + Box::new(|_cc| Ok(Box::::new( + PlotDisplay::new(circles, 1000) + ))) + ).map_err(crate::Error::from)?; + Ok(()) +} + +struct PlotDisplay { + circles: Vec, + circle_length: usize, + line_colors: Vec, +} + +impl PlotDisplay { + fn new(circles: Vec, circle_length: usize) -> Self { + let line_colors: Vec = (0..circles.len()) + .map(|_|random_color()).collect(); + Self { + circles, + circle_length, + line_colors, + } + } +} + +impl eframe::App for PlotDisplay { + fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { + egui::CentralPanel::default().show(ctx, |ui| { + crate::plot(ui, &mut self.circles, &self.circle_length, &self.line_colors); + }); + } +} + +fn random_color() -> egui::Color32 { + let mut rng = rand::thread_rng(); + let range = 0..=255; + + egui::Color32::from_rgb( + rng.gen_range(range.clone()), + rng.gen_range(range.clone()), + rng.gen_range(range) + ) +} diff --git a/src/gui.rs b/src/gui.rs index f2ef988..4f4d5cb 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -1,29 +1,46 @@ -struct PlotDisplay { - circles: Vec, - circle_length: usize, +pub fn gui() -> Result<(), eframe::Error> { + let options = eframe::NativeOptions::default(); + eframe::run_native("Encoded Message", options, Box::new(|_cc| Ok(Box::::new( + Default::default() + )))) } -impl PlotDisplay { - fn new(circles: Vec, circle_length: usize) -> Self { - Self { - circles, - circle_length, +struct Gui { + message: Option, + circle_length: Option, +} +impl Default for Gui { + fn default() -> Self { + Self{ + message: None, + circle_length: None, } } } -impl eframe::App for PlotDisplay { //TODO: Define axis ranges + +impl eframe::App for Gui { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { - egui::CentralPanel::default().show(ctx, |ui| { - crate::plot(ui, &mut self.circles, &self.circle_length); + egui::CentralPanel::default().show(ctx, |ui| { + //TODO: UI (on unfocus update values) + // Message Content input + // start shift input + // circle length input + // generate button (if pressed, generate plot with details) }); } } +pub struct Error(eframe::Error); -pub fn display_plot(circles: Vec) -> Result<(), eframe::Error> { - let options = eframe::NativeOptions::default(); - eframe::run_native("Encoded Message", options, Box::new(|_cc| Ok(Box::::new( - PlotDisplay::new(circles, 1000) - )))) +impl From for Error { + fn from(err: eframe::Error) -> Self { + Error(err) + } +} + +impl From for anyhow::Error { + fn from(err: Error) -> Self { + anyhow::anyhow!(err.0.to_string()) + } } diff --git a/src/lib.rs b/src/lib.rs index c2b0a3d..a2ef257 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,14 @@ use clap::{Parser, Subcommand}; use std::path::PathBuf; + mod cli; mod encoding; mod gui; mod message; mod plotting; + #[derive(Parser)] #[command(version, about, long_about = None)] pub struct Args { @@ -38,11 +40,12 @@ pub enum OutputMode { } } - -pub use encoding::encrypt_message; -pub use encoding::circle_to_points; +pub use cli::display_plot; pub use encoding::Circle; -pub use gui::display_plot; +pub use encoding::circle_to_points; +pub use encoding::encrypt_message; +pub use gui::Error; pub use message::Message; pub use plotting::plot; + diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..b8c14a3 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,7 @@ + +fn main() { + let mut message = circle_cipher::Message::new("Hello".to_string(), 12); + let _ = circle_cipher::display_plot( + circle_cipher::encrypt_message(&mut message, &127) + ); +} diff --git a/src/plotting.rs b/src/plotting.rs index 0c948d9..f6f6d84 100644 --- a/src/plotting.rs +++ b/src/plotting.rs @@ -1,11 +1,13 @@ -use egui::Ui; use egui_plot::{Plot, PlotPoints}; use std::f64::{self, consts::PI}; -pub fn plot(ui: &mut Ui, circles: &mut Vec, num_points: &usize) { +pub fn plot(ui: &mut egui::Ui, circles: &mut Vec, num_points: &usize, line_colors: &Vec) { Plot::new("Encoded Message") - .height(500.0) - .width(500.0) + .min_size(ui.available_size()) + .show_axes(false) + .show_grid(false) + .show_x(false) + .show_y(false) .data_aspect(1.0) .view_aspect(1.0) .show(ui, |plot_ui| { @@ -18,8 +20,8 @@ pub fn plot(ui: &mut Ui, circles: &mut Vec, num_points: &usize) { }, }; plot_ui.line(egui_plot::Line::new( - gaussian_distribution(num_points, &points, count) - )); + gaussian_distribution(num_points, &points, &(count as f64)) + ).color(line_colors[count])); }); }); } @@ -37,7 +39,7 @@ fn gaussian_distribution(num_points: &usize, peak_values: &Vec, offset: &f6 radii[j] += peak_value * (-((delta.powf(2.0)) / (2.0 * peak_width.powf(2.0)))).exp(); } } - normalize(&mut radii, &offset); + radii = normalize(&mut radii, &offset); cartesian_to_polar(&radii, &theta) }