Add a second pen of different color
This commit is contained in:
parent
3c6f161a54
commit
0b74394042
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
src/main.rs
10
src/main.rs
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
23
src/tool.rs
23
src/tool.rs
|
|
@ -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),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue