updating
This commit is contained in:
parent
b0a98b197b
commit
9a8f8a6539
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -736,7 +736,7 @@ checksum = "0bd4b30a6560bbd9b4620f4de34c3f14f60848e58a9b7216801afcb4c7b31c3c"
|
||||
[[package]]
|
||||
name = "eframe"
|
||||
version = "0.18.0"
|
||||
source = "git+https://github.com/Titaniumtown/egui.git#913aac5a8c4faaedda8455ad91e13d702dd39df3"
|
||||
source = "git+https://github.com/Titaniumtown/egui.git#d6194a56eb94e35a46d4391161d905058fc0dad9"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"egui",
|
||||
@ -756,7 +756,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "egui"
|
||||
version = "0.18.1"
|
||||
source = "git+https://github.com/Titaniumtown/egui.git#913aac5a8c4faaedda8455ad91e13d702dd39df3"
|
||||
source = "git+https://github.com/Titaniumtown/egui.git#d6194a56eb94e35a46d4391161d905058fc0dad9"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"epaint",
|
||||
@ -768,7 +768,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "egui-winit"
|
||||
version = "0.18.0"
|
||||
source = "git+https://github.com/Titaniumtown/egui.git#913aac5a8c4faaedda8455ad91e13d702dd39df3"
|
||||
source = "git+https://github.com/Titaniumtown/egui.git#d6194a56eb94e35a46d4391161d905058fc0dad9"
|
||||
dependencies = [
|
||||
"arboard",
|
||||
"egui",
|
||||
@ -782,7 +782,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "egui_glow"
|
||||
version = "0.18.1"
|
||||
source = "git+https://github.com/Titaniumtown/egui.git#913aac5a8c4faaedda8455ad91e13d702dd39df3"
|
||||
source = "git+https://github.com/Titaniumtown/egui.git#d6194a56eb94e35a46d4391161d905058fc0dad9"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"egui",
|
||||
@ -802,7 +802,7 @@ checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
|
||||
[[package]]
|
||||
name = "emath"
|
||||
version = "0.18.0"
|
||||
source = "git+https://github.com/Titaniumtown/egui.git#913aac5a8c4faaedda8455ad91e13d702dd39df3"
|
||||
source = "git+https://github.com/Titaniumtown/egui.git#d6194a56eb94e35a46d4391161d905058fc0dad9"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"serde",
|
||||
@ -811,7 +811,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "epaint"
|
||||
version = "0.18.1"
|
||||
source = "git+https://github.com/Titaniumtown/egui.git#913aac5a8c4faaedda8455ad91e13d702dd39df3"
|
||||
source = "git+https://github.com/Titaniumtown/egui.git#d6194a56eb94e35a46d4391161d905058fc0dad9"
|
||||
dependencies = [
|
||||
"ab_glyph",
|
||||
"ahash",
|
||||
|
||||
@ -1,36 +0,0 @@
|
||||
{
|
||||
// help for supported expressions
|
||||
help_expr: [
|
||||
"abs, signum, sin, cos, tan, asin, acos, atan, sinh, cosh, tanh, floor, round, ceil, trunc, fract, exp, sqrt, cbrt, ln, log2, log10, log"
|
||||
],
|
||||
// help for supported variables
|
||||
help_vars: [
|
||||
"- Euler's number is supported via 'e' or 'E'",
|
||||
"- PI is available through 'pi' or 'π'"
|
||||
],
|
||||
// help for buttons located on the top panel
|
||||
help_panel: [
|
||||
"- The 'Panel' button toggles if the side bar should be shown or not. This can also be accomplished by pressing the 'h' key.",
|
||||
"- The 'Add Function' button adds a new function to be graphed. You can then configure that function in the side panel.",
|
||||
"- The 'Help' button opens and closes this window!",
|
||||
"- The 'Info' button provides information on the build currently running."
|
||||
],
|
||||
// help for buttons located in the drop down of functions
|
||||
help_function: [
|
||||
"(From Left to Right)",
|
||||
"`✖` allows you to delete the selected function. Deleting a function is prevented if only 1 function exists.",
|
||||
"`∫` toggles integration.",
|
||||
"`d/dx` toggles the calculation of derivatives.",
|
||||
"`⚙` opens a window to tweak function options."
|
||||
],
|
||||
// help for other "misc" things
|
||||
help_other: [
|
||||
"- Extrema (local minimums and maximums) and Roots (intersections with the x-axis) are displayed though yellow and light blue points respectively located on the graph. These can be toggled in the side panel."
|
||||
],
|
||||
// welcome text
|
||||
welcome: [
|
||||
"Welcome to the (Yet-to-be-named) Graphing Software!",
|
||||
"",
|
||||
"This project aims to provide an intuitive experience graphing mathematical functions with features such as Integration, Differentiation, Extrema, Roots, and much more! (see the Help Window for more details)"
|
||||
]
|
||||
}
|
||||
19
build.rs
19
build.rs
@ -146,26 +146,7 @@ fn main() {
|
||||
]),
|
||||
};
|
||||
|
||||
let text_json: serde_json::Value = json5::from_str(include_str!("assets/text.json5")).unwrap();
|
||||
let mut json_file_array = text_json.as_object().unwrap().clone();
|
||||
for value in json_file_array.iter_mut() {
|
||||
if let serde_json::Value::Array(values) = value.1 {
|
||||
let values_copy = values.clone();
|
||||
*value.1 = serde_json::Value::String(
|
||||
values_copy
|
||||
.iter()
|
||||
.map(|s| s.as_str().expect("failed to make a string"))
|
||||
.collect::<Vec<&str>>()
|
||||
.join("\n"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let text_data: TextDataRaw = serde_json::from_value(serde_json::Value::Object(json_file_array))
|
||||
.expect("Failed to convert data to TextDataRaw");
|
||||
|
||||
let data = bincode::serialize(&TotalData {
|
||||
text: text_data.into_rich(),
|
||||
fonts,
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
@ -26,7 +26,12 @@ impl FlatExWrapper {
|
||||
fn partial(&self, x: usize) -> Self {
|
||||
self.func
|
||||
.as_ref()
|
||||
.map(|f| f.partial(x).map(|a| Self::new(a)).unwrap_or(Self::EMPTY))
|
||||
.map(|f| {
|
||||
f.clone()
|
||||
.partial(x)
|
||||
.map(|a| Self::new(a))
|
||||
.unwrap_or(Self::EMPTY)
|
||||
})
|
||||
.unwrap_or(Self::EMPTY)
|
||||
}
|
||||
|
||||
@ -34,11 +39,12 @@ impl FlatExWrapper {
|
||||
fn get_string(&self) -> &str { self.func.as_ref().map(|f| f.unparse()).unwrap_or("") }
|
||||
|
||||
#[inline]
|
||||
fn partial_iter(&self, x: &[usize]) -> Self {
|
||||
fn partial_iter(&self, n: usize) -> Self {
|
||||
self.func
|
||||
.as_ref()
|
||||
.map(|f| {
|
||||
f.partial_iter(x.iter())
|
||||
f.clone()
|
||||
.partial_iter((0..=n).map(|_| 0).into_iter())
|
||||
.map(|a| Self::new(a))
|
||||
.unwrap_or(Self::EMPTY)
|
||||
})
|
||||
@ -163,9 +169,7 @@ impl BackingFunction {
|
||||
return curr_n_func.eval(&[x]);
|
||||
}
|
||||
}
|
||||
let new_func = self
|
||||
.function
|
||||
.partial_iter((1..=n).map(|_| 0).collect::<Vec<usize>>().as_slice());
|
||||
let new_func = self.function.partial_iter(n);
|
||||
|
||||
self.nth_derivative = Some((
|
||||
n,
|
||||
|
||||
37
src/data.rs
37
src/data.rs
@ -1,43 +1,6 @@
|
||||
#[derive(PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct TextData {
|
||||
pub help_expr: egui::RichText,
|
||||
pub help_vars: egui::RichText,
|
||||
pub help_panel: egui::RichText,
|
||||
pub help_function: egui::RichText,
|
||||
pub help_other: egui::RichText,
|
||||
pub welcome: egui::RichText,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct TextDataRaw {
|
||||
pub help_expr: String,
|
||||
pub help_vars: String,
|
||||
pub help_panel: String,
|
||||
pub help_function: String,
|
||||
pub help_other: String,
|
||||
pub welcome: String,
|
||||
}
|
||||
|
||||
pub const FONT_SIZE: f32 = 14.0;
|
||||
// ui.fonts().crate::data::FONT_SIZE(&egui::FontSelection::default().resolve(ui.style()));
|
||||
|
||||
impl TextDataRaw {
|
||||
#[allow(dead_code)]
|
||||
fn into_rich(self) -> TextData {
|
||||
use egui::RichText;
|
||||
TextData {
|
||||
help_expr: RichText::from(self.help_expr),
|
||||
help_vars: RichText::from(self.help_vars),
|
||||
help_panel: RichText::from(self.help_panel),
|
||||
help_function: RichText::from(self.help_function),
|
||||
help_other: RichText::from(self.help_other),
|
||||
welcome: RichText::from(self.welcome).size(FONT_SIZE + 1.0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, PartialEq)]
|
||||
pub struct TotalData {
|
||||
pub text: TextData,
|
||||
pub fonts: epaint::text::FontDefinitions,
|
||||
}
|
||||
|
||||
@ -149,7 +149,7 @@ impl FunctionEntry {
|
||||
|
||||
pub const fn is_some(&self) -> bool { !self.function.is_none() }
|
||||
|
||||
pub fn settings_window(&mut self, ctx: &mut Context) {
|
||||
pub fn settings_window(&mut self, ctx: &Context) {
|
||||
let mut invalidate_nth = false;
|
||||
egui::Window::new(format!("Settings: {}", self.raw_func_str))
|
||||
.open(&mut self.settings_opened)
|
||||
@ -382,8 +382,8 @@ impl FunctionEntry {
|
||||
.cloned()
|
||||
.collect::<Vec<Value>>()
|
||||
.to_line()
|
||||
.stroke(const { epaint::Stroke::none() })
|
||||
.color(const { Color32::from_rgb(4, 4, 255) })
|
||||
.stroke(epaint::Stroke::none())
|
||||
.color(Color32::from_rgb(4, 4, 255))
|
||||
.fill(0.0),
|
||||
);
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ impl Default for FunctionManager {
|
||||
fn default() -> Self {
|
||||
let mut vec: Functions = Vec::with_capacity(COLORS.len());
|
||||
vec.push((
|
||||
Id::new_from_u64(11414819524356497634), // Random number here to avoid call to crate::misc::random_u64()
|
||||
Id(11414819524356497634), // Random number here to avoid call to crate::misc::random_u64()
|
||||
FunctionEntry::EMPTY,
|
||||
));
|
||||
Self { functions: vec }
|
||||
@ -37,7 +37,7 @@ impl Serialize for FunctionManager {
|
||||
&self
|
||||
.functions
|
||||
.iter()
|
||||
.map(|(id, func)| (id.value(), func.clone()))
|
||||
.map(|(id, func)| (id.0, func.clone()))
|
||||
.collect::<Vec<(u64, FunctionEntry)>>(),
|
||||
)?;
|
||||
s.end()
|
||||
@ -59,16 +59,14 @@ impl<'de> Deserialize<'de> for FunctionManager {
|
||||
.0
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|(id, func)| (egui::Id::new_from_u64(id), func))
|
||||
.map(|(id, func)| (Id(id), func))
|
||||
.collect::<Vec<(Id, FunctionEntry)>>(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Function that creates button that's used with the `button_area`
|
||||
const fn button_area_button(text: impl Into<WidgetText>) -> Button {
|
||||
Button::new(text).frame(false)
|
||||
}
|
||||
fn button_area_button(text: impl Into<WidgetText>) -> Button { Button::new(text).frame(false) }
|
||||
|
||||
impl FunctionManager {
|
||||
#[inline]
|
||||
@ -94,8 +92,8 @@ impl FunctionManager {
|
||||
let mut movement: Movement = Movement::default();
|
||||
|
||||
let size_multiplier = vec2(1.0, {
|
||||
let had_focus = ui.ctx.memory().has_focus(*te_id);
|
||||
(ui.ctx.animate_bool(*te_id, had_focus) * 1.5) + 1.0
|
||||
let had_focus = ui.ctx().memory().has_focus(*te_id);
|
||||
(ui.ctx().animate_bool(*te_id, had_focus) * 1.5) + 1.0
|
||||
});
|
||||
|
||||
let re = ui.add_sized(
|
||||
@ -117,7 +115,7 @@ impl FunctionManager {
|
||||
new_string.retain(|c| crate::misc::is_valid_char(&c));
|
||||
|
||||
// If not fully open, return here as buttons cannot yet be displayed, therefore the user is inable to mark it for deletion
|
||||
let animate_bool = ui.ctx.animate_bool(*te_id, re.has_focus());
|
||||
let animate_bool = ui.ctx().animate_bool(*te_id, re.has_focus());
|
||||
if animate_bool == 1.0 {
|
||||
function.autocomplete.update_string(&new_string);
|
||||
|
||||
@ -145,7 +143,7 @@ impl FunctionManager {
|
||||
// Doesn't need to have a number in id as there should only be 1 autocomplete popup in the entire gui
|
||||
|
||||
// hashed "autocomplete_popup"
|
||||
const POPUP_ID: Id = Id::new_from_u64(7574801616484505465);
|
||||
const POPUP_ID: Id = Id(7574801616484505465);
|
||||
|
||||
let mut clicked = false;
|
||||
|
||||
@ -166,17 +164,17 @@ impl FunctionManager {
|
||||
|
||||
movement = Movement::Complete;
|
||||
} else {
|
||||
ui.memory_mut().open_popup(POPUP_ID);
|
||||
ui.memory().open_popup(POPUP_ID);
|
||||
}
|
||||
}
|
||||
|
||||
// Push cursor to end if needed
|
||||
if movement == Movement::Complete {
|
||||
let mut state =
|
||||
unsafe { TextEdit::load_state(ui.ctx, *te_id).unwrap_unchecked() };
|
||||
unsafe { TextEdit::load_state(ui.ctx(), *te_id).unwrap_unchecked() };
|
||||
let ccursor = egui::text::CCursor::new(function.autocomplete.string.len());
|
||||
state.set_ccursor_range(Some(egui::text::CCursorRange::one(ccursor)));
|
||||
TextEdit::store_state(ui.ctx, *te_id, state);
|
||||
TextEdit::store_state(ui.ctx(), *te_id, state);
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,7 +187,7 @@ impl FunctionManager {
|
||||
// There's more than 1 function! Functions can now be deleted
|
||||
if ui
|
||||
.add_enabled(can_remove, button_area_button("✖"))
|
||||
.on_hover_text(ui.ctx, "Delete Function")
|
||||
.on_hover_text("Delete Function")
|
||||
.clicked()
|
||||
{
|
||||
remove_i = Some(i);
|
||||
@ -199,39 +197,30 @@ impl FunctionManager {
|
||||
// Toggle integral being enabled or not
|
||||
function.integral.bitxor_assign(
|
||||
ui.add(button_area_button("∫"))
|
||||
.on_hover_text(
|
||||
ui.ctx,
|
||||
match function.integral {
|
||||
.on_hover_text(match function.integral {
|
||||
true => "Don't integrate",
|
||||
false => "Integrate",
|
||||
},
|
||||
)
|
||||
})
|
||||
.clicked(),
|
||||
);
|
||||
|
||||
// Toggle showing the derivative (even though it's already calculated this option just toggles if it's displayed or not)
|
||||
function.derivative.bitxor_assign(
|
||||
ui.add(button_area_button("d/dx"))
|
||||
.on_hover_text(
|
||||
ui.ctx,
|
||||
match function.derivative {
|
||||
.on_hover_text(match function.derivative {
|
||||
true => "Don't Differentiate",
|
||||
false => "Differentiate",
|
||||
},
|
||||
)
|
||||
})
|
||||
.clicked(),
|
||||
);
|
||||
|
||||
// Toggle showing the settings window
|
||||
function.settings_opened.bitxor_assign(
|
||||
ui.add(button_area_button("⚙"))
|
||||
.on_hover_text(
|
||||
ui.ctx,
|
||||
match function.settings_opened {
|
||||
.on_hover_text(match function.settings_opened {
|
||||
true => "Close Settings",
|
||||
false => "Open Settings",
|
||||
},
|
||||
)
|
||||
})
|
||||
.clicked(),
|
||||
);
|
||||
});
|
||||
@ -239,7 +228,7 @@ impl FunctionManager {
|
||||
});
|
||||
}
|
||||
|
||||
function.settings_window(ui.ctx);
|
||||
function.settings_window(ui.ctx());
|
||||
}
|
||||
|
||||
// Remove function if the user requests it
|
||||
@ -255,7 +244,7 @@ impl FunctionManager {
|
||||
/// Create and push new empty function entry
|
||||
pub fn push_empty(&mut self) {
|
||||
self.functions.push((
|
||||
Id::new_from_u64(random_u64().expect("unable to generate random id")),
|
||||
Id(random_u64().expect("unable to generate random id")),
|
||||
FunctionEntry::EMPTY,
|
||||
));
|
||||
}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
use crate::{
|
||||
consts::*, data::TextData, function_entry::Riemann, function_manager::FunctionManager,
|
||||
misc::option_vec_printer,
|
||||
consts::*, function_entry::Riemann, function_manager::FunctionManager, misc::option_vec_printer,
|
||||
};
|
||||
use eframe::App;
|
||||
use egui::{
|
||||
@ -102,9 +101,6 @@ pub struct MathApp {
|
||||
/// Stores opened windows/elements for later reference
|
||||
opened: Opened,
|
||||
|
||||
/// Stores loaded text data from `test.json`
|
||||
text: TextData,
|
||||
|
||||
/// Stores settings (pretty self-explanatory)
|
||||
settings: AppSettings,
|
||||
}
|
||||
@ -128,7 +124,7 @@ const FUNC_NAME: &str = "YTBN-FUNCTIONS";
|
||||
impl MathApp {
|
||||
#[allow(dead_code)] // This is used lol
|
||||
/// Create new instance of [`MathApp`] and return it
|
||||
pub fn new(cc: &mut eframe::CreationContext<'_, '_>) -> Self {
|
||||
pub fn new(cc: &eframe::CreationContext<'_>) -> Self {
|
||||
#[cfg(threading)]
|
||||
tracing::info!("Threading: Enabled");
|
||||
|
||||
@ -252,10 +248,10 @@ impl MathApp {
|
||||
cc.egui_ctx.set_fonts(data.fonts);
|
||||
|
||||
// Set dark mode by default
|
||||
cc.egui_ctx.set_visuals(crate::style::STYLE);
|
||||
cc.egui_ctx.set_visuals(crate::style::style());
|
||||
|
||||
// Set spacing
|
||||
cc.egui_ctx.set_spacing(crate::style::SPACING);
|
||||
// cc.egui_ctx.set_spacing(crate::style::SPACING);
|
||||
|
||||
tracing::info!("Initialized! Took: {:?}", start.elapsed());
|
||||
|
||||
@ -267,14 +263,13 @@ impl MathApp {
|
||||
functions: FunctionManager::default(),
|
||||
|
||||
last_info: (None, None),
|
||||
text: data.text,
|
||||
opened: const { Opened::default() },
|
||||
settings: const { AppSettings::default() },
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates SidePanel which contains configuration options
|
||||
fn side_panel(&mut self, ctx: &mut Context) {
|
||||
fn side_panel(&mut self, ctx: &Context) {
|
||||
// Side Panel which contains vital options to the operation of the application
|
||||
// (such as adding functions and other options)
|
||||
SidePanel::left("side_panel")
|
||||
@ -369,25 +364,19 @@ impl MathApp {
|
||||
ui.horizontal(|ui| {
|
||||
self.settings.do_extrema.bitxor_assign(
|
||||
ui.add(Button::new("Extrema"))
|
||||
.on_hover_text(
|
||||
ui.ctx,
|
||||
match self.settings.do_extrema {
|
||||
.on_hover_text(match self.settings.do_extrema {
|
||||
true => "Disable Displaying Extrema",
|
||||
false => "Display Extrema",
|
||||
},
|
||||
)
|
||||
})
|
||||
.clicked(),
|
||||
);
|
||||
|
||||
self.settings.do_roots.bitxor_assign(
|
||||
ui.add(Button::new("Roots"))
|
||||
.on_hover_text(
|
||||
ui.ctx,
|
||||
match self.settings.do_roots {
|
||||
.on_hover_text(match self.settings.do_roots {
|
||||
true => "Disable Displaying Roots",
|
||||
false => "Display Roots",
|
||||
},
|
||||
)
|
||||
})
|
||||
.clicked(),
|
||||
);
|
||||
});
|
||||
@ -428,7 +417,7 @@ impl MathApp {
|
||||
|
||||
impl App for MathApp {
|
||||
/// Called each time the UI needs repainting.
|
||||
fn update(&mut self, ctx: &mut Context, _frame: &mut eframe::Frame) {
|
||||
fn update(&mut self, ctx: &Context, _frame: &mut eframe::Frame) {
|
||||
// start timer
|
||||
let start = if self.opened.info {
|
||||
Some(instant::Instant::now())
|
||||
@ -453,13 +442,10 @@ impl App for MathApp {
|
||||
// Button in top bar to toggle showing the side panel
|
||||
self.opened.side_panel.bitxor_assign(
|
||||
ui.add(Button::new("Panel"))
|
||||
.on_hover_text(
|
||||
ui.ctx,
|
||||
match self.opened.side_panel {
|
||||
.on_hover_text(match self.opened.side_panel {
|
||||
true => "Hide Side Panel",
|
||||
false => "Show Side Panel",
|
||||
},
|
||||
)
|
||||
})
|
||||
.clicked(),
|
||||
);
|
||||
|
||||
@ -469,7 +455,7 @@ impl App for MathApp {
|
||||
COLORS.len() > self.functions.len(),
|
||||
Button::new("Add Function"),
|
||||
)
|
||||
.on_hover_text(ui.ctx, "Create and graph new function")
|
||||
.on_hover_text("Create and graph new function")
|
||||
.clicked()
|
||||
{
|
||||
self.functions.push_empty();
|
||||
@ -478,26 +464,20 @@ impl App for MathApp {
|
||||
// Toggles opening the Help window
|
||||
self.opened.help.bitxor_assign(
|
||||
ui.add(Button::new("Help"))
|
||||
.on_hover_text(
|
||||
ui.ctx,
|
||||
match self.opened.help {
|
||||
.on_hover_text(match self.opened.help {
|
||||
true => "Close Help Window",
|
||||
false => "Open Help Window",
|
||||
},
|
||||
)
|
||||
})
|
||||
.clicked(),
|
||||
);
|
||||
|
||||
// Toggles opening the Info window
|
||||
self.opened.info.bitxor_assign(
|
||||
ui.add(Button::new("Info"))
|
||||
.on_hover_text(
|
||||
ui.ctx,
|
||||
match self.opened.info {
|
||||
.on_hover_text(match self.opened.info {
|
||||
true => "Close Info Window",
|
||||
false => "Open Info Window",
|
||||
},
|
||||
)
|
||||
})
|
||||
.clicked(),
|
||||
);
|
||||
|
||||
@ -516,23 +496,23 @@ impl App for MathApp {
|
||||
.collapsible(false)
|
||||
.show(ctx, |ui| {
|
||||
ui.collapsing("Supported Expressions", |ui| {
|
||||
ui.label(self.text.help_expr.clone());
|
||||
ui.label("abs, signum, sin, cos, tan, asin, acos, atan, sinh, cosh, tanh, floor, round, ceil, trunc, fract, exp, sqrt, cbrt, ln, log2, log10, log");
|
||||
});
|
||||
|
||||
ui.collapsing("Supported Constants", |ui| {
|
||||
ui.label(self.text.help_vars.clone());
|
||||
ui.label("- Euler's number is supported via 'e' or 'E'\n- PI is available through 'pi' or 'π'");
|
||||
});
|
||||
|
||||
ui.collapsing("Panel", |ui| {
|
||||
ui.label(self.text.help_panel.clone());
|
||||
ui.label("- The 'Panel' button toggles if the side bar should be shown or not. This can also be accomplished by pressing the 'h' key.\n- The 'Add Function' button adds a new function to be graphed. You can then configure that function in the side panel.\n- The 'Help' button opens and closes this window!\n- The 'Info' button provides information on the build currently running.");
|
||||
});
|
||||
|
||||
ui.collapsing("Functions", |ui| {
|
||||
ui.label(self.text.help_function.clone());
|
||||
ui.label("(From Left to Right)\n`✖` allows you to delete the selected function. Deleting a function is prevented if only 1 function exists.\n`∫` toggles integration.\n`d/dx` toggles the calculation of derivatives.\n`⚙` opens a window to tweak function options.");
|
||||
});
|
||||
|
||||
ui.collapsing("Other", |ui| {
|
||||
ui.label(self.text.help_other.clone());
|
||||
ui.label("- Extrema (local minimums and maximums) and Roots (intersections with the x-axis) are displayed though yellow and light blue points respectively located on the graph. These can be toggled in the side panel.");
|
||||
});
|
||||
});
|
||||
|
||||
@ -544,7 +524,7 @@ impl App for MathApp {
|
||||
.collapsible(false)
|
||||
.title_bar(false)
|
||||
.show(ctx, |ui| {
|
||||
ui.label(self.text.welcome.clone());
|
||||
ui.label("Welcome to the (Yet-to-be-named) Graphing Software!\n\nThis project aims to provide an intuitive experience graphing mathematical functions with features such as Integration, Differentiation, Extrema, Roots, and much more! (see the Help Window for more details)");
|
||||
});
|
||||
|
||||
if let Some(response) = welcome_response {
|
||||
@ -576,16 +556,12 @@ impl App for MathApp {
|
||||
|
||||
// Central panel which contains the central plot (or an error created when parsing)
|
||||
CentralPanel::default()
|
||||
.frame(
|
||||
const {
|
||||
Frame {
|
||||
.frame(Frame {
|
||||
inner_margin: Margin::symmetric(0.0, 0.0),
|
||||
rounding: Rounding::none(),
|
||||
fill: crate::style::STYLE.window_fill(),
|
||||
// fill: crate::style::STYLE.window_fill(),
|
||||
..Frame::none()
|
||||
}
|
||||
},
|
||||
)
|
||||
})
|
||||
.show(ctx, |ui| {
|
||||
// Display an error if it exists
|
||||
let errors_formatted: String = self
|
||||
@ -663,8 +639,4 @@ impl App for MathApp {
|
||||
// Calculate and store the last time it took to draw the frame
|
||||
self.last_info.1 = start.map(|a| format!("Took: {}ms", a.elapsed().as_micros()));
|
||||
}
|
||||
|
||||
fn clear_color(&self, _visuals: &egui::Visuals) -> egui::Rgba {
|
||||
crate::style::STYLE.window_fill().into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ pub trait EguiHelper {
|
||||
fn to_tuple(self) -> Vec<(f64, f64)>;
|
||||
}
|
||||
|
||||
impl const EguiHelper for Vec<Value> {
|
||||
impl EguiHelper for Vec<Value> {
|
||||
#[inline(always)]
|
||||
fn to_values(self) -> Values { Values::from_values(self) }
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ use egui::{
|
||||
use emath::vec2;
|
||||
use epaint::{Color32, Rounding, Shadow, Stroke};
|
||||
|
||||
const fn widgets_dark() -> Widgets {
|
||||
fn widgets_dark() -> Widgets {
|
||||
Widgets {
|
||||
noninteractive: WidgetVisuals {
|
||||
bg_fill: Color32::from_gray(27), // window background
|
||||
@ -45,10 +45,7 @@ const fn widgets_dark() -> Widgets {
|
||||
}
|
||||
}
|
||||
|
||||
pub const STYLE: Visuals = dark();
|
||||
pub const SPACING: Spacing = spacing();
|
||||
|
||||
const fn dark() -> Visuals {
|
||||
pub fn style() -> Visuals {
|
||||
Visuals {
|
||||
dark_mode: true,
|
||||
override_text_color: None,
|
||||
@ -70,7 +67,7 @@ const fn dark() -> Visuals {
|
||||
}
|
||||
}
|
||||
|
||||
const fn spacing() -> Spacing {
|
||||
pub fn spacing() -> Spacing {
|
||||
Spacing {
|
||||
item_spacing: vec2(8.0, 3.0),
|
||||
window_margin: Margin::same(6.0),
|
||||
|
||||
@ -7,8 +7,8 @@ pub fn widgets_ontop<R>(
|
||||
add_contents: impl FnOnce(&mut egui::Ui) -> R,
|
||||
) -> InnerResponse<R> {
|
||||
let area = egui::Area::new(id)
|
||||
.fixed_pos(re.rect().min.offset_y(y_offset))
|
||||
.fixed_pos(re.rect.min.offset_y(y_offset))
|
||||
.order(egui::Order::Foreground);
|
||||
|
||||
area.show(ui.ctx, |ui| add_contents(ui))
|
||||
area.show(ui.ctx(), |ui| add_contents(ui))
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user