| 492 | |
| 493 | pub(crate) fn cursor_inside(&self) -> bool { |
| 494 | self.point_inside(self.cursor_position.x, self.cursor_position.y) |
| 495 | } |
| 496 | |
| 497 | fn cursor_local_position(&self, cursor: mouse::Cursor, allow_levitating: bool) -> Option<Vec2> { |
| 498 | let position = match cursor { |
| 499 | mouse::Cursor::Available(position) => position, |
| 500 | mouse::Cursor::Levitating(position) if allow_levitating => position, |
| 501 | mouse::Cursor::Levitating(_) | mouse::Cursor::Unavailable => return None, |
| 502 | }; |
| 503 | |
| 504 | Some(Vec2::new( |
| 505 | position.x - self.bounds.x, |
| 506 | position.y - self.bounds.y, |
| 507 | )) |
| 508 | } |
| 509 | |
| 510 | fn available_cursor_local_position_inside(&self, cursor: mouse::Cursor) -> Option<Vec2> { |
| 511 | let position = self.cursor_local_position(cursor, false)?; |
| 512 | self.point_inside(position.x, position.y) |
| 513 | .then_some(position) |
| 514 | } |
| 515 | |
| 516 | pub(crate) fn available_cursor_is_inside(&self, cursor: mouse::Cursor) -> bool { |
| 517 | self.available_cursor_local_position_inside(cursor) |
| 518 | .is_some() |
| 519 | } |
| 520 | |
| 521 | pub(crate) fn drag_in_progress(&self) -> bool { |
| 522 | self.pan.active || self.selection.active || self.drag.active |
| 523 | } |
| 524 | |
| 525 | fn drag_in_progress_for(&self, button: mouse::Button) -> bool { |
| 526 | (self.pan.active && self.pan.button == Some(button)) |
| 527 | || (self.selection.active && self.selection.button == Some(button)) |
| 528 | || (self.drag.active && self.drag.button == Some(button)) |
| 529 | } |
| 530 | |
| 531 | pub(crate) fn handle_mouse_event( |
| 532 | &mut self, |
| 533 | event: Event, |
| 534 | cursor: mouse::Cursor, |
| 535 | widget: &PlotWidget, |
| 536 | publish_hover_pick: &mut Option<HoverPickEvent>, |
| 537 | publish_drag_event: &mut Option<DragEvent>, |
| 538 | ) -> bool { |
| 539 | // Only request redraws when something actually changes or when we need |
| 540 | // to service a picking request for a new cursor position. |
| 541 | let mut needs_redraw = false; |
| 542 | |
| 543 | let viewport: DVec2 = Vec2::new(self.bounds.width, self.bounds.height).into(); |
| 544 | |
| 545 | match event { |
| 546 | Event::CursorMoved { .. } => { |
| 547 | let Some(position) = self.cursor_local_position(cursor, self.drag_in_progress()) |
| 548 | else { |
| 549 | if self.picking.last_hover_cache.is_some() { |
| 550 | self.picking.last_hover_cache = None; |
| 551 | needs_redraw = true; |