This commit is contained in:
Simon Gardling 2022-05-11 09:21:32 -04:00
parent c341369146
commit 42596be571
8 changed files with 60 additions and 67 deletions

14
Cargo.lock generated
View File

@ -663,7 +663,7 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
[[package]]
name = "eframe"
version = "0.18.0"
source = "git+https://github.com/Titaniumtown/egui.git#bb3e7c02228e8cc3c03f91d4527ad3b4d4c3d0f7"
source = "git+https://github.com/Titaniumtown/egui.git#e9ed0e4b3ad7ca6e887edb013437077ea398d568"
dependencies = [
"bytemuck",
"egui",
@ -683,7 +683,7 @@ dependencies = [
[[package]]
name = "egui"
version = "0.18.1"
source = "git+https://github.com/Titaniumtown/egui.git#bb3e7c02228e8cc3c03f91d4527ad3b4d4c3d0f7"
source = "git+https://github.com/Titaniumtown/egui.git#e9ed0e4b3ad7ca6e887edb013437077ea398d568"
dependencies = [
"ahash",
"epaint",
@ -694,7 +694,7 @@ dependencies = [
[[package]]
name = "egui-winit"
version = "0.18.0"
source = "git+https://github.com/Titaniumtown/egui.git#bb3e7c02228e8cc3c03f91d4527ad3b4d4c3d0f7"
source = "git+https://github.com/Titaniumtown/egui.git#e9ed0e4b3ad7ca6e887edb013437077ea398d568"
dependencies = [
"arboard",
"egui",
@ -707,7 +707,7 @@ dependencies = [
[[package]]
name = "egui_glow"
version = "0.18.1"
source = "git+https://github.com/Titaniumtown/egui.git#bb3e7c02228e8cc3c03f91d4527ad3b4d4c3d0f7"
source = "git+https://github.com/Titaniumtown/egui.git#e9ed0e4b3ad7ca6e887edb013437077ea398d568"
dependencies = [
"bytemuck",
"egui",
@ -727,7 +727,7 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "emath"
version = "0.18.0"
source = "git+https://github.com/Titaniumtown/egui.git#bb3e7c02228e8cc3c03f91d4527ad3b4d4c3d0f7"
source = "git+https://github.com/Titaniumtown/egui.git#e9ed0e4b3ad7ca6e887edb013437077ea398d568"
dependencies = [
"bytemuck",
]
@ -735,7 +735,7 @@ dependencies = [
[[package]]
name = "epaint"
version = "0.18.1"
source = "git+https://github.com/Titaniumtown/egui.git#bb3e7c02228e8cc3c03f91d4527ad3b4d4c3d0f7"
source = "git+https://github.com/Titaniumtown/egui.git#e9ed0e4b3ad7ca6e887edb013437077ea398d568"
dependencies = [
"ab_glyph",
"ahash",
@ -1937,7 +1937,7 @@ dependencies = [
[[package]]
name = "ruzstd"
version = "0.2.4"
source = "git+https://github.com/Titaniumtown/zstd-rs.git?branch=ringbuffer#56972fa1fe8b188ad2f1f54fe1fe35d9479a2d9f"
source = "git+https://github.com/Titaniumtown/zstd-rs.git?branch=ringbuffer#1b2f128459f6a899788465bc005d75f0240c9eae"
dependencies = [
"byteorder",
"twox-hash",

View File

@ -3,5 +3,6 @@
#![feature(const_default_impls)]
#![feature(const_mut_refs)]
mod autocomplete_helper;
pub mod parsing;
pub mod suggestions;

View File

@ -181,12 +181,8 @@ fn prettyify_function_str(func: &str) -> String {
/// Case insensitive checks for if `c` is a character used to represent a variable
#[inline]
pub const fn is_variable(c: &char) -> bool {
match c.to_ascii_lowercase() {
'x' => true,
'e' => true,
'π' => true,
_ => false,
}
let c = c.to_ascii_lowercase();
(c == 'x') | (c == 'e') | (c == 'π')
}
/// Adds asterisks where needed in a function

View File

@ -36,13 +36,11 @@ pub enum SplitType {
}
pub fn split_function_chars(chars: &[char], split: SplitType) -> Vec<String> {
if chars.is_empty() {
return Vec::new();
}
// No point in processing everything if there's only 1 character
if chars.len() == 1 {
return vec![chars[0].to_string()];
// catch some basic cases
match chars.len() {
0 => return Vec::new(),
1 => return vec![chars[0].to_string()],
_ => {}
}
unsafe {

View File

@ -2,11 +2,12 @@
set -e #kill script if error occurs
cargo test-all-features
cargo test --package parsing
bash build.sh release
echo "rsyncing"
#rsync -av --delete --info=progress2 tmp/ rpi-public:/mnt/hdd/http_share/integral-demo/
rsync -av --delete --info=progress2 tmp/ rpi-public:/mnt/hdd/http_share/integral-demo/
rsync -av --delete --info=progress2 --exclude=".git" tmp/ ../titaniumtown.github.io/
rm -fr tmp
cd ../titaniumtown.github.io

View File

@ -1,21 +1,21 @@
use crate::consts::is_mobile;
use crate::function_entry::FunctionEntry;
use crate::widgets::{widgets_ontop, Movement};
use egui::{Button, Key, Modifiers, TextEdit, WidgetText};
use egui::{Button, Id, Key, Modifiers, TextEdit, WidgetText};
use emath::vec2;
use parsing::suggestions::Hint;
use std::ops::BitXorAssign;
use uuid::Uuid;
pub struct FunctionManager {
functions: Vec<(Uuid, FunctionEntry)>,
functions: Vec<(Id, FunctionEntry)>,
}
impl Default for FunctionManager {
fn default() -> Self {
Self {
functions: vec![(
uuid!("684fc8be-4ba0-408d-96ef-480b0642126f"), // Random uuid here to avoid call to `Uuid::new_v4()`
Id::new(uuid!("684fc8be-4ba0-408d-96ef-480b0642126f")), // Random uuid here to avoid call to `Uuid::new_v4()`
FunctionEntry::EMPTY,
)],
}
@ -32,42 +32,30 @@ impl FunctionManager {
// ui.label("Functions:");
let can_remove = self.functions.len() > 1;
let row_height = ui
.fonts()
.row_height(&egui::FontSelection::default().resolve(ui.style()));
// update if font settings are ever changed
const ROW_HEIGHT: f32 = 14.0;
// ui.fonts().row_height(&egui::FontSelection::default().resolve(ui.style()));
let available_width = ui.available_width();
let mut remove_i: Option<usize> = None;
for (i, (uuid, function)) in self.functions.iter_mut().enumerate() {
// render cool input box
let output_string = function.autocomplete.string.clone();
function.update_string(&output_string);
let target_size = vec2(available_width, ROW_HEIGHT);
for (i, (te_id, function)) in self.functions.iter_mut().enumerate() {
let mut new_string = function.autocomplete.string.clone();
function.update_string(&new_string);
let mut movement: Movement = Movement::default();
let mut new_string = function.autocomplete.string.clone();
// unique id for this function
let te_id = ui.make_persistent_id(uuid);
// target size of text edit box
let target_size = vec2(available_width, {
// get the animated bool that stores how "in focus" the text box is
let gotten_focus_value = {
let ctx = ui.ctx();
let had_focus = ctx.memory().has_focus(te_id);
ctx.animate_bool(te_id, had_focus)
};
row_height * (1.0 + (gotten_focus_value * 1.5))
});
let re = ui.add_sized(
target_size,
target_size
* vec2(1.0, {
let ctx = ui.ctx();
let had_focus = ctx.memory().has_focus(*te_id);
(ctx.animate_bool(*te_id, had_focus) * 1.5) + 1.0
}),
egui::TextEdit::singleline(&mut new_string)
.hint_forward(true) // Make the hint appear after the last text in the textbox
.lock_focus(true)
.id(te_id) // set widget's id to `te_id`
.id(*te_id) // set widget's id to `te_id`
.hint_text({
// if there's a single hint, go ahead and apply the hint here, if not, set the hint to an empty string
if let Hint::Single(single_hint) = function.autocomplete.hint {
@ -79,7 +67,7 @@ impl FunctionManager {
);
// if not fully open, return here as buttons cannot yet be displayed, therefore the user is inable to mark it for deletion
if ui.ctx().animate_bool(te_id, re.has_focus()) >= 1.0 {
if ui.ctx().animate_bool(*te_id, re.has_focus()) >= 1.0 {
function.autocomplete.update_string(&new_string);
if !function.autocomplete.hint.is_none() {
@ -92,7 +80,11 @@ impl FunctionManager {
}
// Put here so these key presses don't interact with other elements
let enter_pressed = ui.input_mut().consume_key(Modifiers::NONE, Key::Enter);
let enter_pressed = match is_mobile() {
true => false,
false => ui.input_mut().consume_key(Modifiers::NONE, Key::Enter),
};
let tab_pressed = ui.input_mut().consume_key(Modifiers::NONE, Key::Tab);
if enter_pressed | tab_pressed | ui.input().key_pressed(Key::ArrowRight) {
movement = Movement::Complete;
@ -130,10 +122,10 @@ impl FunctionManager {
// 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);
}
}
@ -144,7 +136,7 @@ impl FunctionManager {
ui,
format!("buttons_area_{}", i),
&re,
row_height * BUTTONS_Y_OFFSET,
ROW_HEIGHT * BUTTONS_Y_OFFSET,
|ui| {
ui.horizontal(|ui| {
// There's more than 1 function! Functions can now be deleted
@ -198,7 +190,10 @@ impl FunctionManager {
}
}
pub fn new_function(&mut self) { self.functions.push((Uuid::new_v4(), FunctionEntry::EMPTY)); }
pub fn new_function(&mut self) {
self.functions
.push((Id::new(Uuid::new_v4()), FunctionEntry::EMPTY));
}
pub fn any_using_integral(&self) -> bool {
self.functions.iter().any(|(_, func)| func.integral)
@ -207,7 +202,7 @@ impl FunctionManager {
#[inline]
pub fn len(&self) -> usize { self.functions.len() }
pub fn get_entries_mut(&mut self) -> &mut Vec<(Uuid, FunctionEntry)> { &mut self.functions }
pub fn get_entries_mut(&mut self) -> &mut Vec<(Id, FunctionEntry)> { &mut self.functions }
pub fn get_entries(&self) -> &Vec<(Uuid, FunctionEntry)> { &self.functions }
pub fn get_entries(&self) -> &Vec<(Id, FunctionEntry)> { &self.functions }
}

View File

@ -143,10 +143,12 @@ impl MathApp {
tracing::info!("Loading assets...");
let mut tar_file_data = Vec::new();
let _ = ruzstd::StreamingDecoder::new(&mut include_bytes!("../assets.tar.zst").as_slice())
.expect("failed to decompress assets")
.read_to_end(&mut tar_file_data)
.expect("failed to read assets");
let _ = unsafe {
ruzstd::StreamingDecoder::new(&mut include_bytes!("../assets.tar.zst").as_slice())
.unwrap_unchecked()
.read_to_end(&mut tar_file_data)
.unwrap_unchecked()
};
// Stores fonts
let mut font_ubuntu_light: Option<FontData> = None;
@ -199,9 +201,9 @@ impl MathApp {
}
}
} else if path_string == "text.json" {
text_data = Some(TextData::from_json_str(
str::from_utf8(&data).expect("unable to read text.json"),
));
text_data = Some(TextData::from_json_str(unsafe {
str::from_utf8(&data).unwrap_unchecked()
}));
} else {
panic!("File {} not expected!", path_string);
}

View File

@ -338,8 +338,8 @@ mod tests {
/// find a bunch of issues)
#[test]
fn stepped_vector_test() {
let min: i32 = -10;
let max: i32 = 10;
let min: i32 = -1000;
let max: i32 = 1000;
let data: Vec<f64> = (min..=max).map(|x| x as f64).collect();
let len_data = data.len();
let stepped_vector: SteppedVector = data.into();