Combined presenter mouse region event dispatching and added support up_out, and drag_over

This commit is contained in:
K Simmons 2022-07-22 14:58:55 -07:00
parent a650c146f1
commit 86fdd55fd4
2 changed files with 43 additions and 42 deletions

View file

@ -65,23 +65,6 @@ impl Presenter {
} }
} }
// pub fn dispatch_path(&self, app: &AppContext) -> Vec<usize> {
// let mut path = Vec::new();
// if let Some(view_id) = app.focused_view_id(self.window_id) {
// self.compute_dispatch_path_from(view_id, &mut path)
// }
// path
// }
// pub(crate) fn compute_dispatch_path_from(&self, mut view_id: usize, path: &mut Vec<usize>) {
// path.push(view_id);
// while let Some(parent_id) = self.parents.get(&view_id).copied() {
// path.push(parent_id);
// view_id = parent_id;
// }
// path.reverse();
// }
pub fn invalidate( pub fn invalidate(
&mut self, &mut self,
invalidation: &mut WindowInvalidation, invalidation: &mut WindowInvalidation,
@ -237,15 +220,12 @@ impl Presenter {
let mut events_to_send = Vec::new(); let mut events_to_send = Vec::new();
match &event { match &event {
Event::MouseDown( Event::MouseDown(e @ MouseButtonEvent { position, .. }) => {
e @ MouseButtonEvent {
position, button, ..
},
) => {
let mut hit = false; let mut hit = false;
for (region, _) in self.mouse_regions.iter().rev() { for (region, _) in self.mouse_regions.iter().rev() {
if region.bounds.contains_point(*position) { if region.bounds.contains_point(*position) {
if !std::mem::replace(&mut hit, true) { if !hit {
hit = true;
invalidated_views.push(region.view_id); invalidated_views.push(region.view_id);
events_to_send events_to_send
.push((region.clone(), MouseRegionEvent::Down(e.clone()))); .push((region.clone(), MouseRegionEvent::Down(e.clone())));
@ -258,15 +238,12 @@ impl Presenter {
} }
} }
} }
Event::MouseUp( Event::MouseUp(e @ MouseButtonEvent { position, .. }) => {
e @ MouseButtonEvent {
position, button, ..
},
) => {
let mut hit = false; let mut hit = false;
for (region, _) in self.mouse_regions.iter().rev() { for (region, _) in self.mouse_regions.iter().rev() {
if region.bounds.contains_point(*position) { if region.bounds.contains_point(*position) {
if !std::mem::replace(&mut hit, true) { if !hit {
hit = true;
invalidated_views.push(region.view_id); invalidated_views.push(region.view_id);
events_to_send events_to_send
.push((region.clone(), MouseRegionEvent::Up(e.clone()))); .push((region.clone(), MouseRegionEvent::Up(e.clone())));
@ -306,7 +283,10 @@ impl Presenter {
self.handle_hover_events(&event, &mut invalidated_views, cx); self.handle_hover_events(&event, &mut invalidated_views, cx);
for (region, event) in events_to_send { for (region, event) in events_to_send {
handled = true; if event.is_local() {
handled = true;
}
if let Some(callback) = region.handlers.get(&event.handler_key()) { if let Some(callback) = region.handlers.get(&event.handler_key()) {
event_cx.with_current_view(region.view_id, |event_cx| { event_cx.with_current_view(region.view_id, |event_cx| {
callback(event, event_cx); callback(event, event_cx);
@ -336,7 +316,8 @@ impl Presenter {
invalidated_views: &mut Vec<usize>, invalidated_views: &mut Vec<usize>,
cx: &'a mut MutableAppContext, cx: &'a mut MutableAppContext,
) -> (bool, EventContext<'a>) { ) -> (bool, EventContext<'a>) {
let mut hover_regions = Vec::new(); let mut events_to_send = Vec::new();
if let Event::MouseMoved( if let Event::MouseMoved(
e @ MouseMovedEvent { e @ MouseMovedEvent {
position, position,
@ -363,24 +344,24 @@ impl Presenter {
if let Some(region_id) = region.id() { if let Some(region_id) = region.id() {
if !self.hovered_region_ids.contains(&region_id) { if !self.hovered_region_ids.contains(&region_id) {
invalidated_views.push(region.view_id); invalidated_views.push(region.view_id);
let region_event = if let Some(pressed_button) = pressed_button { let region_event = if pressed_button.is_some() {
MouseRegionEvent::DragOver(true, e.clone()) MouseRegionEvent::DragOver(true, e.clone())
} else { } else {
MouseRegionEvent::Hover(true, e.clone()) MouseRegionEvent::Hover(true, e.clone())
}; };
hover_regions.push((region.clone(), region_event)); events_to_send.push((region.clone(), region_event));
self.hovered_region_ids.insert(region_id); self.hovered_region_ids.insert(region_id);
} }
} }
} else if let Some(region_id) = region.id() { } else if let Some(region_id) = region.id() {
if self.hovered_region_ids.contains(&region_id) { if self.hovered_region_ids.contains(&region_id) {
invalidated_views.push(region.view_id); invalidated_views.push(region.view_id);
let region_event = if let Some(pressed_button) = pressed_button { let region_event = if pressed_button.is_some() {
MouseRegionEvent::DragOver(false, e.clone()) MouseRegionEvent::DragOver(false, e.clone())
} else { } else {
MouseRegionEvent::Hover(false, e.clone()) MouseRegionEvent::Hover(false, e.clone())
}; };
hover_regions.push((region.clone(), region_event)); events_to_send.push((region.clone(), region_event));
self.hovered_region_ids.remove(&region_id); self.hovered_region_ids.remove(&region_id);
} }
} }
@ -390,11 +371,13 @@ impl Presenter {
let mut event_cx = self.build_event_context(cx); let mut event_cx = self.build_event_context(cx);
let mut handled = false; let mut handled = false;
for (hover_region, region_event) in hover_regions { for (region, event) in events_to_send {
handled = true; if event.is_local() {
if let Some(callback) = hover_region.handlers.get(&region_event.handler_key()) { handled = true;
event_cx.with_current_view(hover_region.view_id, |event_cx| { }
callback(region_event, event_cx); if let Some(callback) = region.handlers.get(&event.handler_key()) {
event_cx.with_current_view(region.view_id, |event_cx| {
callback(event, event_cx);
}) })
} }
} }

View file

@ -106,7 +106,7 @@ impl MouseRegion {
pub fn on_drag_over( pub fn on_drag_over(
mut self, mut self,
button: MouseButton, button: MouseButton,
handler: impl Fn(Vector2F, MouseMovedEvent, &mut EventContext) + 'static, handler: impl Fn(bool, MouseMovedEvent, &mut EventContext) + 'static,
) -> Self { ) -> Self {
self.handlers = self.handlers.on_drag_over(button, handler); self.handlers = self.handlers.on_drag_over(button, handler);
self self
@ -353,41 +353,59 @@ impl MouseRegionEvent {
pub fn move_disc() -> Discriminant<MouseRegionEvent> { pub fn move_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::Move(Default::default())) discriminant(&MouseRegionEvent::Move(Default::default()))
} }
pub fn drag_disc() -> Discriminant<MouseRegionEvent> { pub fn drag_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::Drag( discriminant(&MouseRegionEvent::Drag(
Default::default(), Default::default(),
Default::default(), Default::default(),
)) ))
} }
pub fn drag_over_disc() -> Discriminant<MouseRegionEvent> { pub fn drag_over_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::DragOver( discriminant(&MouseRegionEvent::DragOver(
Default::default(), Default::default(),
Default::default(), Default::default(),
)) ))
} }
pub fn hover_disc() -> Discriminant<MouseRegionEvent> { pub fn hover_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::Hover( discriminant(&MouseRegionEvent::Hover(
Default::default(), Default::default(),
Default::default(), Default::default(),
)) ))
} }
pub fn down_disc() -> Discriminant<MouseRegionEvent> { pub fn down_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::Down(Default::default())) discriminant(&MouseRegionEvent::Down(Default::default()))
} }
pub fn up_disc() -> Discriminant<MouseRegionEvent> { pub fn up_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::Up(Default::default())) discriminant(&MouseRegionEvent::Up(Default::default()))
} }
pub fn up_out_disc() -> Discriminant<MouseRegionEvent> { pub fn up_out_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::UpOut(Default::default())) discriminant(&MouseRegionEvent::UpOut(Default::default()))
} }
pub fn click_disc() -> Discriminant<MouseRegionEvent> { pub fn click_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::Click(Default::default())) discriminant(&MouseRegionEvent::Click(Default::default()))
} }
pub fn down_out_disc() -> Discriminant<MouseRegionEvent> { pub fn down_out_disc() -> Discriminant<MouseRegionEvent> {
discriminant(&MouseRegionEvent::DownOut(Default::default())) discriminant(&MouseRegionEvent::DownOut(Default::default()))
} }
pub fn scroll_wheel_disc() -> Discriminant<MouseRegionEvent> { pub fn scroll_wheel_disc() -> Discriminant<MouseRegionEvent> {
std::mem::discriminant(&MouseRegionEvent::ScrollWheel(Default::default())) discriminant(&MouseRegionEvent::ScrollWheel(Default::default()))
}
pub fn is_local(&self) -> bool {
match self {
MouseRegionEvent::DownOut(_)
| MouseRegionEvent::UpOut(_)
| MouseRegionEvent::DragOver(_, _) => false,
_ => true,
}
} }
pub fn handler_key(&self) -> (Discriminant<MouseRegionEvent>, Option<MouseButton>) { pub fn handler_key(&self) -> (Discriminant<MouseRegionEvent>, Option<MouseButton>) {