Implement event capturing for Scrollable

This commit is contained in:
Héctor Ramón Jiménez 2020-11-12 00:53:39 +01:00
parent 451bf8dc84
commit fd275a2fee

View File

@ -196,24 +196,6 @@ where
let content = layout.children().next().unwrap(); let content = layout.children().next().unwrap();
let content_bounds = content.bounds(); 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 offset = self.state.offset(bounds, content_bounds);
let scrollbar = renderer.scrollbar( let scrollbar = renderer.scrollbar(
bounds, bounds,
@ -228,12 +210,62 @@ where
.map(|scrollbar| scrollbar.is_mouse_over(cursor_position)) .map(|scrollbar| scrollbar.is_mouse_over(cursor_position))
.unwrap_or(false); .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() { if self.state.is_scroller_grabbed() {
match event { match event {
Event::Mouse(mouse::Event::ButtonReleased( Event::Mouse(mouse::Event::ButtonReleased(
mouse::Button::Left, mouse::Button::Left,
)) => { )) => {
self.state.scroller_grabbed_at = None; self.state.scroller_grabbed_at = None;
return event::Status::Captured;
} }
Event::Mouse(mouse::Event::CursorMoved { .. }) => { Event::Mouse(mouse::Event::CursorMoved { .. }) => {
if let (Some(scrollbar), Some(scroller_grabbed_at)) = if let (Some(scrollbar), Some(scroller_grabbed_at)) =
@ -247,6 +279,8 @@ where
bounds, bounds,
content_bounds, content_bounds,
); );
return event::Status::Captured;
} }
} }
_ => {} _ => {}
@ -271,6 +305,8 @@ where
self.state.scroller_grabbed_at = self.state.scroller_grabbed_at =
Some(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 { event::Status::Ignored
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,
)
} }
fn draw( fn draw(