Compare commits
9 Commits
a21fc048ad
...
7f9a962ff7
| Author | SHA1 | Date | |
|---|---|---|---|
| 7f9a962ff7 | |||
| 8b7e3b3009 | |||
| 74813f5f13 | |||
| 4a4bce90d0 | |||
| fabfc6de31 | |||
| 7dc48f1b33 | |||
| c0a05464f3 | |||
| 84e283f5c2 | |||
| faee5488df |
862
Cargo.lock
generated
862
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
33
Cargo.toml
33
Cargo.toml
@ -33,17 +33,17 @@ strip = false
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
parsing = { path = "./parsing" }
|
parsing = { path = "./parsing" }
|
||||||
eframe = { git = "https://github.com/titaniumtown/egui.git", rev = "b088efb9fa917845ecb54729a0d2fc592d2399e7", default-features = false, features = [
|
eframe = { git = "https://github.com/titaniumtown/egui.git", default-features = false, features = [
|
||||||
"glow",
|
"glow",
|
||||||
] }
|
] }
|
||||||
egui = { git = "https://github.com/titaniumtown/egui.git", rev = "b088efb9fa917845ecb54729a0d2fc592d2399e7", default-features = false, features = [
|
egui = { git = "https://github.com/titaniumtown/egui.git", default-features = false, features = [
|
||||||
"serde",
|
"serde",
|
||||||
] }
|
] }
|
||||||
epaint = { git = "https://github.com/titaniumtown/egui.git", rev = "b088efb9fa917845ecb54729a0d2fc592d2399e7", default-features = false , features = [
|
epaint = { git = "https://github.com/titaniumtown/egui.git", default-features = false , features = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
] }
|
] }
|
||||||
emath = { git = "https://github.com/titaniumtown/egui.git", rev = "b088efb9fa917845ecb54729a0d2fc592d2399e7", default-features = false }
|
emath = { git = "https://github.com/titaniumtown/egui.git", default-features = false }
|
||||||
egui_plot = { git = "https://github.com/titaniumtown/egui.git", rev = "b088efb9fa917845ecb54729a0d2fc592d2399e7", default-features = false }
|
egui_plot = { git = "https://github.com/emilk/egui_plot.git", default-features = false }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -63,10 +63,10 @@ benchmarks = { path = "./benchmarks" }
|
|||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
shadow-rs = "0.12"
|
shadow-rs = "0.12"
|
||||||
epaint = { git = "https://github.com/titaniumtown/egui.git", rev = "b088efb9fa917845ecb54729a0d2fc592d2399e7", default-features = false, features = [
|
epaint = { git = "https://github.com/titaniumtown/egui.git", default-features = false, features = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
] }
|
] }
|
||||||
egui = { git = "https://github.com/titaniumtown/egui.git", rev = "b088efb9fa917845ecb54729a0d2fc592d2399e7", default-features = false, features = [
|
egui = { git = "https://github.com/titaniumtown/egui.git", default-features = false, features = [
|
||||||
"serde",
|
"serde",
|
||||||
] }
|
] }
|
||||||
bincode = "1.3"
|
bincode = "1.3"
|
||||||
@ -94,3 +94,22 @@ wasm-bindgen-futures = "=0.4.54"
|
|||||||
|
|
||||||
[package.metadata.cargo-all-features]
|
[package.metadata.cargo-all-features]
|
||||||
skip_optional_dependencies = true #don't test optional dependencies, only features
|
skip_optional_dependencies = true #don't test optional dependencies, only features
|
||||||
|
|
||||||
|
# various dependency patches fix issues with nix complication such as:
|
||||||
|
# ````
|
||||||
|
# ln: failed to create symbolic link '/nix/store/plh3y4gfxgwcacjccv72f551y1k89x75-cargo-vendor-dir/ecolor-0.33.2/qb43vsx43av6kf4h9y4bsmisvbjlcxd1-ecolor-0.33.2': Permission denied
|
||||||
|
# ````
|
||||||
|
|
||||||
|
[patch."https://github.com/emilk/egui_plot.git"]
|
||||||
|
egui = { git = "https://github.com/titaniumtown/egui.git" }
|
||||||
|
eframe = { git = "https://github.com/titaniumtown/egui.git" }
|
||||||
|
epaint = { git = "https://github.com/titaniumtown/egui.git" }
|
||||||
|
emath = { git = "https://github.com/titaniumtown/egui.git" }
|
||||||
|
ecolor = { git = "https://github.com/titaniumtown/egui.git" }
|
||||||
|
|
||||||
|
[patch.crates-io]
|
||||||
|
egui = { git = "https://github.com/titaniumtown/egui.git" }
|
||||||
|
eframe = { git = "https://github.com/titaniumtown/egui.git" }
|
||||||
|
epaint = { git = "https://github.com/titaniumtown/egui.git" }
|
||||||
|
emath = { git = "https://github.com/titaniumtown/egui.git" }
|
||||||
|
ecolor = { git = "https://github.com/titaniumtown/egui.git" }
|
||||||
|
|||||||
30
build.rs
30
build.rs
@ -4,11 +4,12 @@ use std::{
|
|||||||
fs::File,
|
fs::File,
|
||||||
io::{BufWriter, Write},
|
io::{BufWriter, Write},
|
||||||
path::Path,
|
path::Path,
|
||||||
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
use epaint::{
|
use epaint::{
|
||||||
FontFamily,
|
|
||||||
text::{FontData, FontDefinitions, FontTweak},
|
text::{FontData, FontDefinitions, FontTweak},
|
||||||
|
FontFamily,
|
||||||
};
|
};
|
||||||
|
|
||||||
use run_script::ScriptOptions;
|
use run_script::ScriptOptions;
|
||||||
@ -104,37 +105,38 @@ fn main() {
|
|||||||
font_data: BTreeMap::from([
|
font_data: BTreeMap::from([
|
||||||
(
|
(
|
||||||
"Ubuntu-Light".to_owned(),
|
"Ubuntu-Light".to_owned(),
|
||||||
FontData::from_owned(
|
Arc::new(FontData::from_owned(
|
||||||
font_stripper(
|
font_stripper(
|
||||||
"Ubuntu-Light.ttf",
|
"Ubuntu-Light.ttf",
|
||||||
"ubuntu-light.ttf",
|
"ubuntu-light.ttf",
|
||||||
[main_chars, vec!['∫']].concat(),
|
[main_chars, vec!['∫']].concat(),
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
),
|
)),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"NotoEmoji-Regular".to_owned(),
|
"NotoEmoji-Regular".to_owned(),
|
||||||
FontData::from_owned(
|
Arc::new(FontData::from_owned(
|
||||||
font_stripper(
|
font_stripper(
|
||||||
"NotoEmoji-Regular.ttf",
|
"NotoEmoji-Regular.ttf",
|
||||||
"noto-emoji.ttf",
|
"noto-emoji.ttf",
|
||||||
vec!['🌞', '🌙', '✖'],
|
vec!['🌞', '🌙', '✖'],
|
||||||
)
|
)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
),
|
)),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"emoji-icon-font".to_owned(),
|
"emoji-icon-font".to_owned(),
|
||||||
FontData::from_owned(
|
Arc::new(
|
||||||
font_stripper("emoji-icon-font.ttf", "emoji-icon.ttf", vec!['⚙']).unwrap(),
|
FontData::from_owned(
|
||||||
)
|
font_stripper("emoji-icon-font.ttf", "emoji-icon.ttf", vec!['⚙']).unwrap(),
|
||||||
.tweak(FontTweak {
|
)
|
||||||
scale: 0.8,
|
.tweak(FontTweak {
|
||||||
y_offset_factor: 0.07,
|
scale: 0.8,
|
||||||
y_offset: 0.0,
|
y_offset_factor: 0.07,
|
||||||
baseline_offset_factor: -0.0333,
|
y_offset: -0.0333,
|
||||||
}),
|
}),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
families: BTreeMap::from([
|
families: BTreeMap::from([
|
||||||
|
|||||||
@ -45,7 +45,8 @@
|
|||||||
cargoLock = {
|
cargoLock = {
|
||||||
lockFile = ./Cargo.lock;
|
lockFile = ./Cargo.lock;
|
||||||
outputHashes = {
|
outputHashes = {
|
||||||
"ecolor-0.25.0" = "sha256-9s5LCngwvIIL43txT6sBs4JlRXqmYt1Kw8hlDnwx+DI=";
|
"ecolor-0.33.2" = "sha256-jdQK55yKZptadwosrJXIhoQDGNeELQmPExWRsGc0VG0=";
|
||||||
|
"egui_plot-0.34.0" = "sha256-CfqrpAnLNcB3StuZ9YSDTWih8OUVEa9SJi9RwS1i4ok=";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -449,7 +449,7 @@ impl FunctionEntry {
|
|||||||
Some(integral_data) => {
|
Some(integral_data) => {
|
||||||
if integral_step > step {
|
if integral_step > step {
|
||||||
plot_ui.bar_chart(
|
plot_ui.bar_chart(
|
||||||
BarChart::new(integral_data.0.clone())
|
BarChart::new("integral bar chart", integral_data.0.clone())
|
||||||
.color(Color32::BLUE)
|
.color(Color32::BLUE)
|
||||||
.width(integral_step),
|
.width(integral_step),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
consts::COLORS, function_entry::FunctionEntry, misc::random_u64, widgets::widgets_ontop,
|
consts::COLORS, function_entry::FunctionEntry, misc::random_u64, widgets::widgets_ontop,
|
||||||
};
|
};
|
||||||
use egui::{Button, Id, Key, Modifiers, TextEdit, WidgetText};
|
use egui::{Button, Id, Key, Modifiers, PopupCloseBehavior, TextEdit, WidgetText};
|
||||||
use emath::vec2;
|
use emath::vec2;
|
||||||
use parsing::Movement;
|
use parsing::Movement;
|
||||||
use serde::ser::SerializeStruct;
|
use serde::ser::SerializeStruct;
|
||||||
@ -147,17 +147,23 @@ impl FunctionManager {
|
|||||||
|
|
||||||
let autocomplete_popup_id = Id::new("autocomplete popup");
|
let autocomplete_popup_id = Id::new("autocomplete popup");
|
||||||
|
|
||||||
egui::popup_below_widget(ui, autocomplete_popup_id, &re, |ui| {
|
egui::popup_below_widget(
|
||||||
hints.iter().enumerate().for_each(|(i, candidate)| {
|
ui,
|
||||||
if ui
|
autocomplete_popup_id,
|
||||||
.selectable_label(i == function.autocomplete.i, *candidate)
|
&re,
|
||||||
.clicked()
|
PopupCloseBehavior::CloseOnClickOutside,
|
||||||
{
|
|ui| {
|
||||||
clicked = true;
|
hints.iter().enumerate().for_each(|(i, candidate)| {
|
||||||
function.autocomplete.i = i;
|
if ui
|
||||||
}
|
.selectable_label(i == function.autocomplete.i, *candidate)
|
||||||
});
|
.clicked()
|
||||||
});
|
{
|
||||||
|
clicked = true;
|
||||||
|
function.autocomplete.i = i;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
if clicked {
|
if clicked {
|
||||||
function
|
function
|
||||||
@ -172,10 +178,14 @@ impl FunctionManager {
|
|||||||
|
|
||||||
// Push cursor to end if needed
|
// Push cursor to end if needed
|
||||||
if movement == Movement::Complete {
|
if movement == Movement::Complete {
|
||||||
|
// TODO! proper error handling
|
||||||
let mut state =
|
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());
|
let ccursor = egui::text::CCursor::new(function.autocomplete.string.len());
|
||||||
state.set_ccursor_range(Some(egui::text::CCursorRange::one(ccursor)));
|
state
|
||||||
|
.cursor
|
||||||
|
.set_char_range(Some(egui::text::CCursorRange::one(ccursor)));
|
||||||
|
|
||||||
TextEdit::store_state(ui.ctx(), te_id, state);
|
TextEdit::store_state(ui.ctx(), te_id, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
27
src/lib.rs
27
src/lib.rs
@ -22,6 +22,7 @@ pub use crate::{
|
|||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(target_arch = "wasm32")] {
|
if #[cfg(target_arch = "wasm32")] {
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
use web_sys::HtmlCanvasElement;
|
||||||
|
|
||||||
use lol_alloc::{FreeListAllocator, LockedAllocator};
|
use lol_alloc::{FreeListAllocator, LockedAllocator};
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
@ -49,26 +50,28 @@ cfg_if::cfg_if! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Call this once from JavaScript to start your app.
|
/// Call this once from JavaScript to start your app.
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub async fn start(&self, canvas_id: &str) -> Result<(), wasm_bindgen::JsValue> {
|
pub async fn start(&self, canvas_id: HtmlCanvasElement) -> Result<(), wasm_bindgen::JsValue> {
|
||||||
self.runner
|
self.runner
|
||||||
.start(
|
.start(
|
||||||
canvas_id,
|
canvas_id,
|
||||||
eframe::WebOptions::default(),
|
eframe::WebOptions::default(),
|
||||||
Box::new(|cc| Box::new(math_app::MathApp::new(cc))),
|
Box::new(|cc| Ok(Box::new(math_app::MathApp::new(cc)))),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen(start)]
|
#[wasm_bindgen(start)]
|
||||||
pub async fn start() {
|
pub async fn start() {
|
||||||
tracing::info!("Starting...");
|
tracing::info!("Starting...");
|
||||||
|
|
||||||
|
let document = web_sys::window().unwrap().document().unwrap();
|
||||||
|
let canvas = document.get_element_by_id("canvas").unwrap().dyn_into::<HtmlCanvasElement>().unwrap();
|
||||||
|
|
||||||
let web_handle = WebHandle::new();
|
let web_handle = WebHandle::new();
|
||||||
web_handle.start("canvas").await.unwrap()
|
web_handle.start(canvas).await.unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,13 +6,13 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use eframe::App;
|
use eframe::App;
|
||||||
use egui::{
|
use egui::{
|
||||||
Button, CentralPanel, Color32, ComboBox, Context, DragValue, Frame, Key, Layout, SidePanel,
|
Button, CentralPanel, Color32, ComboBox, Context, CornerRadius, DragValue, Frame, Key, Layout,
|
||||||
TopBottomPanel, Ui, Vec2, Window, style::Margin,
|
SidePanel, TopBottomPanel, Ui, Vec2, Window,
|
||||||
};
|
};
|
||||||
use egui_plot::Plot;
|
use egui_plot::Plot;
|
||||||
|
|
||||||
use emath::{Align, Align2};
|
use emath::{Align, Align2};
|
||||||
use epaint::Rounding;
|
use epaint::{Margin, Rounding};
|
||||||
use instant::Instant;
|
use instant::Instant;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use std::{io::Read, ops::BitXorAssign};
|
use std::{io::Read, ops::BitXorAssign};
|
||||||
@ -535,11 +535,11 @@ impl App for MathApp {
|
|||||||
// Central panel which contains the central plot (or an error created when parsing)
|
// Central panel which contains the central plot (or an error created when parsing)
|
||||||
CentralPanel::default()
|
CentralPanel::default()
|
||||||
.frame(Frame {
|
.frame(Frame {
|
||||||
inner_margin: Margin::symmetric(0.0, 0.0),
|
inner_margin: Margin::ZERO,
|
||||||
rounding: Rounding::ZERO,
|
corner_radius: CornerRadius::ZERO,
|
||||||
// fill: crate::style::STYLE.window_fill(),
|
// fill: crate::style::STYLE.window_fill(),
|
||||||
fill: Color32::from_gray(27),
|
fill: Color32::from_gray(27),
|
||||||
..Frame::none()
|
..Frame::NONE
|
||||||
})
|
})
|
||||||
.show(ctx, |ui| {
|
.show(ctx, |ui| {
|
||||||
// Display an error if it exists
|
// Display an error if it exists
|
||||||
|
|||||||
16
src/misc.rs
16
src/misc.rs
@ -8,13 +8,13 @@ use parsing::FlatExWrapper;
|
|||||||
/// Implements traits that are useful when dealing with Vectors of egui's `Value`
|
/// Implements traits that are useful when dealing with Vectors of egui's `Value`
|
||||||
pub trait EguiHelper {
|
pub trait EguiHelper {
|
||||||
/// Converts to `egui::plot::Values`
|
/// Converts to `egui::plot::Values`
|
||||||
fn to_values(self) -> PlotPoints;
|
fn to_values(self) -> PlotPoints<'static>;
|
||||||
|
|
||||||
/// Converts to `egui::plot::Line`
|
/// Converts to `egui::plot::Line`
|
||||||
fn to_line(self) -> Line;
|
fn to_line(self) -> Line<'static>;
|
||||||
|
|
||||||
/// Converts to `egui::plot::Points`
|
/// Converts to `egui::plot::Points`
|
||||||
fn to_points(self) -> Points;
|
fn to_points(self) -> Points<'static>;
|
||||||
|
|
||||||
/// Converts Vector of Values into vector of tuples
|
/// Converts Vector of Values into vector of tuples
|
||||||
fn to_tuple(self) -> Vec<(f64, f64)>;
|
fn to_tuple(self) -> Vec<(f64, f64)>;
|
||||||
@ -22,18 +22,18 @@ pub trait EguiHelper {
|
|||||||
|
|
||||||
impl EguiHelper for Vec<PlotPoint> {
|
impl EguiHelper for Vec<PlotPoint> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn to_values(self) -> PlotPoints {
|
fn to_values(self) -> PlotPoints<'static> {
|
||||||
PlotPoints::from(unsafe { std::mem::transmute::<Vec<PlotPoint>, Vec<[f64; 2]>>(self) })
|
PlotPoints::from(unsafe { std::mem::transmute::<Vec<PlotPoint>, Vec<[f64; 2]>>(self) })
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn to_line(self) -> Line {
|
fn to_line(self) -> Line<'static> {
|
||||||
Line::new(self.to_values())
|
Line::new("", self.to_values())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn to_points(self) -> Points {
|
fn to_points(self) -> Points<'static> {
|
||||||
Points::new(self.to_values())
|
Points::new("", self.to_values())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|||||||
@ -56,9 +56,10 @@
|
|||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0%;
|
top: 0;
|
||||||
left: 50%;
|
left: 0;
|
||||||
transform: translate(-50%, 0%);
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user