move stuff from AppSettings
This commit is contained in:
parent
bb91dc5983
commit
fe8dc62f06
@ -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();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user