mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
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
6 changed files with 132 additions and 2 deletions
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 raw_window_handle;
|
||||
mod system;
|
||||
|
@ -5,6 +6,7 @@ mod window;
|
|||
mod windows;
|
||||
|
||||
pub use crate::raw_window_handle::*;
|
||||
pub use cursor::*;
|
||||
pub use event::*;
|
||||
pub use system::*;
|
||||
pub use window::*;
|
||||
|
@ -13,8 +15,8 @@ pub use windows::*;
|
|||
pub mod prelude {
|
||||
#[doc(hidden)]
|
||||
pub use crate::{
|
||||
CursorEntered, CursorLeft, CursorMoved, FileDragAndDrop, ReceivedCharacter, Window,
|
||||
WindowDescriptor, WindowMoved, Windows,
|
||||
CursorEntered, CursorIcon, CursorLeft, CursorMoved, FileDragAndDrop, ReceivedCharacter,
|
||||
Window, WindowDescriptor, WindowMoved, Windows,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ impl WindowId {
|
|||
}
|
||||
}
|
||||
|
||||
use crate::CursorIcon;
|
||||
use std::fmt;
|
||||
|
||||
use crate::raw_window_handle::RawWindowHandleWrapper;
|
||||
|
@ -123,6 +124,7 @@ pub struct Window {
|
|||
vsync: bool,
|
||||
resizable: bool,
|
||||
decorations: bool,
|
||||
cursor_icon: CursorIcon,
|
||||
cursor_visible: bool,
|
||||
cursor_locked: bool,
|
||||
physical_cursor_position: Option<DVec2>,
|
||||
|
@ -162,6 +164,9 @@ pub enum WindowCommand {
|
|||
SetCursorLockMode {
|
||||
locked: bool,
|
||||
},
|
||||
SetCursorIcon {
|
||||
icon: CursorIcon,
|
||||
},
|
||||
SetCursorVisibility {
|
||||
visible: bool,
|
||||
},
|
||||
|
@ -222,6 +227,7 @@ impl Window {
|
|||
decorations: window_descriptor.decorations,
|
||||
cursor_visible: window_descriptor.cursor_visible,
|
||||
cursor_locked: window_descriptor.cursor_locked,
|
||||
cursor_icon: CursorIcon::Default,
|
||||
physical_cursor_position: None,
|
||||
raw_window_handle: RawWindowHandleWrapper::new(raw_window_handle),
|
||||
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.
|
||||
#[inline]
|
||||
pub fn physical_cursor_position(&self) -> Option<DVec2> {
|
||||
|
|
|
@ -5,6 +5,7 @@ use bevy_input::{
|
|||
ElementState,
|
||||
};
|
||||
use bevy_math::Vec2;
|
||||
use bevy_window::CursorIcon;
|
||||
|
||||
pub fn convert_keyboard_input(keyboard_input: &winit::event::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,
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
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 } => {
|
||||
let window = winit_windows.get_window(id).unwrap();
|
||||
window
|
||||
|
|
|
@ -13,6 +13,7 @@ fn main() {
|
|||
.add_plugins(DefaultPlugins)
|
||||
.add_system(change_title)
|
||||
.add_system(toggle_cursor)
|
||||
.add_system(cycle_cursor_icon)
|
||||
.run();
|
||||
}
|
||||
|
||||
|
@ -33,3 +34,30 @@ fn toggle_cursor(input: Res<Input<KeyCode>>, mut windows: ResMut<Windows>) {
|
|||
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 a new issue