Store mouse cursor position in Window (#940)

This commit is contained in:
Tomasz Sterna 2020-12-03 20:30:27 +01:00 committed by GitHub
parent b8f8d468db
commit 1f2e4171cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 66 additions and 9 deletions

View File

@ -41,6 +41,16 @@ pub struct CursorMoved {
pub position: Vec2, pub position: Vec2,
} }
#[derive(Debug, Clone)]
pub struct CursorEntered {
pub id: WindowId,
}
#[derive(Debug, Clone)]
pub struct CursorLeft {
pub id: WindowId,
}
/// An event that is sent whenever a window receives a character from the OS or underlying system. /// An event that is sent whenever a window receives a character from the OS or underlying system.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ReceivedCharacter { pub struct ReceivedCharacter {

View File

@ -9,7 +9,10 @@ pub use window::*;
pub use windows::*; pub use windows::*;
pub mod prelude { pub mod prelude {
pub use crate::{CursorMoved, ReceivedCharacter, Window, WindowDescriptor, Windows}; pub use crate::{
CursorEntered, CursorLeft, CursorMoved, ReceivedCharacter, Window, WindowDescriptor,
Windows,
};
} }
use bevy_app::prelude::*; use bevy_app::prelude::*;
@ -36,6 +39,8 @@ impl Plugin for WindowPlugin {
.add_event::<WindowCloseRequested>() .add_event::<WindowCloseRequested>()
.add_event::<CloseWindow>() .add_event::<CloseWindow>()
.add_event::<CursorMoved>() .add_event::<CursorMoved>()
.add_event::<CursorEntered>()
.add_event::<CursorLeft>()
.add_event::<ReceivedCharacter>() .add_event::<ReceivedCharacter>()
.init_resource::<Windows>(); .init_resource::<Windows>();

View File

@ -1,3 +1,4 @@
use bevy_math::Vec2;
use bevy_utils::Uuid; use bevy_utils::Uuid;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
@ -42,6 +43,7 @@ pub struct Window {
decorations: bool, decorations: bool,
cursor_visible: bool, cursor_visible: bool,
cursor_locked: bool, cursor_locked: bool,
cursor_position: Option<Vec2>,
mode: WindowMode, mode: WindowMode,
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
pub canvas: Option<String>, pub canvas: Option<String>,
@ -107,6 +109,7 @@ impl Window {
decorations: window_descriptor.decorations, decorations: window_descriptor.decorations,
cursor_visible: window_descriptor.cursor_visible, cursor_visible: window_descriptor.cursor_visible,
cursor_locked: window_descriptor.cursor_locked, cursor_locked: window_descriptor.cursor_locked,
cursor_position: None,
mode: window_descriptor.mode, mode: window_descriptor.mode,
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
canvas: window_descriptor.canvas.clone(), canvas: window_descriptor.canvas.clone(),
@ -145,13 +148,15 @@ impl Window {
.push(WindowCommand::SetResolution { width, height }); .push(WindowCommand::SetResolution { width, height });
} }
#[doc(hidden)] #[allow(missing_docs)]
#[inline]
pub fn update_resolution_from_backend(&mut self, width: u32, height: u32) { pub fn update_resolution_from_backend(&mut self, width: u32, height: u32) {
self.width = width; self.width = width;
self.height = height; self.height = height;
} }
#[doc(hidden)] #[allow(missing_docs)]
#[inline]
pub fn update_scale_factor_from_backend(&mut self, scale_factor: f64) { pub fn update_scale_factor_from_backend(&mut self, scale_factor: f64) {
self.scale_factor = scale_factor; self.scale_factor = scale_factor;
} }
@ -227,11 +232,22 @@ impl Window {
}); });
} }
#[inline]
pub fn cursor_position(&self) -> Option<Vec2> {
self.cursor_position
}
pub fn set_cursor_position(&mut self, x: i32, y: i32) { pub fn set_cursor_position(&mut self, x: i32, y: i32) {
self.command_queue self.command_queue
.push(WindowCommand::SetCursorPosition { x, y }); .push(WindowCommand::SetCursorPosition { x, y });
} }
#[allow(missing_docs)]
#[inline]
pub fn update_cursor_position_from_backend(&mut self, cursor_position: Option<Vec2>) {
self.cursor_position = cursor_position;
}
#[inline] #[inline]
pub fn mode(&self) -> WindowMode { pub fn mode(&self) -> WindowMode {
self.mode self.mode

View File

@ -14,8 +14,8 @@ use bevy_ecs::{Resources, World};
use bevy_math::Vec2; use bevy_math::Vec2;
use bevy_utils::tracing::{error, trace}; use bevy_utils::tracing::{error, trace};
use bevy_window::{ use bevy_window::{
CreateWindow, CursorMoved, ReceivedCharacter, Window, WindowCloseRequested, WindowCreated, CreateWindow, CursorEntered, CursorLeft, CursorMoved, ReceivedCharacter, Window,
WindowResized, Windows, WindowCloseRequested, WindowCreated, WindowResized, Windows,
}; };
use winit::{ use winit::{
event::{self, DeviceEvent, Event, WindowEvent}, event::{self, DeviceEvent, Event, WindowEvent},
@ -224,17 +224,43 @@ pub fn winit_runner(mut app: App) {
let mut cursor_moved_events = let mut cursor_moved_events =
app.resources.get_mut::<Events<CursorMoved>>().unwrap(); app.resources.get_mut::<Events<CursorMoved>>().unwrap();
let winit_windows = app.resources.get_mut::<WinitWindows>().unwrap(); let winit_windows = app.resources.get_mut::<WinitWindows>().unwrap();
let mut windows = app.resources.get_mut::<Windows>().unwrap();
let window_id = winit_windows.get_window_id(winit_window_id).unwrap(); let window_id = winit_windows.get_window_id(winit_window_id).unwrap();
let window = winit_windows.get_window(window_id).unwrap(); let winit_window = winit_windows.get_window(window_id).unwrap();
let position = position.to_logical(window.scale_factor()); let window = windows.get_mut(window_id).unwrap();
let inner_size = window.inner_size().to_logical::<f32>(window.scale_factor()); let position = position.to_logical(winit_window.scale_factor());
let inner_size = winit_window
.inner_size()
.to_logical::<f32>(winit_window.scale_factor());
// move origin to bottom left // move origin to bottom left
let y_position = inner_size.height - position.y; let y_position = inner_size.height - position.y;
let position = Vec2::new(position.x, y_position);
window.update_cursor_position_from_backend(Some(position));
cursor_moved_events.send(CursorMoved { cursor_moved_events.send(CursorMoved {
id: window_id, id: window_id,
position: Vec2::new(position.x, y_position), position,
}); });
} }
WindowEvent::CursorEntered { .. } => {
let mut cursor_entered_events =
app.resources.get_mut::<Events<CursorEntered>>().unwrap();
let winit_windows = app.resources.get_mut::<WinitWindows>().unwrap();
let window_id = winit_windows.get_window_id(winit_window_id).unwrap();
cursor_entered_events.send(CursorEntered { id: window_id });
}
WindowEvent::CursorLeft { .. } => {
let mut cursor_left_events =
app.resources.get_mut::<Events<CursorLeft>>().unwrap();
let winit_windows = app.resources.get_mut::<WinitWindows>().unwrap();
let mut windows = app.resources.get_mut::<Windows>().unwrap();
let window_id = winit_windows.get_window_id(winit_window_id).unwrap();
let window = windows.get_mut(window_id).unwrap();
window.update_cursor_position_from_backend(None);
cursor_left_events.send(CursorLeft { id: window_id });
}
WindowEvent::MouseInput { state, button, .. } => { WindowEvent::MouseInput { state, button, .. } => {
let mut mouse_button_input_events = let mut mouse_button_input_events =
app.resources.get_mut::<Events<MouseButtonInput>>().unwrap(); app.resources.get_mut::<Events<MouseButtonInput>>().unwrap();