move stuff from AppSettings

This commit is contained in:
Simon Gardling 2022-03-29 14:44:19 -04:00
parent bb91dc5983
commit fe8dc62f06
4 changed files with 53 additions and 54 deletions

View File

@ -233,15 +233,6 @@ cfg_if::cfg_if! {
// TODO: find a better name for this // TODO: find a better name for this
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct AppSettings { 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 /// Stores the type of Rienmann sum that should be calculated
pub riemann_sum: Riemann, pub riemann_sum: Riemann,
@ -257,9 +248,6 @@ pub struct AppSettings {
/// Number of rectangles used to calculate integral /// Number of rectangles used to calculate integral
pub integral_num: usize, pub integral_num: usize,
/// Stores whether or not dark mode is enabled
pub dark_mode: bool,
/// Stores whether or not displaying extrema is enabled /// Stores whether or not displaying extrema is enabled
pub do_extrema: bool, pub do_extrema: bool,
@ -268,8 +256,6 @@ pub struct AppSettings {
/// Stores current plot pixel width /// Stores current plot pixel width
pub plot_width: usize, pub plot_width: usize,
pub text_boxes_focused: bool,
} }
impl Default for AppSettings { impl Default for AppSettings {
@ -277,19 +263,14 @@ impl Default for AppSettings {
/// starts up /// starts up
fn default() -> Self { fn default() -> Self {
Self { Self {
help_open: true,
info_open: false,
show_side_panel: true,
riemann_sum: DEFAULT_RIEMANN, riemann_sum: DEFAULT_RIEMANN,
integral_min_x: DEFAULT_MIN_X, integral_min_x: DEFAULT_MIN_X,
integral_max_x: DEFAULT_MAX_X, integral_max_x: DEFAULT_MAX_X,
integral_changed: true, integral_changed: true,
integral_num: DEFAULT_INTEGRAL_NUM, integral_num: DEFAULT_INTEGRAL_NUM,
dark_mode: true,
do_extrema: true, do_extrema: true,
do_roots: true, do_roots: true,
plot_width: 0, 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. /// took for the last frame (the Duration). Stored in a Tuple.
last_info: (Vec<Option<f64>>, Duration), last_info: (Vec<Option<f64>>, 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) /// Stores settings (pretty self-explanatory)
settings: AppSettings, settings: AppSettings,
} }
@ -322,6 +318,11 @@ impl Default for MathApp {
func_strs: vec![String::new()], func_strs: vec![String::new()],
last_error: Vec::new(), last_error: Vec::new(),
last_info: (vec![None], Duration::ZERO), 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(), settings: AppSettings::default(),
} }
} }
@ -449,7 +450,7 @@ impl MathApp {
let functions_len = self.functions.len(); let functions_len = self.functions.len();
let mut remove_i: Option<usize> = None; let mut remove_i: Option<usize> = None;
self.settings.text_boxes_focused = false; self.text_boxes_focused = false;
for (i, function) in self.functions.iter_mut().enumerate() { for (i, function) in self.functions.iter_mut().enumerate() {
let mut integral_enabled = function.integral; let mut integral_enabled = function.integral;
let mut derivative_enabled = function.derivative; let mut derivative_enabled = function.derivative;
@ -500,7 +501,7 @@ impl MathApp {
// If in focus and right arrow key was pressed, apply hint // If in focus and right arrow key was pressed, apply hint
// TODO: change position of cursor // TODO: change position of cursor
if func_edit_focus { if func_edit_focus {
self.settings.text_boxes_focused = true; self.text_boxes_focused = true;
if ui.input().key_down(Key::ArrowRight) { if ui.input().key_down(Key::ArrowRight) {
self.func_strs[i] += &hint; self.func_strs[i] += &hint;
} }
@ -555,15 +556,14 @@ impl epi::App for MathApp {
// start timer // start timer
let start = instant::Instant::now(); let start = instant::Instant::now();
// Set dark/light mode depending on the variable `self.settings.dark_mode` // Set dark/light mode depending on the variable `self.dark_mode`
ctx.set_visuals(match self.settings.dark_mode { ctx.set_visuals(match self.dark_mode {
true => Visuals::dark(), true => Visuals::dark(),
false => Visuals::light(), false => Visuals::light(),
}); });
if !self.settings.text_boxes_focused { if !self.text_boxes_focused {
self.settings self.show_side_panel
.show_side_panel
.bitxor_assign(ctx.input().key_down(Key::H)); .bitxor_assign(ctx.input().key_down(Key::H));
} }
@ -574,9 +574,9 @@ impl epi::App for MathApp {
TopBottomPanel::top("top_bar").show(ctx, |ui| { TopBottomPanel::top("top_bar").show(ctx, |ui| {
ui.horizontal(|ui| { ui.horizontal(|ui| {
// Button in top bar to toggle showing the side panel // 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")) 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", true => "Hide Side Panel",
false => "Show Side Panel", false => "Show Side Panel",
}) })
@ -594,9 +594,9 @@ impl epi::App for MathApp {
} }
// Toggles opening the Help window // Toggles opening the Help window
self.settings.help_open.bitxor_assign( self.help_open.bitxor_assign(
ui.add(Button::new("Help")) ui.add(Button::new("Help"))
.on_hover_text(match self.settings.help_open { .on_hover_text(match self.help_open {
true => "Close Help Window", true => "Close Help Window",
false => "Open Help Window", false => "Open Help Window",
}) })
@ -604,9 +604,9 @@ impl epi::App for MathApp {
); );
// Toggles opening the Info window // Toggles opening the Info window
self.settings.info_open.bitxor_assign( self.info_open.bitxor_assign(
ui.add(Button::new("Info")) ui.add(Button::new("Info"))
.on_hover_text(match self.settings.info_open { .on_hover_text(match self.info_open {
true => "Close Info Window", true => "Close Info Window",
false => "Open Info Window", false => "Open Info Window",
}) })
@ -614,12 +614,12 @@ impl epi::App for MathApp {
); );
// Toggles dark/light mode // Toggles dark/light mode
self.settings.dark_mode.bitxor_assign( self.dark_mode.bitxor_assign(
ui.add(Button::new(match self.settings.dark_mode { ui.add(Button::new(match self.dark_mode {
true => "🌞", true => "🌞",
false => "🌙", false => "🌙",
})) }))
.on_hover_text(match self.settings.dark_mode { .on_hover_text(match self.dark_mode {
true => "Turn the Lights on!", true => "Turn the Lights on!",
false => "Turn the Lights off.", false => "Turn the Lights off.",
}) })
@ -638,7 +638,7 @@ impl epi::App for MathApp {
// Help window with information for users // Help window with information for users
Window::new("Help") Window::new("Help")
.default_pos([200.0, 200.0]) .default_pos([200.0, 200.0])
.open(&mut self.settings.help_open) .open(&mut self.help_open)
.resizable(false) .resizable(false)
.collapsible(false) .collapsible(false)
.show(ctx, |ui| { .show(ctx, |ui| {
@ -668,7 +668,7 @@ impl epi::App for MathApp {
// Window with information about the build and current commit // Window with information about the build and current commit
Window::new("Info") Window::new("Info")
.default_pos([200.0, 200.0]) .default_pos([200.0, 200.0])
.open(&mut self.settings.info_open) .open(&mut self.info_open)
.resizable(false) .resizable(false)
.collapsible(false) .collapsible(false)
.show(ctx, |ui| { .show(ctx, |ui| {
@ -676,8 +676,10 @@ impl epi::App for MathApp {
}); });
// If side panel is enabled, show it. // If side panel is enabled, show it.
if self.settings.show_side_panel { if self.show_side_panel {
self.side_panel(ctx); self.side_panel(ctx);
} else {
self.text_boxes_focused = false;
} }
// Referenced in plotting code, but needs to be here so it can be later // 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 { if width_changed {
self.settings.plot_width = available_width; self.settings.plot_width = available_width;
} }
let settings_copy = self.settings;
// Create and setup plot // Create and setup plot
Plot::new("plot") Plot::new("plot")
@ -724,7 +725,7 @@ impl epi::App for MathApp {
minx_bounds, minx_bounds,
maxx_bounds, maxx_bounds,
width_changed, width_changed,
settings_copy, &self.settings,
) )
}); });
@ -733,7 +734,7 @@ impl epi::App for MathApp {
.iter() .iter()
.enumerate() .enumerate()
.filter(|(i, _)| !self.func_strs[*i].is_empty()) .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(); .collect();
}); });
}); });

View File

@ -166,7 +166,7 @@ impl FunctionEntry {
/// Does the calculations and stores results in `self.output` /// Does the calculations and stores results in `self.output`
pub fn calculate( 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: f64 = settings.plot_width as f64 / (max_x.abs() + min_x.abs());
let resolution_iter = resolution_helper(settings.plot_width + 1, min_x, resolution); 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 /// Displays the function's output on PlotUI `plot_ui` with settings
/// `settings`. Returns an `Option<f64>` of the calculated integral /// `settings`. Returns an `Option<f64>` of the calculated integral
pub fn display(&self, plot_ui: &mut PlotUi, settings: AppSettings) -> Option<f64> { pub fn display(&self, plot_ui: &mut PlotUi, settings: &AppSettings) -> Option<f64> {
let func_str = self.get_func_str(); let func_str = self.get_func_str();
let derivative_str = self.function.get_derivative_str(); let derivative_str = self.function.get_derivative_str();
let step = (settings.integral_min_x - settings.integral_max_x).abs() 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, 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 settings = settings;
let back_target = back_target; let back_target = back_target;
assert!(self.output.back.is_some()); assert!(self.output.back.is_some());
@ -396,19 +396,15 @@ mod tests {
integral_num: usize, integral_num: usize,
) -> AppSettings { ) -> AppSettings {
crate::egui_app::AppSettings { crate::egui_app::AppSettings {
help_open: false,
info_open: false,
show_side_panel: false,
riemann_sum: sum, riemann_sum: sum,
integral_min_x, integral_min_x,
integral_max_x, integral_max_x,
integral_changed: true, integral_changed: true,
integral_num, integral_num,
dark_mode: false,
do_extrema: false, do_extrema: false,
do_roots: false, do_roots: false,
plot_width: pixel_width, plot_width: pixel_width,
text_boxes_focused: false, ..crate::egui_app::AppSettings::default()
} }
} }

View File

@ -4,7 +4,8 @@ lazy_static::lazy_static! {
/// Function returns `f64::NaN` at every x value, which is not displayed. /// Function returns `f64::NaN` at every x value, which is not displayed.
static ref EMPTY_FUNCTION: FlatEx<f64> = exmex::parse::<f64>("0/0").unwrap(); static ref EMPTY_FUNCTION: FlatEx<f64> = exmex::parse::<f64>("0/0").unwrap();
} }
/// Function that includes f(x), f'(x), f'(x)'s string representation, and
/// f''(x)
#[derive(Clone)] #[derive(Clone)]
pub struct BackingFunction { pub struct BackingFunction {
/// f(x) /// f(x)

View File

@ -1,6 +1,7 @@
use crate::misc::{chars_take, common_substring}; use crate::misc::{chars_take, common_substring};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
/// Generate a hint based on the input `input`, returns an `Option<String>`
pub fn generate_hint(input: &str) -> Option<String> { pub fn generate_hint(input: &str) -> Option<String> {
if input.is_empty() { if input.is_empty() {
return Some("x^2".to_owned()); return Some("x^2".to_owned());
@ -53,6 +54,7 @@ pub fn generate_hint(input: &str) -> Option<String> {
None None
} }
/// Creates hashmap used for function name completion
fn gen_completion_hashmap(input: Vec<String>) -> HashMap<String, String> { fn gen_completion_hashmap(input: Vec<String>) -> HashMap<String, String> {
let mut tuple_list: Vec<(String, String)> = Vec::new(); let mut tuple_list: Vec<(String, String)> = Vec::new();
@ -112,6 +114,7 @@ fn gen_completion_hashmap(input: Vec<String>) -> HashMap<String, String> {
output output
} }
/// List of supported functions from exmex
const SUPPORTED_FUNCTIONS: [&str; 22] = [ const SUPPORTED_FUNCTIONS: [&str; 22] = [
"abs", "signum", "sin", "cos", "tan", "asin", "acos", "atan", "sinh", "cosh", "tanh", "floor", "abs", "signum", "sin", "cos", "tan", "asin", "acos", "atan", "sinh", "cosh", "tanh", "floor",
"round", "ceil", "trunc", "fract", "exp", "sqrt", "cbrt", "ln", "log2", "log10", "round", "ceil", "trunc", "fract", "exp", "sqrt", "cbrt", "ln", "log2", "log10",
@ -121,6 +124,7 @@ lazy_static::lazy_static! {
static ref COMPLETION_HASHMAP: HashMap<String, String> = gen_completion_hashmap(SUPPORTED_FUNCTIONS.to_vec().iter().map(|ele| ele.to_string() + "(").collect()); static ref COMPLETION_HASHMAP: HashMap<String, String> = 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<String> { pub fn get_completion(key: String) -> Option<String> {
if key.is_empty() { if key.is_empty() {
return None; return None;
@ -165,10 +169,7 @@ mod tests {
for (key, value) in values { for (key, value) in values {
println!("{} + {}", key, value); println!("{} + {}", key, value);
assert_eq!( assert_eq!(generate_hint(key).unwrap_or_default(), value.to_owned());
generate_hint(key).unwrap_or_default(),
value.to_owned()
);
} }
} }