diff --git a/editor/src/ui.rs b/editor/src/ui.rs index 1a78886958..e965f7a3e0 100644 --- a/editor/src/ui.rs +++ b/editor/src/ui.rs @@ -189,6 +189,9 @@ impl GUI for UI { { self.state.set_current_selection(self.mouseover_something()); } + if input.window_lost_cursor() { + self.state.set_current_selection(None); + } let mut recalculate_current_selection = false; self.state.event( diff --git a/ezgui/src/canvas.rs b/ezgui/src/canvas.rs index fd464fab4f..73098b5710 100644 --- a/ezgui/src/canvas.rs +++ b/ezgui/src/canvas.rs @@ -15,8 +15,10 @@ pub struct Canvas { pub cam_y: f64, pub cam_zoom: f64, + // TODO We probably shouldn't even track screen-space cursor when we don't have the cursor. cursor_x: f64, cursor_y: f64, + window_has_cursor: bool, left_mouse_drag_from: Option, @@ -47,6 +49,7 @@ impl Canvas { cursor_x: 0.0, cursor_y: 0.0, + window_has_cursor: true, left_mouse_drag_from: None, window_width: f64::from(initial_width), @@ -82,6 +85,12 @@ impl Canvas { let delta = scroll * ZOOM_SPEED * self.cam_zoom; self.zoom_towards_mouse(delta); } + if input.window_gained_cursor() { + self.window_has_cursor = true; + } + if input.window_lost_cursor() { + self.window_has_cursor = false; + } } pub(crate) fn start_drawing(&self, g: &mut GfxCtx) { @@ -169,7 +178,11 @@ impl Canvas { } pub fn get_cursor_in_map_space(&self) -> Option { - Some(self.screen_to_map(self.get_cursor_in_screen_space())) + if self.window_has_cursor { + Some(self.screen_to_map(self.get_cursor_in_screen_space())) + } else { + None + } } pub fn screen_to_map(&self, pt: ScreenPt) -> Pt2D { diff --git a/ezgui/src/event.rs b/ezgui/src/event.rs index ef3f721a8d..cc6ef9c2b5 100644 --- a/ezgui/src/event.rs +++ b/ezgui/src/event.rs @@ -16,6 +16,8 @@ pub enum Event { // Time has passed; EventLoopMode::Animation is active Update, MouseMovedTo(ScreenPt), + WindowLostCursor, + WindowGainedCursor, // Vertical only MouseWheelScroll(f64), WindowResized(f64, f64), @@ -24,8 +26,8 @@ pub enum Event { impl Event { pub fn from_piston_event(ev: pi::Event) -> Event { use piston::input::{ - ButtonEvent, MouseCursorEvent, MouseScrollEvent, PressEvent, ReleaseEvent, ResizeEvent, - TouchEvent, UpdateEvent, + ButtonEvent, CursorEvent, MouseCursorEvent, MouseScrollEvent, PressEvent, ReleaseEvent, + ResizeEvent, TouchEvent, UpdateEvent, }; if let Some(pi::Button::Mouse(button)) = ev.press_args() { @@ -74,6 +76,14 @@ impl Event { if let Some(pair) = ev.resize_args() { return Event::WindowResized(f64::from(pair[0]), f64::from(pair[1])); } + if let Some(has) = ev.cursor_args() { + if has { + return Event::WindowGainedCursor; + } else { + // TODO Sometimes this doesn't happen! :( + return Event::WindowLostCursor; + } + } panic!("Unknown piston event {:?}", ev); } diff --git a/ezgui/src/input.rs b/ezgui/src/input.rs index bad799aa6f..812026e105 100644 --- a/ezgui/src/input.rs +++ b/ezgui/src/input.rs @@ -332,6 +332,13 @@ impl UserInput { self.event == Event::RightMouseButtonDown } + pub(crate) fn window_gained_cursor(&mut self) -> bool { + self.event == Event::WindowGainedCursor + } + pub fn window_lost_cursor(&mut self) -> bool { + self.event == Event::WindowLostCursor + } + pub fn get_moved_mouse(&self) -> Option { if self.context_menu_active() { return None; diff --git a/ezgui/src/runner.rs b/ezgui/src/runner.rs index 73271b4782..bca0edc680 100644 --- a/ezgui/src/runner.rs +++ b/ezgui/src/runner.rs @@ -88,10 +88,9 @@ pub fn run>(mut gui: G, window_title: &str) { } else { // Skip some events. use piston::input::{ - AfterRenderEvent, CursorEvent, FocusEvent, IdleEvent, MouseRelativeEvent, TextEvent, + AfterRenderEvent, FocusEvent, IdleEvent, MouseRelativeEvent, TextEvent, }; if ev.after_render_args().is_some() - || ev.cursor_args().is_some() || ev.focus_args().is_some() || ev.idle_args().is_some() || ev.mouse_relative_args().is_some()