From b9b32972afda261020dd207b4ea2b44b7b697b83 Mon Sep 17 00:00:00 2001 From: Nathan Reiner Date: Sun, 21 Jan 2024 17:02:00 +0100 Subject: add multiple functions to canvas --- src/ui/graph.rs | 74 ++++++++++++++++++++++++++++++++++++--------------------- src/ui/mod.rs | 8 ++++--- 2 files changed, 52 insertions(+), 30 deletions(-) (limited to 'src/ui') diff --git a/src/ui/graph.rs b/src/ui/graph.rs index 63e1c43..83d90f8 100644 --- a/src/ui/graph.rs +++ b/src/ui/graph.rs @@ -16,17 +16,16 @@ use crate::{ #[derive(Default)] pub struct GraphCanvas { graph: Cache, - pub func: Mutex, - pub ctx: Context, + funcs: Mutex>>, + ctx: Context, } impl GraphCanvas { - pub fn new(fstr: &String) -> Self { + pub fn new() -> Self { let ctx = Context::commonsense(); - let func = ExpressionFunction::from_string(fstr.clone(), ctx.operations()); Self { graph: Cache::default(), - func: Mutex::new(FunctionCache::new(func)), + funcs: Mutex::new(Vec::new()), ctx, } } @@ -34,6 +33,26 @@ impl GraphCanvas { pub fn clear(&self) { self.graph.clear(); } + + pub fn push(&mut self, f: &str) { + if let Ok(f) = ExpressionFunction::from_string(f.to_string(), self.ctx.operations()) { + self.funcs.lock().unwrap().push(Some(FunctionCache::new(f))); + } else { + self.funcs.lock().unwrap().push(None); + } + } + + pub fn set(&mut self, i: usize, f: &str) { + if let Ok(f) = ExpressionFunction::from_string(f.to_string(), self.ctx.operations()) { + self.funcs.lock().unwrap()[i] = Some(FunctionCache::new(f)); + } else { + self.funcs.lock().unwrap().push(None); + } + } + + pub fn remove(&mut self, i: usize) { + self.funcs.lock().unwrap().remove(i); + } } #[derive(Copy, Clone)] @@ -190,28 +209,29 @@ impl canvas::Program for GraphCanvas { }); let step = (step / 10).max(1); - let mut y1 = self - .func + + for func in self + .funcs .lock() .unwrap() - .eval(Complex::new(rect.x as f64, 0.0), &self.ctx) - .real as f32; - for x in (rect.x as i64..(rect.x + rect.width) as i64).step_by(step) { - for d in 0..10 { - let d = d as f32 / 10.0; - let x1 = x as f32 + d * step as f32; - let x2 = x as f32 + (d + 0.1) * step as f32; - let y2 = self - .func - .lock() - .unwrap() - .eval(Complex::new(x2 as f64, 0.0), &self.ctx) - .real as f32; - if y1.is_finite() && !y1.is_nan() && y2.is_finite() && !y2.is_nan() { - let line = Path::line(state.map_coords(x1, y1), state.map_coords(x2, y2)); - frame.stroke(&line, graphline.clone()) + .iter_mut() + .filter(|f| f.is_some()) + .map(|f| f.as_mut().unwrap()) + { + let mut y1 = func.eval(Complex::new(rect.x as f64, 0.0), &self.ctx).real as f32; + for x in (rect.x as i64..(rect.x + rect.width) as i64).step_by(step) { + for d in 0..10 { + let d = d as f32 / 10.0; + let x1 = x as f32 + d * step as f32; + let x2 = x as f32 + (d + 0.1) * step as f32; + let y2 = func.eval(Complex::new(x2 as f64, 0.0), &self.ctx).real as f32; + if y1.is_finite() && !y1.is_nan() && y2.is_finite() && !y2.is_nan() { + let line = + Path::line(state.map_coords(x1, y1), state.map_coords(x2, y2)); + frame.stroke(&line, graphline.clone()) + } + y1 = y2; } - y1 = y2; } } }); @@ -232,7 +252,7 @@ impl canvas::Program for GraphCanvas { if let canvas::Event::Mouse(mouse::Event::ButtonPressed(_)) = event { state.interaction = Interaction::Grabbing; state.last_position = cursor.position(); - return (event::Status::Captured, Some(Message::UpdateScreen)); + return (event::Status::Captured, Some(Message::RefreshGraphCanvas)); } if let canvas::Event::Mouse(mouse::Event::CursorMoved { position }) = event { @@ -242,7 +262,7 @@ impl canvas::Program for GraphCanvas { state.center.y += position.y - lp.y; } state.last_position = Some(position); - return (event::Status::Captured, Some(Message::UpdateScreen)); + return (event::Status::Captured, Some(Message::RefreshGraphCanvas)); } } @@ -259,7 +279,7 @@ impl canvas::Program for GraphCanvas { state.scale *= 1.1; } state.scale = state.scale.max(0.000001); - return (event::Status::Captured, Some(Message::UpdateScreen)); + return (event::Status::Captured, Some(Message::RefreshGraphCanvas)); } _ => {} } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index b7c11fb..9ea4662 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -5,8 +5,10 @@ pub mod pane; #[derive(Debug, Clone)] pub enum Message { - InputChanged(String), - UpdateFunction, - UpdateScreen, + InputChanged(String, usize), + AddFunction, + RemoveFunction(usize), + UpdateFunction(usize), + RefreshGraphCanvas, Resized(ResizeEvent) } -- cgit v1.2.3-70-g09d2