Use a RadioGroup to show which canvas tool is active

This commit is contained in:
Francesco Magliocca 2020-11-09 17:18:00 +01:00
parent be11d8e6ee
commit 8bd487dc11
1 changed files with 40 additions and 7 deletions

View File

@ -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<CanvasData, CanvasToolType> for CanvasToolLens {
fn with<R, F: FnOnce(&CanvasToolType) -> R>(&self, data: &CanvasData, f: F) -> R {
f(&data.current_tool.tool_type())
}
fn with_mut<R, F: FnOnce(&mut CanvasToolType) -> 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<CanvasData> for CanvasWidget {
@ -231,15 +262,17 @@ impl Widget<CanvasData> for CanvasWidget {
}
fn build_ui() -> impl Widget<CanvasData> {
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)