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>;
#[derive(Serialize, Deserialize)]
#[serde(remote = "druid::Color")]
enum ColorDef {
Rgba32(u32)
}
#[derive(Debug, Clone, druid::Data, Serialize, Deserialize)]
pub enum CanvasElement {
Freehand { path: Path, thickness: f64 },
Freehand {
path: Path,
thickness: f64,
#[serde(with = "ColorDef")]
stroke_color: druid::Color,
},
}
impl CanvasElement {
pub fn bounding_box(&self) -> druid::Rect {
match self {
CanvasElement::Freehand { path, thickness } => {
CanvasElement::Freehand { path, thickness, .. } => {
use druid::kurbo::Shape;
path.kurbo_path
.bounding_box()
@ -45,10 +56,9 @@ impl CanvasElement {
}
pub fn draw(&self, ctx: &mut druid::PaintCtx) {
match self {
CanvasElement::Freehand { path, thickness } => {
CanvasElement::Freehand { path, thickness, stroke_color } => {
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 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@ -84,32 +85,41 @@ impl Serialize for Path {
}
}
struct PathDeserializer;
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>
impl<'de> Deserialize<'de> for Path {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
A: SeqAccess<'de>,
D: Deserializer<'de>,
{
use druid::kurbo::BezPath;
struct PathVisitor;
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);
impl<'de> Visitor<'de> for PathVisitor{
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
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,
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 {
canvas: CanvasState {
versioned_canvas: VersionedCanvas::new(vector![]),
@ -55,10 +59,14 @@ pub fn main() {
tool_params: default_pen_params,
selected: true,
},
CanvasToolIconState {
tool_params: default_pen_params_2,
selected: false,
},
CanvasToolIconState {
tool_params: CanvasToolParams::Eraser,
selected: false,
}
},
],
current_tool: 0,
};

View File

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