From 8bd487dc11b420931ddf6b98d11a0147cc272a39 Mon Sep 17 00:00:00 2001 From: Francesco Magliocca Date: Mon, 9 Nov 2020 17:18:00 +0100 Subject: [PATCH] Use a RadioGroup to show which canvas tool is active --- src/main.rs | 47 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/src/main.rs b/src/main.rs index 5721e1e..607a727 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,10 +16,15 @@ use druid::kurbo::{BezPath, Rect}; use druid::widget::prelude::*; -use druid::{AppLauncher, Color, Data, Event, LocalizedString, WindowDesc}; +use druid::{AppLauncher, Color, Data, Lens, Event, LocalizedString, WidgetExt, WindowDesc}; use stiletto::{CanvasElement, VersionedCanvas, Canvas}; +#[derive(Clone, Data, PartialEq)] +enum CanvasToolType { + Pen, + Eraser +} // Tools that can be used to interact with the canvas #[derive(Clone, Data)] @@ -35,6 +40,33 @@ impl CanvasTool { fn new_eraser() -> CanvasTool { CanvasTool::Eraser { eraser_rect: None } } + + fn tool_type(&self) -> CanvasToolType { + match self { + CanvasTool::Pen { current_element: _ } => CanvasToolType::Pen, + CanvasTool::Eraser { eraser_rect: _ } => CanvasToolType::Eraser, + } + } +} + +struct CanvasToolLens; + +impl Lens for CanvasToolLens { + fn with R>(&self, data: &CanvasData, f: F) -> R { + f(&data.current_tool.tool_type()) + } + + fn with_mut R>(&self, data: &mut CanvasData, f: F) -> R { + let mut curr_type = data.current_tool.tool_type(); + let result = f(&mut curr_type); + + match curr_type { + CanvasToolType::Pen => data.current_tool = CanvasTool::new_pen(), + CanvasToolType::Eraser => data.current_tool = CanvasTool::new_eraser(), + } + + result + } } #[derive(Clone, Data)] @@ -48,9 +80,7 @@ impl CanvasData { self.current_element.is_some() }*/ - fn set_tool(&mut self, tool: CanvasTool) { - self.current_tool = tool; - } + const CURRENT_TOOL_LENS: CanvasToolLens = CanvasToolLens; fn perform_undo(&mut self) { self.elements.undo(); @@ -133,6 +163,7 @@ impl CanvasData { } } + struct CanvasWidget; impl Widget for CanvasWidget { @@ -231,15 +262,17 @@ impl Widget for CanvasWidget { } fn build_ui() -> impl Widget { - use druid::widget::{Align, Button, CrossAxisAlignment, Flex, SizedBox}; + use druid::widget::{Align, Button, RadioGroup, CrossAxisAlignment, Flex, SizedBox}; + + let radio_group = RadioGroup::new(vec![("Pen", CanvasToolType::Pen), ("Eraser", CanvasToolType::Eraser)]); + let toolbar = Flex::row() .cross_axis_alignment(CrossAxisAlignment::Center) .with_spacer(30.0) .with_child(Button::new("Undo").on_click(|_ctx, data: &mut CanvasData, _env| data.perform_undo())) .with_child(Button::new("Redo").on_click(|_ctx, data: &mut CanvasData, _env| data.perform_redo())) - .with_child(Button::new("Pen").on_click(|_ctx, data: &mut CanvasData, _env| data.set_tool(CanvasTool::new_pen()))) - .with_child(Button::new("Eraser").on_click(|_ctx, data: &mut CanvasData, _env| data.set_tool(CanvasTool::new_eraser()))); + .with_child(radio_group.lens(CanvasData::CURRENT_TOOL_LENS)); Flex::column() .cross_axis_alignment(CrossAxisAlignment::Center)