Skip to content

Commit d004bce

Browse files
authored
Added basic mouse capture API (#679)
Added basic cursor lock API
1 parent 7ba4584 commit d004bce

File tree

5 files changed

+59
-0
lines changed

5 files changed

+59
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,3 +293,4 @@ required-features = ["bevy_winit"]
293293
name = "assets_wasm"
294294
path = "examples/wasm/assets_wasm.rs"
295295
required-features = ["bevy_winit"]
296+

crates/bevy_window/src/window.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ pub struct Window {
4040
vsync: bool,
4141
resizable: bool,
4242
decorations: bool,
43+
cursor_visible: bool,
44+
cursor_locked: bool,
4345
mode: WindowMode,
4446
#[cfg(target_arch = "wasm32")]
4547
pub canvas: Option<String>,
@@ -68,6 +70,12 @@ pub enum WindowCommand {
6870
SetDecorations {
6971
decorations: bool,
7072
},
73+
SetCursorLockMode {
74+
locked: bool,
75+
},
76+
SetCursorVisibility {
77+
visible: bool,
78+
},
7179
}
7280

7381
/// Defines the way a window is displayed
@@ -92,6 +100,8 @@ impl Window {
92100
vsync: window_descriptor.vsync,
93101
resizable: window_descriptor.resizable,
94102
decorations: window_descriptor.decorations,
103+
cursor_visible: window_descriptor.cursor_visible,
104+
cursor_locked: window_descriptor.cursor_locked,
95105
mode: window_descriptor.mode,
96106
#[cfg(target_arch = "wasm32")]
97107
canvas: window_descriptor.canvas.clone(),
@@ -165,6 +175,27 @@ impl Window {
165175
.push(WindowCommand::SetDecorations { decorations });
166176
}
167177

178+
pub fn cursor_locked(&self) -> bool {
179+
self.cursor_locked
180+
}
181+
182+
pub fn set_cursor_lock_mode(&mut self, lock_mode: bool) {
183+
self.cursor_locked = lock_mode;
184+
self.command_queue
185+
.push(WindowCommand::SetCursorLockMode { locked: lock_mode });
186+
}
187+
188+
pub fn cursor_visible(&self) -> bool {
189+
self.cursor_visible
190+
}
191+
192+
pub fn set_cursor_visibility(&mut self, visibile_mode: bool) {
193+
self.cursor_visible = visibile_mode;
194+
self.command_queue.push(WindowCommand::SetCursorVisibility {
195+
visible: visibile_mode,
196+
});
197+
}
198+
168199
pub fn mode(&self) -> WindowMode {
169200
self.mode
170201
}
@@ -191,6 +222,8 @@ pub struct WindowDescriptor {
191222
pub vsync: bool,
192223
pub resizable: bool,
193224
pub decorations: bool,
225+
pub cursor_visible: bool,
226+
pub cursor_locked: bool,
194227
pub mode: WindowMode,
195228
#[cfg(target_arch = "wasm32")]
196229
pub canvas: Option<String>,
@@ -210,6 +243,8 @@ impl Default for WindowDescriptor {
210243
vsync: true,
211244
resizable: true,
212245
decorations: true,
246+
cursor_locked: false,
247+
cursor_visible: true,
213248
mode: WindowMode::Windowed,
214249
#[cfg(target_arch = "wasm32")]
215250
canvas: None,

crates/bevy_winit/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,14 @@ fn change_window(_: &mut World, resources: &mut Resources) {
8484
let window = winit_windows.get_window(id).unwrap();
8585
window.set_decorations(decorations);
8686
}
87+
bevy_window::WindowCommand::SetCursorLockMode { locked } => {
88+
let window = winit_windows.get_window(id).unwrap();
89+
window.set_cursor_grab(locked).unwrap();
90+
}
91+
bevy_window::WindowCommand::SetCursorVisibility { visible } => {
92+
let window = winit_windows.get_window(id).unwrap();
93+
window.set_cursor_visible(visible);
94+
}
8795
}
8896
}
8997
}

crates/bevy_winit/src/winit_windows.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ impl WinitWindows {
7171

7272
let winit_window = winit_window_builder.build(&event_loop).unwrap();
7373

74+
winit_window
75+
.set_cursor_grab(window.cursor_locked())
76+
.unwrap();
77+
winit_window.set_cursor_visible(window.cursor_visible());
78+
7479
self.window_id_to_winit
7580
.insert(window.id(), winit_window.id());
7681
self.winit_to_window_id

examples/window/window_settings.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ fn main() {
1313
})
1414
.add_default_plugins()
1515
.add_system(change_title.system())
16+
.add_system(toggle_cursor.system())
1617
.run();
1718
}
1819

@@ -24,3 +25,12 @@ fn change_title(time: Res<Time>, mut windows: ResMut<Windows>) {
2425
time.seconds_since_startup.round()
2526
));
2627
}
28+
29+
/// This system toggles the cursor's visibility when the space bar is pressed
30+
fn toggle_cursor(input: Res<Input<KeyCode>>, mut windows: ResMut<Windows>) {
31+
let window = windows.get_primary_mut().unwrap();
32+
if input.just_pressed(KeyCode::Space) {
33+
window.set_cursor_lock_mode(!window.cursor_locked());
34+
window.set_cursor_visibility(!window.cursor_visible());
35+
}
36+
}

0 commit comments

Comments
 (0)