use iced::widget::canvas::{self, Canvas, Event, Program};
use iced::{mouse, Element, Point, Rectangle, Color};
struct DrawingBoard {
// Program configuration
}
#[derive(Default)]
struct State {
points: Vec<Point>,
dragging: bool,
}
#[derive(Debug, Clone)]
enum Message {
PointAdded(Point),
}
impl Program<Message> for DrawingBoard {
type State = State;
fn draw(
&self,
state: &State,
renderer: &Renderer,
_theme: &Theme,
bounds: Rectangle,
_cursor: mouse::Cursor,
) -> Vec<canvas::Geometry> {
let mut frame = canvas::Frame::new(renderer, bounds.size());
// Draw all points
for point in &state.points {
let circle = canvas::Path::circle(*point, 3.0);
frame.fill(&circle, Color::from_rgb(0.0, 0.0, 1.0));
}
vec![frame.into_geometry()]
}
fn update(
&self,
state: &mut State,
event: &Event,
bounds: Rectangle,
cursor: mouse::Cursor,
) -> Option<canvas::Action<Message>> {
match event {
Event::Mouse(mouse::Event::ButtonPressed(mouse::Button::Left)) => {
if let Some(position) = cursor.position_in(bounds) {
state.points.push(position);
state.dragging = true;
return Some(canvas::Action::publish(Message::PointAdded(position)));
}
}
Event::Mouse(mouse::Event::ButtonReleased(mouse::Button::Left)) => {
state.dragging = false;
}
Event::Mouse(mouse::Event::CursorMoved { .. }) => {
if state.dragging {
if let Some(position) = cursor.position_in(bounds) {
state.points.push(position);
return Some(canvas::Action::request_redraw());
}
}
}
_ => {}
}
None
}
fn mouse_interaction(
&self,
_state: &State,
bounds: Rectangle,
cursor: mouse::Cursor,
) -> mouse::Interaction {
if cursor.is_over(bounds) {
mouse::Interaction::Crosshair
} else {
mouse::Interaction::default()
}
}
}