Implement event capturing for Canvas

This commit is contained in:
Héctor Ramón Jiménez 2020-11-12 01:24:59 +01:00
parent bf6c65b5ad
commit 3aca177132
5 changed files with 98 additions and 66 deletions

View file

@ -69,7 +69,8 @@ impl Sandbox for Example {
mod bezier {
use iced::{
canvas::{self, Canvas, Cursor, Event, Frame, Geometry, Path, Stroke},
canvas::event::{self, Event},
canvas::{self, Canvas, Cursor, Frame, Geometry, Path, Stroke},
mouse, Element, Length, Point, Rectangle,
};
@ -109,41 +110,51 @@ mod bezier {
event: Event,
bounds: Rectangle,
cursor: Cursor,
) -> Option<Curve> {
let cursor_position = cursor.position_in(&bounds)?;
) -> (event::Status, Option<Curve>) {
let cursor_position =
if let Some(position) = cursor.position_in(&bounds) {
position
} else {
return (event::Status::Ignored, None);
};
match event {
Event::Mouse(mouse_event) => match mouse_event {
mouse::Event::ButtonPressed(mouse::Button::Left) => {
match self.state.pending {
None => {
self.state.pending = Some(Pending::One {
from: cursor_position,
});
None
}
Some(Pending::One { from }) => {
self.state.pending = Some(Pending::Two {
from,
to: cursor_position,
});
Event::Mouse(mouse_event) => {
let message = match mouse_event {
mouse::Event::ButtonPressed(mouse::Button::Left) => {
match self.state.pending {
None => {
self.state.pending = Some(Pending::One {
from: cursor_position,
});
None
}
Some(Pending::Two { from, to }) => {
self.state.pending = None;
None
}
Some(Pending::One { from }) => {
self.state.pending = Some(Pending::Two {
from,
to: cursor_position,
});
Some(Curve {
from,
to,
control: cursor_position,
})
None
}
Some(Pending::Two { from, to }) => {
self.state.pending = None;
Some(Curve {
from,
to,
control: cursor_position,
})
}
}
}
}
_ => None,
},
_ => None,
_ => None,
};
(event::Status::Captured, message)
}
_ => (event::Status::Ignored, None),
}
}

View file

@ -153,9 +153,8 @@ impl Application for GameOfLife {
mod grid {
use crate::Preset;
use iced::{
canvas::{
self, Cache, Canvas, Cursor, Event, Frame, Geometry, Path, Text,
},
canvas::event::{self, Event},
canvas::{self, Cache, Canvas, Cursor, Frame, Geometry, Path, Text},
mouse, Color, Element, HorizontalAlignment, Length, Point, Rectangle,
Size, Vector, VerticalAlignment,
};
@ -328,12 +327,18 @@ mod grid {
event: Event,
bounds: Rectangle,
cursor: Cursor,
) -> Option<Message> {
) -> (event::Status, Option<Message>) {
if let Event::Mouse(mouse::Event::ButtonReleased(_)) = event {
self.interaction = Interaction::None;
}
let cursor_position = cursor.position_in(&bounds)?;
let cursor_position =
if let Some(position) = cursor.position_in(&bounds) {
position
} else {
return (event::Status::Ignored, None);
};
let cell = Cell::at(self.project(cursor_position, bounds.size()));
let is_populated = self.state.contains(&cell);
@ -345,28 +350,32 @@ mod grid {
match event {
Event::Mouse(mouse_event) => match mouse_event {
mouse::Event::ButtonPressed(button) => match button {
mouse::Button::Left => {
self.interaction = if is_populated {
Interaction::Erasing
} else {
Interaction::Drawing
};
mouse::Event::ButtonPressed(button) => {
let message = match button {
mouse::Button::Left => {
self.interaction = if is_populated {
Interaction::Erasing
} else {
Interaction::Drawing
};
populate.or(unpopulate)
}
mouse::Button::Right => {
self.interaction = Interaction::Panning {
translation: self.translation,
start: cursor_position,
};
populate.or(unpopulate)
}
mouse::Button::Right => {
self.interaction = Interaction::Panning {
translation: self.translation,
start: cursor_position,
};
None
}
_ => None,
},
None
}
_ => None,
};
(event::Status::Captured, message)
}
mouse::Event::CursorMoved { .. } => {
match self.interaction {
let message = match self.interaction {
Interaction::Drawing => populate,
Interaction::Erasing => unpopulate,
Interaction::Panning { translation, start } => {
@ -380,7 +389,14 @@ mod grid {
None
}
_ => None,
}
};
let event_status = match self.interaction {
Interaction::None => event::Status::Ignored,
_ => event::Status::Captured,
};
(event_status, message)
}
mouse::Event::WheelScrolled { delta } => match delta {
mouse::ScrollDelta::Lines { y, .. }
@ -413,12 +429,12 @@ mod grid {
self.grid_cache.clear();
}
None
(event::Status::Captured, None)
}
},
_ => None,
_ => (event::Status::Ignored, None),
},
_ => None,
_ => (event::Status::Ignored, None),
}
}