fixed visual bug. refactored gui

This commit is contained in:
Joshua Perry 2024-11-04 19:54:00 +00:00
parent 1114207f47
commit 1545cc8752
7 changed files with 103 additions and 94 deletions

View File

@ -1,3 +0,0 @@
mod display;
pub use display::display_plot;

View File

@ -1,61 +0,0 @@
use rand::Rng;
pub fn display_plot(circles: Vec<crate::Circle>) -> anyhow::Result<()> { //TODO: Save Button
let options = eframe::NativeOptions::default();
eframe::run_native(
"Encoded Message",
options,
Box::new(|_cc| Ok(Box::<PlotDisplay>::new(
PlotDisplay::new(circles, 1000)
)))
).map_err(crate::Error::from)?;
Ok(())
}
struct PlotDisplay {
circles: Vec<crate::Circle>,
circle_length: usize,
line_colors: Vec<egui::Color32>,
}
impl PlotDisplay {
fn new(circles: Vec<crate::Circle>, circle_length: usize) -> Self {
let line_colors: Vec<egui::Color32> = (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| {
ui.with_layout(egui::Layout::bottom_up(egui::Align::Center), |ui| {
save_button(ui);
crate::plot(ui, &mut self.circles, &self.circle_length, &self.line_colors);
});
});
}
}
fn save_button(ui: &mut egui::Ui) {
if ui.button("Save").clicked() {
//TODO: Open file dialog
// Get destination path
// save screenshot of plot to path
}
}
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)
)
}

View File

@ -1,36 +1,47 @@
mod views;
pub struct Error(eframe::Error); pub struct Error(eframe::Error);
pub fn gui() -> anyhow::Result<()> { pub fn gui(message: &mut crate::Message, circle_length: &mut usize, inputs: bool) -> anyhow::Result<()> {
let options = eframe::NativeOptions::default(); let options = eframe::NativeOptions::default();
eframe::run_native( eframe::run_native(
"Encoded Message", "Encoded Message",
options, options,
Box::new(|_cc| Ok(Box::<Gui>::new( Box::new(|_cc| Ok(Box::<Gui>::new(
Default::default() Gui::new(message, circle_length, inputs)
))) )))
).map_err(crate::Error::from)?; ).map_err(crate::Error::from)?;
Ok(()) Ok(())
} }
#[derive(Default)]
struct Gui { struct Gui<'a> {
message: Option<crate::Message>, display: views::Display<'a>,
circle_length: Option<usize>, }
impl<'a> Gui<'a> {
fn new(message: &'a mut crate::Message, circle_length: &'a mut usize, inputs: bool) -> Self {
let circles = crate::encrypt_message(message, circle_length);
let line_colors: Vec<egui::Color32> = (0..circles.len())
.map(|_|views::random_color()).collect();
Self {
display: match inputs {
true => views::display_gui(),
false => views::display_plot(circles, circle_length, line_colors),
},
}
}
} }
impl eframe::App for Gui { impl eframe::App for Gui<'_> {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| { egui::CentralPanel::default().show(ctx,|ui| {
//TODO: UI (on unfocus update values) (self.display)(ui)
// Message Content input });
// start shift input
// circle length input
// generate button (if pressed, generate plot with details)
});
} }
} }
impl From<eframe::Error> for Error { impl From<eframe::Error> for Error {
fn from(err: eframe::Error) -> Self { fn from(err: eframe::Error) -> Self {
Error(err) Error(err)

43
src/gui/views.rs Normal file
View File

@ -0,0 +1,43 @@
pub fn save_button(ui: &mut egui::Ui) {
if ui.button("Save").clicked() {
//TODO: Open file dialog
//Get destination path
//save screenshot of plot to path
}
}
pub type Display<'a> = Box<dyn FnMut(&mut egui::Ui) + 'a>;
pub fn display_plot<'a>(mut circles: Vec<crate::Circle>, circle_length: &'a usize, line_colors: Vec<egui::Color32>) -> Display<'a> {
Box::new(move |ui| {
ui.with_layout(egui::Layout::bottom_up(egui::Align::Center), |ui| {
save_button(ui);
crate::plot(ui, &mut circles, &circle_length, &line_colors);
});
})
}
pub fn display_gui() -> Display<'static> {
Box::new(move |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 fn random_color() -> egui::Color32 {
use rand::Rng;
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)
)
}

View File

@ -2,23 +2,45 @@ use clap::{Parser, Subcommand};
use std::path::PathBuf; use std::path::PathBuf;
mod cli;
mod encoding; mod encoding;
mod gui; pub mod gui;
mod message; mod message;
mod plotting; mod plotting;
pub fn run() -> anyhow::Result<()> {
let mut args = Args::parse();
let mut message = Message::new(args.message, args.start_shift);
match args.mode {
crate::Mode::Gui => gui::gui(&mut message, &mut args.circle_length, true),
crate::Mode::Encode { output } => encode(
&mut message,
&mut args.circle_length,
output),
}
}
fn encode(message: &mut crate::Message, circle_length: &mut usize, output: crate::OutputMode) -> anyhow::Result<()> {
match output {
crate::OutputMode::Display => crate::gui::gui(message, circle_length, false),
crate::OutputMode::Save { path } => Ok(()), //TODO: Create plot and save
}
}
#[derive(Parser)] #[derive(Parser)]
#[command(version, about, long_about = None)] #[command(version, about, long_about = None)]
pub struct Args { pub struct Args {
/// Which mode to run the program in
#[command(subcommand)] #[command(subcommand)]
pub mode: Mode, pub mode: Mode,
#[arg(short, long)] /// The message to be encrypted
#[arg(short, long, default_value = "")]
pub message: String, pub message: String,
#[arg(short, long)] /// The starting value for the caesar shift
pub start_shift: String, #[arg(short, long, default_value_t = 0)]
#[arg(short, long)] pub start_shift: u8,
/// The number of characters in each circle
#[arg(short, long, default_value_t = 127)]
pub circle_length: usize, pub circle_length: usize,
} }
@ -35,12 +57,11 @@ pub enum Mode {
pub enum OutputMode { pub enum OutputMode {
Display, Display,
Save { Save {
#[arg(short, long)] #[arg(short, long, default_value = "./message")]
path: PathBuf, path: PathBuf,
} }
} }
pub use cli::display_plot;
pub use encoding::caesar_shift; pub use encoding::caesar_shift;
pub use encoding::Circle; pub use encoding::Circle;
pub use encoding::circle_to_points; pub use encoding::circle_to_points;

View File

@ -1,7 +1,3 @@
fn main() -> anyhow::Result<()> {
fn main() { circle_cipher::run()
let mut message = circle_cipher::Message::new("Hello".to_string(), 12);
let _ = circle_cipher::display_plot(
circle_cipher::encrypt_message(&mut message, &127)
);
} }

View File

@ -1,5 +1,6 @@
use std::vec::IntoIter; use std::vec::IntoIter;
#[derive(Clone)]
pub struct Message { pub struct Message {
pub parts: Parts, pub parts: Parts,
pub combined: String, pub combined: String,
@ -24,6 +25,7 @@ impl Message {
).collect() ).collect()
} }
} }
#[derive(Clone)]
pub struct Parts { pub struct Parts {
pub content: String, pub content: String,
pub start_shift: u8, pub start_shift: u8,