diff --git a/Cargo.lock b/Cargo.lock index 892039e..8175ada 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", diff --git a/parsing/src/lib.rs b/parsing/src/lib.rs index 9ca4bb4..7b05fc3 100644 --- a/parsing/src/lib.rs +++ b/parsing/src/lib.rs @@ -3,5 +3,6 @@ #![feature(const_default_impls)] #![feature(const_mut_refs)] +mod autocomplete_helper; pub mod parsing; pub mod suggestions; diff --git a/parsing/src/parsing.rs b/parsing/src/parsing.rs index 768aaae..15da5c4 100644 --- a/parsing/src/parsing.rs +++ b/parsing/src/parsing.rs @@ -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 diff --git a/parsing/src/suggestions.rs b/parsing/src/suggestions.rs index 69ea01c..801ff99 100644 --- a/parsing/src/suggestions.rs +++ b/parsing/src/suggestions.rs @@ -36,13 +36,11 @@ pub enum SplitType { } pub fn split_function_chars(chars: &[char], split: SplitType) -> Vec { - 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 { diff --git a/push.sh b/push.sh index 8906801..d67e2ee 100755 --- a/push.sh +++ b/push.sh @@ -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 diff --git a/src/function_manager.rs b/src/function_manager.rs index 5a441fd..e28b1fa 100644 --- a/src/function_manager.rs +++ b/src/function_manager.rs @@ -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 = 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 } } diff --git a/src/math_app.rs b/src/math_app.rs index 76ec71c..9871423 100644 --- a/src/math_app.rs +++ b/src/math_app.rs @@ -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 = 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); } diff --git a/src/misc.rs b/src/misc.rs index ccbab6b..52cfd0c 100644 --- a/src/misc.rs +++ b/src/misc.rs @@ -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 = (min..=max).map(|x| x as f64).collect(); let len_data = data.len(); let stepped_vector: SteppedVector = data.into();