From fe8dc62f068b3ba20117b80b0a265f1091125e5c Mon Sep 17 00:00:00 2001 From: Simon Gardling Date: Tue, 29 Mar 2022 14:44:19 -0400 Subject: [PATCH] move stuff from AppSettings --- src/egui_app.rs | 83 +++++++++++++++++++++++----------------------- src/function.rs | 12 +++---- src/parsing.rs | 3 +- src/suggestions.rs | 9 ++--- 4 files changed, 53 insertions(+), 54 deletions(-) diff --git a/src/egui_app.rs b/src/egui_app.rs index a83ec96..74323ab 100644 --- a/src/egui_app.rs +++ b/src/egui_app.rs @@ -233,15 +233,6 @@ cfg_if::cfg_if! { // TODO: find a better name for this #[derive(Copy, Clone)] pub struct AppSettings { - /// Stores whether or not the Help window is open - pub help_open: bool, - - /// Stores whether or not the Info window is open - pub info_open: bool, - - /// Stores whether or not the side panel is shown or not - pub show_side_panel: bool, - /// Stores the type of Rienmann sum that should be calculated pub riemann_sum: Riemann, @@ -257,9 +248,6 @@ pub struct AppSettings { /// Number of rectangles used to calculate integral pub integral_num: usize, - /// Stores whether or not dark mode is enabled - pub dark_mode: bool, - /// Stores whether or not displaying extrema is enabled pub do_extrema: bool, @@ -268,8 +256,6 @@ pub struct AppSettings { /// Stores current plot pixel width pub plot_width: usize, - - pub text_boxes_focused: bool, } impl Default for AppSettings { @@ -277,19 +263,14 @@ impl Default for AppSettings { /// starts up fn default() -> Self { Self { - help_open: true, - info_open: false, - show_side_panel: true, riemann_sum: DEFAULT_RIEMANN, integral_min_x: DEFAULT_MIN_X, integral_max_x: DEFAULT_MAX_X, integral_changed: true, integral_num: DEFAULT_INTEGRAL_NUM, - dark_mode: true, do_extrema: true, do_roots: true, plot_width: 0, - text_boxes_focused: false, } } } @@ -311,6 +292,21 @@ pub struct MathApp { /// took for the last frame (the Duration). Stored in a Tuple. last_info: (Vec>, Duration), + /// Stores whether or not the Help window is open + help_open: bool, + + /// Stores whether or not the Info window is open + info_open: bool, + + /// Stores whether or not dark mode is enabled + dark_mode: bool, + + /// Stores whether or not the text boxes are focused + text_boxes_focused: bool, + + /// Stores whether or not the side panel is shown or not + show_side_panel: bool, + /// Stores settings (pretty self-explanatory) settings: AppSettings, } @@ -322,6 +318,11 @@ impl Default for MathApp { func_strs: vec![String::new()], last_error: Vec::new(), last_info: (vec![None], Duration::ZERO), + help_open: true, + info_open: false, + dark_mode: true, + text_boxes_focused: false, + show_side_panel: true, settings: AppSettings::default(), } } @@ -449,7 +450,7 @@ impl MathApp { let functions_len = self.functions.len(); let mut remove_i: Option = None; - self.settings.text_boxes_focused = false; + self.text_boxes_focused = false; for (i, function) in self.functions.iter_mut().enumerate() { let mut integral_enabled = function.integral; let mut derivative_enabled = function.derivative; @@ -500,7 +501,7 @@ impl MathApp { // If in focus and right arrow key was pressed, apply hint // TODO: change position of cursor if func_edit_focus { - self.settings.text_boxes_focused = true; + self.text_boxes_focused = true; if ui.input().key_down(Key::ArrowRight) { self.func_strs[i] += &hint; } @@ -555,15 +556,14 @@ impl epi::App for MathApp { // start timer let start = instant::Instant::now(); - // Set dark/light mode depending on the variable `self.settings.dark_mode` - ctx.set_visuals(match self.settings.dark_mode { + // Set dark/light mode depending on the variable `self.dark_mode` + ctx.set_visuals(match self.dark_mode { true => Visuals::dark(), false => Visuals::light(), }); - if !self.settings.text_boxes_focused { - self.settings - .show_side_panel + if !self.text_boxes_focused { + self.show_side_panel .bitxor_assign(ctx.input().key_down(Key::H)); } @@ -574,9 +574,9 @@ impl epi::App for MathApp { TopBottomPanel::top("top_bar").show(ctx, |ui| { ui.horizontal(|ui| { // Button in top bar to toggle showing the side panel - self.settings.show_side_panel.bitxor_assign( + self.show_side_panel.bitxor_assign( ui.add(Button::new("Panel")) - .on_hover_text(match self.settings.show_side_panel { + .on_hover_text(match self.show_side_panel { true => "Hide Side Panel", false => "Show Side Panel", }) @@ -594,9 +594,9 @@ impl epi::App for MathApp { } // Toggles opening the Help window - self.settings.help_open.bitxor_assign( + self.help_open.bitxor_assign( ui.add(Button::new("Help")) - .on_hover_text(match self.settings.help_open { + .on_hover_text(match self.help_open { true => "Close Help Window", false => "Open Help Window", }) @@ -604,9 +604,9 @@ impl epi::App for MathApp { ); // Toggles opening the Info window - self.settings.info_open.bitxor_assign( + self.info_open.bitxor_assign( ui.add(Button::new("Info")) - .on_hover_text(match self.settings.info_open { + .on_hover_text(match self.info_open { true => "Close Info Window", false => "Open Info Window", }) @@ -614,12 +614,12 @@ impl epi::App for MathApp { ); // Toggles dark/light mode - self.settings.dark_mode.bitxor_assign( - ui.add(Button::new(match self.settings.dark_mode { + self.dark_mode.bitxor_assign( + ui.add(Button::new(match self.dark_mode { true => "🌞", false => "🌙", })) - .on_hover_text(match self.settings.dark_mode { + .on_hover_text(match self.dark_mode { true => "Turn the Lights on!", false => "Turn the Lights off.", }) @@ -638,7 +638,7 @@ impl epi::App for MathApp { // Help window with information for users Window::new("Help") .default_pos([200.0, 200.0]) - .open(&mut self.settings.help_open) + .open(&mut self.help_open) .resizable(false) .collapsible(false) .show(ctx, |ui| { @@ -668,7 +668,7 @@ impl epi::App for MathApp { // Window with information about the build and current commit Window::new("Info") .default_pos([200.0, 200.0]) - .open(&mut self.settings.info_open) + .open(&mut self.info_open) .resizable(false) .collapsible(false) .show(ctx, |ui| { @@ -676,8 +676,10 @@ impl epi::App for MathApp { }); // If side panel is enabled, show it. - if self.settings.show_side_panel { + if self.show_side_panel { self.side_panel(ctx); + } else { + self.text_boxes_focused = false; } // Referenced in plotting code, but needs to be here so it can be later @@ -703,7 +705,6 @@ impl epi::App for MathApp { if width_changed { self.settings.plot_width = available_width; } - let settings_copy = self.settings; // Create and setup plot Plot::new("plot") @@ -724,7 +725,7 @@ impl epi::App for MathApp { minx_bounds, maxx_bounds, width_changed, - settings_copy, + &self.settings, ) }); @@ -733,7 +734,7 @@ impl epi::App for MathApp { .iter() .enumerate() .filter(|(i, _)| !self.func_strs[*i].is_empty()) - .map(|(_, function)| function.display(plot_ui, settings_copy)) + .map(|(_, function)| function.display(plot_ui, &self.settings)) .collect(); }); }); diff --git a/src/function.rs b/src/function.rs index bf6c70a..cf35e2f 100644 --- a/src/function.rs +++ b/src/function.rs @@ -166,7 +166,7 @@ impl FunctionEntry { /// Does the calculations and stores results in `self.output` pub fn calculate( - &mut self, min_x: f64, max_x: f64, width_changed: bool, settings: AppSettings, + &mut self, min_x: f64, max_x: f64, width_changed: bool, settings: &AppSettings, ) { let resolution: f64 = settings.plot_width as f64 / (max_x.abs() + min_x.abs()); let resolution_iter = resolution_helper(settings.plot_width + 1, min_x, resolution); @@ -291,7 +291,7 @@ impl FunctionEntry { /// Displays the function's output on PlotUI `plot_ui` with settings /// `settings`. Returns an `Option` of the calculated integral - pub fn display(&self, plot_ui: &mut PlotUi, settings: AppSettings) -> Option { + pub fn display(&self, plot_ui: &mut PlotUi, settings: &AppSettings) -> Option { let func_str = self.get_func_str(); let derivative_str = self.function.get_derivative_str(); let step = (settings.integral_min_x - settings.integral_max_x).abs() @@ -360,7 +360,7 @@ impl FunctionEntry { derivative_target: Vec<(f64, f64)>, area_target: f64, min_x: f64, max_x: f64, ) { { - self.calculate(min_x, max_x, true, settings); + self.calculate(min_x, max_x, true, &settings); let settings = settings; let back_target = back_target; assert!(self.output.back.is_some()); @@ -396,19 +396,15 @@ mod tests { integral_num: usize, ) -> AppSettings { crate::egui_app::AppSettings { - help_open: false, - info_open: false, - show_side_panel: false, riemann_sum: sum, integral_min_x, integral_max_x, integral_changed: true, integral_num, - dark_mode: false, do_extrema: false, do_roots: false, plot_width: pixel_width, - text_boxes_focused: false, + ..crate::egui_app::AppSettings::default() } } diff --git a/src/parsing.rs b/src/parsing.rs index 9ca6690..9b9a7af 100644 --- a/src/parsing.rs +++ b/src/parsing.rs @@ -4,7 +4,8 @@ lazy_static::lazy_static! { /// Function returns `f64::NaN` at every x value, which is not displayed. static ref EMPTY_FUNCTION: FlatEx = exmex::parse::("0/0").unwrap(); } - +/// Function that includes f(x), f'(x), f'(x)'s string representation, and +/// f''(x) #[derive(Clone)] pub struct BackingFunction { /// f(x) diff --git a/src/suggestions.rs b/src/suggestions.rs index 85e9e08..891a5ff 100644 --- a/src/suggestions.rs +++ b/src/suggestions.rs @@ -1,6 +1,7 @@ use crate::misc::{chars_take, common_substring}; use std::collections::{HashMap, HashSet}; +/// Generate a hint based on the input `input`, returns an `Option` pub fn generate_hint(input: &str) -> Option { if input.is_empty() { return Some("x^2".to_owned()); @@ -53,6 +54,7 @@ pub fn generate_hint(input: &str) -> Option { None } +/// Creates hashmap used for function name completion fn gen_completion_hashmap(input: Vec) -> HashMap { let mut tuple_list: Vec<(String, String)> = Vec::new(); @@ -112,6 +114,7 @@ fn gen_completion_hashmap(input: Vec) -> HashMap { output } +/// List of supported functions from exmex const SUPPORTED_FUNCTIONS: [&str; 22] = [ "abs", "signum", "sin", "cos", "tan", "asin", "acos", "atan", "sinh", "cosh", "tanh", "floor", "round", "ceil", "trunc", "fract", "exp", "sqrt", "cbrt", "ln", "log2", "log10", @@ -121,6 +124,7 @@ lazy_static::lazy_static! { static ref COMPLETION_HASHMAP: HashMap = gen_completion_hashmap(SUPPORTED_FUNCTIONS.to_vec().iter().map(|ele| ele.to_string() + "(").collect()); } +/// Gets completion from `COMPLETION_HASHMAP` pub fn get_completion(key: String) -> Option { if key.is_empty() { return None; @@ -165,10 +169,7 @@ mod tests { for (key, value) in values { println!("{} + {}", key, value); - assert_eq!( - generate_hint(key).unwrap_or_default(), - value.to_owned() - ); + assert_eq!(generate_hint(key).unwrap_or_default(), value.to_owned()); } }