move AutoComplete
This commit is contained in:
parent
2dfa0dd5af
commit
30475eb4f4
@ -11,7 +11,7 @@ pub use crate::{
|
|||||||
autocomplete_helper::compile_hashmap,
|
autocomplete_helper::compile_hashmap,
|
||||||
parsing::{process_func_str, BackingFunction},
|
parsing::{process_func_str, BackingFunction},
|
||||||
suggestions::{
|
suggestions::{
|
||||||
generate_hint, get_last_term, split_function, split_function_chars, Hint, HINT_EMPTY,
|
generate_hint, get_last_term, split_function, split_function_chars, AutoComplete, Hint,
|
||||||
SUPPORTED_FUNCTIONS,
|
Movement, HINT_EMPTY, SUPPORTED_FUNCTIONS,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -253,3 +253,110 @@ impl<'a> Hint<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
|
include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug)]
|
||||||
|
pub enum Movement {
|
||||||
|
Complete,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
Down,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
Up,
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Movement {
|
||||||
|
pub const fn is_none(&self) -> bool { matches!(&self, Self::None) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl const Default for Movement {
|
||||||
|
fn default() -> Self { Self::None }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct AutoComplete<'a> {
|
||||||
|
pub i: usize,
|
||||||
|
pub hint: &'a Hint<'a>,
|
||||||
|
pub string: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> const Default for AutoComplete<'a> {
|
||||||
|
fn default() -> AutoComplete<'a> { AutoComplete::EMPTY }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> AutoComplete<'a> {
|
||||||
|
const EMPTY: AutoComplete<'a> = Self {
|
||||||
|
i: 0,
|
||||||
|
hint: &HINT_EMPTY,
|
||||||
|
string: String::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn update_string(&mut self, string: &str) {
|
||||||
|
if self.string != string {
|
||||||
|
// catch empty strings here to avoid call to `generate_hint` and unnecessary logic
|
||||||
|
if string.is_empty() {
|
||||||
|
*self = Self::EMPTY;
|
||||||
|
} else {
|
||||||
|
self.string = string.to_owned();
|
||||||
|
self.do_update_logic();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Runs update logic assuming that a change to `self.string` has been made
|
||||||
|
fn do_update_logic(&mut self) {
|
||||||
|
self.i = 0;
|
||||||
|
self.hint = generate_hint(&self.string);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn register_movement(&mut self, movement: &Movement) {
|
||||||
|
if movement.is_none() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.hint {
|
||||||
|
Hint::Many(hints) => {
|
||||||
|
// Impossible for plural hints to be singular or non-existant
|
||||||
|
unsafe {
|
||||||
|
assume(hints.len() > 1);
|
||||||
|
assume(!hints.is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
match movement {
|
||||||
|
Movement::Up => {
|
||||||
|
// if self.i is below 1, it's at
|
||||||
|
match self.i {
|
||||||
|
0 => self.i = hints.len() - 1,
|
||||||
|
_ => self.i -= 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Movement::Down => {
|
||||||
|
// add one, if resulting value is above maximum i value, set i to 0
|
||||||
|
self.i += 1;
|
||||||
|
if self.i > (hints.len() - 1) {
|
||||||
|
self.i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Movement::Complete => {
|
||||||
|
unsafe { assume(hints.len() >= (self.i + 1)) }
|
||||||
|
|
||||||
|
self.apply_hint(hints[self.i]);
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Hint::Single(hint) => {
|
||||||
|
if movement == &Movement::Complete {
|
||||||
|
self.apply_hint(hint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn apply_hint(&mut self, hint: &str) {
|
||||||
|
self.string.push_str(hint);
|
||||||
|
self.do_update_logic();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
use crate::math_app::AppSettings;
|
use crate::math_app::AppSettings;
|
||||||
use crate::misc::*;
|
use crate::misc::*;
|
||||||
use crate::widgets::AutoComplete;
|
|
||||||
use egui::{
|
use egui::{
|
||||||
plot::{BarChart, PlotUi, Value},
|
plot::{BarChart, PlotUi, Value},
|
||||||
widgets::plot::Bar,
|
widgets::plot::Bar,
|
||||||
Checkbox, Context,
|
Checkbox, Context,
|
||||||
};
|
};
|
||||||
use epaint::Color32;
|
use epaint::Color32;
|
||||||
|
use parsing::AutoComplete;
|
||||||
use parsing::{process_func_str, BackingFunction};
|
use parsing::{process_func_str, BackingFunction};
|
||||||
use std::{
|
use std::{
|
||||||
fmt::{self, Debug},
|
fmt::{self, Debug},
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
use crate::consts::is_mobile;
|
use crate::consts::is_mobile;
|
||||||
use crate::function_entry::FunctionEntry;
|
use crate::function_entry::FunctionEntry;
|
||||||
use crate::widgets::{widgets_ontop, Movement};
|
use crate::widgets::widgets_ontop;
|
||||||
use egui::{Button, Id, Key, Modifiers, TextEdit, WidgetText};
|
use egui::{Button, Id, Key, Modifiers, TextEdit, WidgetText};
|
||||||
use emath::vec2;
|
use emath::vec2;
|
||||||
use parsing::Hint;
|
use parsing::Hint;
|
||||||
|
use parsing::Movement;
|
||||||
use std::ops::BitXorAssign;
|
use std::ops::BitXorAssign;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,6 @@ pub use crate::{
|
|||||||
decimal_round, option_vec_printer, resolution_helper, storage_create, storage_read,
|
decimal_round, option_vec_printer, resolution_helper, storage_create, storage_read,
|
||||||
SteppedVector,
|
SteppedVector,
|
||||||
},
|
},
|
||||||
widgets::{AutoComplete, Movement},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
|
|||||||
108
src/widgets.rs
108
src/widgets.rs
@ -1,111 +1,3 @@
|
|||||||
use std::intrinsics::assume;
|
|
||||||
|
|
||||||
use parsing::{generate_hint, Hint, HINT_EMPTY};
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
|
||||||
pub enum Movement {
|
|
||||||
Complete,
|
|
||||||
Down,
|
|
||||||
Up,
|
|
||||||
None,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Movement {
|
|
||||||
pub const fn is_none(&self) -> bool { matches!(&self, Self::None) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl const Default for Movement {
|
|
||||||
fn default() -> Self { Self::None }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct AutoComplete<'a> {
|
|
||||||
pub i: usize,
|
|
||||||
pub hint: &'a Hint<'a>,
|
|
||||||
pub string: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> const Default for AutoComplete<'a> {
|
|
||||||
fn default() -> AutoComplete<'a> { AutoComplete::EMPTY }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> AutoComplete<'a> {
|
|
||||||
const EMPTY: AutoComplete<'a> = Self {
|
|
||||||
i: 0,
|
|
||||||
hint: &HINT_EMPTY,
|
|
||||||
string: String::new(),
|
|
||||||
};
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn update_string(&mut self, string: &str) {
|
|
||||||
if self.string != string {
|
|
||||||
// catch empty strings here to avoid call to `generate_hint` and unnecessary logic
|
|
||||||
if string.is_empty() {
|
|
||||||
*self = Self::EMPTY;
|
|
||||||
} else {
|
|
||||||
self.string = string.to_owned();
|
|
||||||
self.do_update_logic();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Runs update logic assuming that a change to `self.string` has been made
|
|
||||||
fn do_update_logic(&mut self) {
|
|
||||||
self.i = 0;
|
|
||||||
self.hint = generate_hint(&self.string);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn register_movement(&mut self, movement: &Movement) {
|
|
||||||
if movement.is_none() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
match self.hint {
|
|
||||||
Hint::Many(hints) => {
|
|
||||||
// Impossible for plural hints to be singular or non-existant
|
|
||||||
unsafe {
|
|
||||||
assume(hints.len() > 1);
|
|
||||||
assume(!hints.is_empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
match movement {
|
|
||||||
Movement::Up => {
|
|
||||||
// if self.i is below 1, it's at
|
|
||||||
match self.i {
|
|
||||||
0 => self.i = hints.len() - 1,
|
|
||||||
_ => self.i -= 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Movement::Down => {
|
|
||||||
// add one, if resulting value is above maximum i value, set i to 0
|
|
||||||
self.i += 1;
|
|
||||||
if self.i > (hints.len() - 1) {
|
|
||||||
self.i = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Movement::Complete => {
|
|
||||||
unsafe { assume(hints.len() >= (self.i + 1)) }
|
|
||||||
|
|
||||||
self.apply_hint(hints[self.i]);
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Hint::Single(hint) => {
|
|
||||||
if movement == &Movement::Complete {
|
|
||||||
self.apply_hint(hint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn apply_hint(&mut self, hint: &str) {
|
|
||||||
self.string.push_str(hint);
|
|
||||||
self.do_update_logic();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn widgets_ontop<R>(
|
pub fn widgets_ontop<R>(
|
||||||
ui: &egui::Ui, id: String, re: &egui::Response, y_offset: f32,
|
ui: &egui::Ui, id: String, re: &egui::Response, y_offset: f32,
|
||||||
add_contents: impl FnOnce(&mut egui::Ui) -> R,
|
add_contents: impl FnOnce(&mut egui::Ui) -> R,
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
use parsing::Hint;
|
use parsing::{AutoComplete, Hint, Movement};
|
||||||
use ytbn_graphing_software::{AutoComplete, Movement};
|
|
||||||
|
|
||||||
enum Action<'a> {
|
enum Action<'a> {
|
||||||
AssertIndex(usize),
|
AssertIndex(usize),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user