Add a second pen of different color

This commit is contained in:
Enrico Lumetti 2021-02-24 15:51:00 +01:00
parent 3c6f161a54
commit 0b74394042
3 changed files with 68 additions and 45 deletions

View File

@ -27,15 +27,26 @@ pub struct Path {
pub type Canvas = Vector<CanvasElement>; pub type Canvas = Vector<CanvasElement>;
#[derive(Serialize, Deserialize)]
#[serde(remote = "druid::Color")]
enum ColorDef {
Rgba32(u32)
}
#[derive(Debug, Clone, druid::Data, Serialize, Deserialize)] #[derive(Debug, Clone, druid::Data, Serialize, Deserialize)]
pub enum CanvasElement { pub enum CanvasElement {
Freehand { path: Path, thickness: f64 }, Freehand {
path: Path,
thickness: f64,
#[serde(with = "ColorDef")]
stroke_color: druid::Color,
},
} }
impl CanvasElement { impl CanvasElement {
pub fn bounding_box(&self) -> druid::Rect { pub fn bounding_box(&self) -> druid::Rect {
match self { match self {
CanvasElement::Freehand { path, thickness } => { CanvasElement::Freehand { path, thickness, .. } => {
use druid::kurbo::Shape; use druid::kurbo::Shape;
path.kurbo_path path.kurbo_path
.bounding_box() .bounding_box()
@ -45,10 +56,9 @@ impl CanvasElement {
} }
pub fn draw(&self, ctx: &mut druid::PaintCtx) { pub fn draw(&self, ctx: &mut druid::PaintCtx) {
match self { match self {
CanvasElement::Freehand { path, thickness } => { CanvasElement::Freehand { path, thickness, stroke_color } => {
use druid::RenderContext; use druid::RenderContext;
let stroke_color = druid::Color::rgb8(0, 128, 0); ctx.stroke(&path.kurbo_path, &*stroke_color, *thickness);
ctx.stroke(&path.kurbo_path, &stroke_color, *thickness);
} }
} }
} }
@ -60,15 +70,6 @@ impl CanvasElement {
} }
} }
impl<'de> Deserialize<'de> for Path {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(PathDeserializer)
}
}
impl Serialize for Path { impl Serialize for Path {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
@ -84,32 +85,41 @@ impl Serialize for Path {
} }
} }
struct PathDeserializer; impl<'de> Deserialize<'de> for Path {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
impl<'de> Visitor<'de> for PathDeserializer {
type Value = Path;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(formatter, "A sequence of 2D points")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where where
A: SeqAccess<'de>, D: Deserializer<'de>,
{ {
use druid::kurbo::BezPath; struct PathVisitor;
let mut kurbo_path = BezPath::new(); impl<'de> Visitor<'de> for PathVisitor{
let mut first_element = true; type Value = Path;
while let Some(point) = seq.next_element::<(f64, f64)>()? {
if first_element { fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
kurbo_path.move_to(point); write!(formatter, "A sequence of 2D points")
first_element = false; }
} else {
kurbo_path.line_to(point); fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
use druid::kurbo::BezPath;
let mut kurbo_path = BezPath::new();
let mut first_element = true;
while let Some(point) = seq.next_element::<(f64, f64)>()? {
if first_element {
kurbo_path.move_to(point);
first_element = false;
} else {
kurbo_path.line_to(point);
}
}
Ok(Path { kurbo_path })
} }
} }
Ok(Path { kurbo_path }) deserializer.deserialize_seq(PathVisitor)
} }
} }

View File

@ -45,6 +45,10 @@ pub fn main() {
thickness: 2.0, thickness: 2.0,
color: Color::rgb(0, 0, 0), color: Color::rgb(0, 0, 0),
}; };
let default_pen_params_2 = CanvasToolParams::Pen {
thickness: 2.0,
color: Color::rgb(255, 0, 0),
};
let canvas_data = StilettoState { let canvas_data = StilettoState {
canvas: CanvasState { canvas: CanvasState {
versioned_canvas: VersionedCanvas::new(vector![]), versioned_canvas: VersionedCanvas::new(vector![]),
@ -55,10 +59,14 @@ pub fn main() {
tool_params: default_pen_params, tool_params: default_pen_params,
selected: true, selected: true,
}, },
CanvasToolIconState {
tool_params: default_pen_params_2,
selected: false,
},
CanvasToolIconState { CanvasToolIconState {
tool_params: CanvasToolParams::Eraser, tool_params: CanvasToolParams::Eraser,
selected: false, selected: false,
} },
], ],
current_tool: 0, current_tool: 0,
}; };

View File

@ -36,7 +36,7 @@ pub enum CanvasToolType {
#[derive(Clone, Data)] #[derive(Clone, Data)]
pub enum CanvasToolState { pub enum CanvasToolState {
Idle, Idle,
DrawingFreehand { current_path: CanvasElement }, DrawingFreehand { pen_params: CanvasToolParams, current_path: CanvasElement },
} }
#[derive(Clone, Data)] #[derive(Clone, Data)]
@ -86,16 +86,21 @@ impl CanvasToolCtx {
(CanvasToolState::Idle, Event::MouseDown(mouse_event)) => { (CanvasToolState::Idle, Event::MouseDown(mouse_event)) => {
let mut kurbo_path = BezPath::new(); let mut kurbo_path = BezPath::new();
kurbo_path.move_to((mouse_event.pos.x, mouse_event.pos.y)); kurbo_path.move_to((mouse_event.pos.x, mouse_event.pos.y));
self.state = CanvasToolState::DrawingFreehand { if let CanvasToolParams::Pen{ thickness, color } = &self.initial_params {
current_path: CanvasElement::Freehand { self.state = CanvasToolState::DrawingFreehand {
path: canvas::Path { kurbo_path }, pen_params: self.initial_params.clone(),
thickness: 2.0, current_path: CanvasElement::Freehand {
}, path: canvas::Path { kurbo_path },
}; thickness: *thickness,
stroke_color: color.clone(),
},
};
}
} }
( (
CanvasToolState::DrawingFreehand { CanvasToolState::DrawingFreehand {
ref mut current_path, ref mut current_path,
..
}, },
Event::MouseMove(mouse_event), Event::MouseMove(mouse_event),
) => { ) => {
@ -108,7 +113,7 @@ impl CanvasToolCtx {
(CanvasToolState::DrawingFreehand { .. }, Event::MouseUp(_)) => { (CanvasToolState::DrawingFreehand { .. }, Event::MouseUp(_)) => {
vcanvas.update(move |canvas: &mut Canvas| { vcanvas.update(move |canvas: &mut Canvas| {
let current_state = std::mem::replace(&mut self.state, CanvasToolState::Idle); let current_state = std::mem::replace(&mut self.state, CanvasToolState::Idle);
if let CanvasToolState::DrawingFreehand { current_path } = current_state { if let CanvasToolState::DrawingFreehand { current_path, .. } = current_state {
canvas.push_back(current_path); canvas.push_back(current_path);
} }
}); });
@ -123,7 +128,7 @@ impl CanvasToolCtx {
pub fn paint(&self, ctx: &mut PaintCtx, _env: &Env) { pub fn paint(&self, ctx: &mut PaintCtx, _env: &Env) {
match &self.state { match &self.state {
CanvasToolState::DrawingFreehand { current_path } => current_path.draw(ctx), CanvasToolState::DrawingFreehand { current_path, .. } => current_path.draw(ctx),
_ => {} _ => {}
} }
} }