Added set_cursor_icon(...) to Window (#3395)
# Objective The window's cursor should be settable without having to implement a custom cursor icon solution. This will especially be helpful when creating user-interfaces that might like to use the cursor to denote some meaning (e.g., _clickable_, _resizable_, etc.). ## Solution Added a `CursorIcon` enum that maps one-to-one to winit's `CursorIcon` enum, as well as a method to set/get it for the given `Window`.
This commit is contained in:
parent
3443cc77cb
commit
5479047aa2
39
crates/bevy_window/src/cursor.rs
Normal file
39
crates/bevy_window/src/cursor.rs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/// The icon to display for a window's cursor
|
||||||
|
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
|
||||||
|
pub enum CursorIcon {
|
||||||
|
Default,
|
||||||
|
Crosshair,
|
||||||
|
Hand,
|
||||||
|
Arrow,
|
||||||
|
Move,
|
||||||
|
Text,
|
||||||
|
Wait,
|
||||||
|
Help,
|
||||||
|
Progress,
|
||||||
|
NotAllowed,
|
||||||
|
ContextMenu,
|
||||||
|
Cell,
|
||||||
|
VerticalText,
|
||||||
|
Alias,
|
||||||
|
Copy,
|
||||||
|
NoDrop,
|
||||||
|
Grab,
|
||||||
|
Grabbing,
|
||||||
|
AllScroll,
|
||||||
|
ZoomIn,
|
||||||
|
ZoomOut,
|
||||||
|
EResize,
|
||||||
|
NResize,
|
||||||
|
NeResize,
|
||||||
|
NwResize,
|
||||||
|
SResize,
|
||||||
|
SeResize,
|
||||||
|
SwResize,
|
||||||
|
WResize,
|
||||||
|
EwResize,
|
||||||
|
NsResize,
|
||||||
|
NeswResize,
|
||||||
|
NwseResize,
|
||||||
|
ColResize,
|
||||||
|
RowResize,
|
||||||
|
}
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
mod cursor;
|
||||||
mod event;
|
mod event;
|
||||||
mod raw_window_handle;
|
mod raw_window_handle;
|
||||||
mod system;
|
mod system;
|
||||||
@ -5,6 +6,7 @@ mod window;
|
|||||||
mod windows;
|
mod windows;
|
||||||
|
|
||||||
pub use crate::raw_window_handle::*;
|
pub use crate::raw_window_handle::*;
|
||||||
|
pub use cursor::*;
|
||||||
pub use event::*;
|
pub use event::*;
|
||||||
pub use system::*;
|
pub use system::*;
|
||||||
pub use window::*;
|
pub use window::*;
|
||||||
@ -13,8 +15,8 @@ pub use windows::*;
|
|||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
CursorEntered, CursorLeft, CursorMoved, FileDragAndDrop, ReceivedCharacter, Window,
|
CursorEntered, CursorIcon, CursorLeft, CursorMoved, FileDragAndDrop, ReceivedCharacter,
|
||||||
WindowDescriptor, WindowMoved, Windows,
|
Window, WindowDescriptor, WindowMoved, Windows,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,7 @@ impl WindowId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use crate::CursorIcon;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use crate::raw_window_handle::RawWindowHandleWrapper;
|
use crate::raw_window_handle::RawWindowHandleWrapper;
|
||||||
@ -123,6 +124,7 @@ pub struct Window {
|
|||||||
vsync: bool,
|
vsync: bool,
|
||||||
resizable: bool,
|
resizable: bool,
|
||||||
decorations: bool,
|
decorations: bool,
|
||||||
|
cursor_icon: CursorIcon,
|
||||||
cursor_visible: bool,
|
cursor_visible: bool,
|
||||||
cursor_locked: bool,
|
cursor_locked: bool,
|
||||||
physical_cursor_position: Option<DVec2>,
|
physical_cursor_position: Option<DVec2>,
|
||||||
@ -162,6 +164,9 @@ pub enum WindowCommand {
|
|||||||
SetCursorLockMode {
|
SetCursorLockMode {
|
||||||
locked: bool,
|
locked: bool,
|
||||||
},
|
},
|
||||||
|
SetCursorIcon {
|
||||||
|
icon: CursorIcon,
|
||||||
|
},
|
||||||
SetCursorVisibility {
|
SetCursorVisibility {
|
||||||
visible: bool,
|
visible: bool,
|
||||||
},
|
},
|
||||||
@ -222,6 +227,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_icon: CursorIcon::Default,
|
||||||
physical_cursor_position: None,
|
physical_cursor_position: None,
|
||||||
raw_window_handle: RawWindowHandleWrapper::new(raw_window_handle),
|
raw_window_handle: RawWindowHandleWrapper::new(raw_window_handle),
|
||||||
focused: true,
|
focused: true,
|
||||||
@ -474,6 +480,16 @@ impl Window {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn cursor_icon(&self) -> CursorIcon {
|
||||||
|
self.cursor_icon
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_cursor_icon(&mut self, icon: CursorIcon) {
|
||||||
|
self.command_queue
|
||||||
|
.push(WindowCommand::SetCursorIcon { icon });
|
||||||
|
}
|
||||||
|
|
||||||
/// The current mouse position, in physical pixels.
|
/// The current mouse position, in physical pixels.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn physical_cursor_position(&self) -> Option<DVec2> {
|
pub fn physical_cursor_position(&self) -> Option<DVec2> {
|
||||||
|
|||||||
@ -5,6 +5,7 @@ use bevy_input::{
|
|||||||
ElementState,
|
ElementState,
|
||||||
};
|
};
|
||||||
use bevy_math::Vec2;
|
use bevy_math::Vec2;
|
||||||
|
use bevy_window::CursorIcon;
|
||||||
|
|
||||||
pub fn convert_keyboard_input(keyboard_input: &winit::event::KeyboardInput) -> KeyboardInput {
|
pub fn convert_keyboard_input(keyboard_input: &winit::event::KeyboardInput) -> KeyboardInput {
|
||||||
KeyboardInput {
|
KeyboardInput {
|
||||||
@ -225,3 +226,43 @@ pub fn convert_virtual_key_code(virtual_key_code: winit::event::VirtualKeyCode)
|
|||||||
winit::event::VirtualKeyCode::Cut => KeyCode::Cut,
|
winit::event::VirtualKeyCode::Cut => KeyCode::Cut,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn convert_cursor_icon(cursor_icon: CursorIcon) -> winit::window::CursorIcon {
|
||||||
|
match cursor_icon {
|
||||||
|
CursorIcon::Default => winit::window::CursorIcon::Default,
|
||||||
|
CursorIcon::Crosshair => winit::window::CursorIcon::Crosshair,
|
||||||
|
CursorIcon::Hand => winit::window::CursorIcon::Hand,
|
||||||
|
CursorIcon::Arrow => winit::window::CursorIcon::Arrow,
|
||||||
|
CursorIcon::Move => winit::window::CursorIcon::Move,
|
||||||
|
CursorIcon::Text => winit::window::CursorIcon::Text,
|
||||||
|
CursorIcon::Wait => winit::window::CursorIcon::Wait,
|
||||||
|
CursorIcon::Help => winit::window::CursorIcon::Help,
|
||||||
|
CursorIcon::Progress => winit::window::CursorIcon::Progress,
|
||||||
|
CursorIcon::NotAllowed => winit::window::CursorIcon::NotAllowed,
|
||||||
|
CursorIcon::ContextMenu => winit::window::CursorIcon::ContextMenu,
|
||||||
|
CursorIcon::Cell => winit::window::CursorIcon::Cell,
|
||||||
|
CursorIcon::VerticalText => winit::window::CursorIcon::VerticalText,
|
||||||
|
CursorIcon::Alias => winit::window::CursorIcon::Alias,
|
||||||
|
CursorIcon::Copy => winit::window::CursorIcon::Copy,
|
||||||
|
CursorIcon::NoDrop => winit::window::CursorIcon::NoDrop,
|
||||||
|
CursorIcon::Grab => winit::window::CursorIcon::Grab,
|
||||||
|
CursorIcon::Grabbing => winit::window::CursorIcon::Grabbing,
|
||||||
|
CursorIcon::AllScroll => winit::window::CursorIcon::AllScroll,
|
||||||
|
CursorIcon::ZoomIn => winit::window::CursorIcon::ZoomIn,
|
||||||
|
CursorIcon::ZoomOut => winit::window::CursorIcon::ZoomOut,
|
||||||
|
CursorIcon::EResize => winit::window::CursorIcon::EResize,
|
||||||
|
CursorIcon::NResize => winit::window::CursorIcon::NResize,
|
||||||
|
CursorIcon::NeResize => winit::window::CursorIcon::NeResize,
|
||||||
|
CursorIcon::NwResize => winit::window::CursorIcon::NwResize,
|
||||||
|
CursorIcon::SResize => winit::window::CursorIcon::SResize,
|
||||||
|
CursorIcon::SeResize => winit::window::CursorIcon::SeResize,
|
||||||
|
CursorIcon::SwResize => winit::window::CursorIcon::SwResize,
|
||||||
|
CursorIcon::WResize => winit::window::CursorIcon::WResize,
|
||||||
|
CursorIcon::EwResize => winit::window::CursorIcon::EwResize,
|
||||||
|
CursorIcon::NsResize => winit::window::CursorIcon::NsResize,
|
||||||
|
CursorIcon::NeswResize => winit::window::CursorIcon::NeswResize,
|
||||||
|
CursorIcon::NwseResize => winit::window::CursorIcon::NwseResize,
|
||||||
|
CursorIcon::ColResize => winit::window::CursorIcon::ColResize,
|
||||||
|
CursorIcon::RowResize => winit::window::CursorIcon::RowResize,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -103,6 +103,10 @@ fn change_window(world: &mut World) {
|
|||||||
let window = winit_windows.get_window(id).unwrap();
|
let window = winit_windows.get_window(id).unwrap();
|
||||||
window.set_decorations(decorations);
|
window.set_decorations(decorations);
|
||||||
}
|
}
|
||||||
|
bevy_window::WindowCommand::SetCursorIcon { icon } => {
|
||||||
|
let window = winit_windows.get_window(id).unwrap();
|
||||||
|
window.set_cursor_icon(converters::convert_cursor_icon(icon));
|
||||||
|
}
|
||||||
bevy_window::WindowCommand::SetCursorLockMode { locked } => {
|
bevy_window::WindowCommand::SetCursorLockMode { locked } => {
|
||||||
let window = winit_windows.get_window(id).unwrap();
|
let window = winit_windows.get_window(id).unwrap();
|
||||||
window
|
window
|
||||||
|
|||||||
@ -13,6 +13,7 @@ fn main() {
|
|||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_system(change_title)
|
.add_system(change_title)
|
||||||
.add_system(toggle_cursor)
|
.add_system(toggle_cursor)
|
||||||
|
.add_system(cycle_cursor_icon)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,3 +34,30 @@ fn toggle_cursor(input: Res<Input<KeyCode>>, mut windows: ResMut<Windows>) {
|
|||||||
window.set_cursor_visibility(!window.cursor_visible());
|
window.set_cursor_visibility(!window.cursor_visible());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This system cycles the cursor's icon through a small set of icons when clicking
|
||||||
|
fn cycle_cursor_icon(
|
||||||
|
input: Res<Input<MouseButton>>,
|
||||||
|
mut windows: ResMut<Windows>,
|
||||||
|
mut index: Local<usize>,
|
||||||
|
) {
|
||||||
|
const ICONS: &[CursorIcon] = &[
|
||||||
|
CursorIcon::Default,
|
||||||
|
CursorIcon::Hand,
|
||||||
|
CursorIcon::Wait,
|
||||||
|
CursorIcon::Text,
|
||||||
|
CursorIcon::Copy,
|
||||||
|
];
|
||||||
|
let window = windows.get_primary_mut().unwrap();
|
||||||
|
if input.just_pressed(MouseButton::Left) {
|
||||||
|
*index = (*index + 1) % ICONS.len();
|
||||||
|
window.set_cursor_icon(ICONS[*index]);
|
||||||
|
} else if input.just_pressed(MouseButton::Right) {
|
||||||
|
*index = if *index == 0 {
|
||||||
|
ICONS.len() - 1
|
||||||
|
} else {
|
||||||
|
*index - 1
|
||||||
|
};
|
||||||
|
window.set_cursor_icon(ICONS[*index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user