Implement event capturing for Scrollable
This commit is contained in:
parent
451bf8dc84
commit
fd275a2fee
@ -196,24 +196,6 @@ where
|
||||
let content = layout.children().next().unwrap();
|
||||
let content_bounds = content.bounds();
|
||||
|
||||
// TODO: Event capture. Nested scrollables should capture scroll events.
|
||||
if is_mouse_over {
|
||||
match event {
|
||||
Event::Mouse(mouse::Event::WheelScrolled { delta }) => {
|
||||
match delta {
|
||||
mouse::ScrollDelta::Lines { y, .. } => {
|
||||
// TODO: Configurable speed (?)
|
||||
self.state.scroll(y * 60.0, bounds, content_bounds);
|
||||
}
|
||||
mouse::ScrollDelta::Pixels { y, .. } => {
|
||||
self.state.scroll(y, bounds, content_bounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let offset = self.state.offset(bounds, content_bounds);
|
||||
let scrollbar = renderer.scrollbar(
|
||||
bounds,
|
||||
@ -228,12 +210,62 @@ where
|
||||
.map(|scrollbar| scrollbar.is_mouse_over(cursor_position))
|
||||
.unwrap_or(false);
|
||||
|
||||
let event_status = {
|
||||
let cursor_position = if is_mouse_over && !is_mouse_over_scrollbar {
|
||||
Point::new(
|
||||
cursor_position.x,
|
||||
cursor_position.y
|
||||
+ self.state.offset(bounds, content_bounds) as f32,
|
||||
)
|
||||
} else {
|
||||
// TODO: Make `cursor_position` an `Option<Point>` so we can encode
|
||||
// cursor availability.
|
||||
// This will probably happen naturally once we add multi-window
|
||||
// support.
|
||||
Point::new(cursor_position.x, -1.0)
|
||||
};
|
||||
|
||||
self.content.on_event(
|
||||
event.clone(),
|
||||
content,
|
||||
cursor_position,
|
||||
messages,
|
||||
renderer,
|
||||
clipboard,
|
||||
)
|
||||
};
|
||||
|
||||
if let event::Status::Captured = event_status {
|
||||
return event::Status::Captured;
|
||||
}
|
||||
|
||||
if is_mouse_over {
|
||||
match event {
|
||||
Event::Mouse(mouse::Event::WheelScrolled { delta }) => {
|
||||
match delta {
|
||||
mouse::ScrollDelta::Lines { y, .. } => {
|
||||
// TODO: Configurable speed (?)
|
||||
self.state.scroll(y * 60.0, bounds, content_bounds);
|
||||
}
|
||||
mouse::ScrollDelta::Pixels { y, .. } => {
|
||||
self.state.scroll(y, bounds, content_bounds);
|
||||
}
|
||||
}
|
||||
|
||||
return event::Status::Captured;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
if self.state.is_scroller_grabbed() {
|
||||
match event {
|
||||
Event::Mouse(mouse::Event::ButtonReleased(
|
||||
mouse::Button::Left,
|
||||
)) => {
|
||||
self.state.scroller_grabbed_at = None;
|
||||
|
||||
return event::Status::Captured;
|
||||
}
|
||||
Event::Mouse(mouse::Event::CursorMoved { .. }) => {
|
||||
if let (Some(scrollbar), Some(scroller_grabbed_at)) =
|
||||
@ -247,6 +279,8 @@ where
|
||||
bounds,
|
||||
content_bounds,
|
||||
);
|
||||
|
||||
return event::Status::Captured;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@ -271,6 +305,8 @@ where
|
||||
|
||||
self.state.scroller_grabbed_at =
|
||||
Some(scroller_grabbed_at);
|
||||
|
||||
return event::Status::Captured;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -278,28 +314,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
let cursor_position = if is_mouse_over && !is_mouse_over_scrollbar {
|
||||
Point::new(
|
||||
cursor_position.x,
|
||||
cursor_position.y
|
||||
+ self.state.offset(bounds, content_bounds) as f32,
|
||||
)
|
||||
} else {
|
||||
// TODO: Make `cursor_position` an `Option<Point>` so we can encode
|
||||
// cursor availability.
|
||||
// This will probably happen naturally once we add multi-window
|
||||
// support.
|
||||
Point::new(cursor_position.x, -1.0)
|
||||
};
|
||||
|
||||
self.content.on_event(
|
||||
event,
|
||||
content,
|
||||
cursor_position,
|
||||
messages,
|
||||
renderer,
|
||||
clipboard,
|
||||
)
|
||||
event::Status::Ignored
|
||||
}
|
||||
|
||||
fn draw(
|
||||
|
Loading…
Reference in New Issue
Block a user