From 3686f51e2c53e1d8e8886b545606c11b149daf19 Mon Sep 17 00:00:00 2001 From: Enrico Lumetti Date: Sun, 8 Nov 2020 13:00:29 +0100 Subject: [PATCH] Working again --- src/main.rs | 157 +++++++++++++++++++++------------------------------- 1 file changed, 63 insertions(+), 94 deletions(-) diff --git a/src/main.rs b/src/main.rs index f65cfff..2e9faf7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,125 +17,82 @@ use druid::im::{vector, Vector}; use druid::kurbo::BezPath; use druid::widget::prelude::*; -use druid::{AppLauncher, Color, Data, Event, LocalizedString, Rect, WindowDesc}; -use std::rc::Rc; +use druid::{AppLauncher, Color, Data, Event, LocalizedString, WindowDesc}; mod stiletto { use druid::widget::prelude::*; - pub trait CanvasElement: CanvasElementData { - //: CanvasElementData { - /// returns the axis-aligned bounding box - fn bounding_box(&self) -> druid::Rect; - - fn draw(&self, ctx: &mut druid::PaintCtx); - - fn get_path(&self) -> Option<&CanvasPath> { - None - } - - fn get_path_mut(&mut self) -> Option<&mut CanvasPath> { - None - } - } - - pub trait CanvasElementData { - fn clone_box(&self) -> Box; - } - - impl CanvasElementData for T - where - T: 'static + CanvasElement + druid::Data - { - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } - } - impl Clone for Box { - fn clone(&self) -> Self { - self.clone_box() - } - } - - impl druid::Data for Box { - fn same(&self, other: &Self) -> bool { - if let (Some(p1), Some(p2)) = (self.get_path(), other.get_path()) - { - p1.same(p2) - } else { - false - } - } - } #[derive(Clone, druid::Data)] - pub struct CanvasPath { + pub struct Path { pub kurbo_path: druid::kurbo::BezPath, } - impl CanvasElement for CanvasPath { - fn bounding_box(&self) -> druid::Rect { - use druid::kurbo::Shape; - self.kurbo_path.bounding_box() + #[derive(Clone, druid::Data)] + pub enum CanvasElement { + Path(Path), + } + + impl CanvasElement { + pub fn bounding_box(&self) -> druid::Rect { + match self { + CanvasElement::Path(p) => { + use druid::kurbo::Shape; + p.kurbo_path.bounding_box() + } + } + } + pub fn draw(&self, ctx: &mut druid::PaintCtx) { + match self { + CanvasElement::Path(p) => { + let stroke_color = druid::Color::rgb8(0, 128, 0); + ctx.stroke(&p.kurbo_path, &stroke_color, 2.0); + } + } } - fn draw(&self, ctx: &mut druid::PaintCtx) { - let stroke_color = druid::Color::rgb8(0, 128, 0); - ctx.stroke(&self.kurbo_path, &stroke_color, 2.0); - } - - fn get_path(&self) -> Option<&CanvasPath> { - None - } - - fn get_path_mut(&mut self) -> Option<&mut CanvasPath> { - Some(self) + pub fn get_path_mut(&mut self) -> Option<&mut Path> { + match self { + CanvasElement::Path(p) => Some(p), + } } } } struct CanvasWidget; +use stiletto::CanvasElement; + #[derive(Clone, Data)] struct CanvasData { - current_element: Option>, - elements: Vector>>, + current_element: Option, + elements: Vector, is_drawing: bool, } impl Widget for CanvasWidget { - fn event( - &mut self, - _ctx: &mut EventCtx, - event: &Event, - data: &mut CanvasData, - _env: &Env, - ) { + fn event(&mut self, _ctx: &mut EventCtx, event: &Event, data: &mut CanvasData, _env: &Env) { match event { Event::MouseDown(mouse_event) => { - if true - /*&& mouse_event.pointer_type == druid::PointerType::Stylus || mouse_event.pointer_type == druid::PointerType::Mouse*/ - { - data.is_drawing = true; - let mut kurbo_path = BezPath::new(); - kurbo_path.move_to((mouse_event.pos.x, mouse_event.pos.y)); - data.current_element = Some(Box::new(stiletto::CanvasPath { kurbo_path } )); - } + data.is_drawing = true; + let mut kurbo_path = BezPath::new(); + kurbo_path.move_to((mouse_event.pos.x, mouse_event.pos.y)); + data.current_element = Some(CanvasElement::Path(stiletto::Path { kurbo_path })); } Event::MouseMove(mouse_event) => { - if data.is_drawing - /*&& (mouse_event.pointer_type == druid::PointerType::Stylus || mouse_event.pointer_type == druid::PointerType::Mouse)*/ - { - let current_path = data.current_element.as_mut().unwrap().get_path_mut().unwrap(); - - current_path - .kurbo_path - .line_to((mouse_event.pos.x, mouse_event.pos.y)); + if data.is_drawing { + if let Some(current_element) = data.current_element.as_mut() { + current_element + .get_path_mut() + .unwrap() + .kurbo_path + .line_to((mouse_event.pos.x, mouse_event.pos.y)); + } } } Event::MouseUp(_) => { if data.is_drawing { - if let Some(b) = data.current_element.as_mut() { - data.elements.push_back(Rc::new(b)); + if let Some(current_element) = data.current_element.take() { + data.elements.push_back(current_element); data.is_drawing = false; } } @@ -156,11 +113,21 @@ impl Widget for CanvasWidget { fn update( &mut self, ctx: &mut UpdateCtx, - _old_data: &CanvasData, - _data: &CanvasData, + old_data: &CanvasData, + data: &CanvasData, _env: &Env, ) { - ctx.request_paint_rect(Rect::new(0., 0., 200., 200.)); + // the current_element is moved to the elements array, no need to repaint + if old_data.is_drawing && !data.is_drawing { + return; + } + if data.is_drawing { + data.current_element.as_ref().map(|e| { + ctx.request_paint_rect(e.bounding_box()); + }); + } else { + ctx.request_paint(); + } } fn layout( @@ -195,6 +162,9 @@ impl Widget for CanvasWidget { for element in &data.elements { element.draw(ctx); } + if let Some(element) = &data.current_element { + element.draw(ctx); + } } } @@ -202,8 +172,7 @@ pub fn main() { let window = WindowDesc::new(|| CanvasWidget {}) //.window_size((1024.0, 1400.0)) .title( - LocalizedString::new("custom-widget-demo-window-title") - .with_placeholder("Fancy Colors"), + LocalizedString::new("custom-widget-demo-window-title").with_placeholder("Stiletto"), ); let canvas_data = CanvasData { current_element: None,