Skip to main content

bevy_window/cursor/
custom_cursor.rs

1use crate::cursor::CursorIcon;
2use alloc::string::String;
3use bevy_asset::Handle;
4use bevy_ecs::template::FromTemplate;
5use bevy_image::{Image, TextureAtlas};
6use bevy_math::URect;
7
8#[cfg(feature = "bevy_reflect")]
9use bevy_reflect::{std_traits::ReflectDefault, Reflect};
10
11/// A custom cursor created from an image.
12#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, FromTemplate)]
13#[cfg_attr(
14    feature = "bevy_reflect",
15    derive(Reflect),
16    reflect(Debug, Default, Hash, PartialEq, Clone)
17)]
18pub struct CustomCursorImage {
19    /// Handle to the image to use as the cursor. The image must be in 8 bit int
20    /// or 32 bit float rgba. PNG images work well for this.
21    pub handle: Handle<Image>,
22    /// An optional texture atlas used to render the image.
23    #[template(built_in)]
24    pub texture_atlas: Option<TextureAtlas>,
25    /// Whether the image should be flipped along its x-axis.
26    ///
27    /// If true, the cursor's `hotspot` automatically flips along with the
28    /// image.
29    pub flip_x: bool,
30    /// Whether the image should be flipped along its y-axis.
31    ///
32    /// If true, the cursor's `hotspot` automatically flips along with the
33    /// image.
34    pub flip_y: bool,
35    /// An optional rectangle representing the region of the image to render,
36    /// instead of rendering the full image. This is an easy one-off alternative
37    /// to using a [`TextureAtlas`].
38    ///
39    /// When used with a [`TextureAtlas`], the rect is offset by the atlas's
40    /// minimal (top-left) corner position.
41    pub rect: Option<URect>,
42    /// X and Y coordinates of the hotspot in pixels. The hotspot must be within
43    /// the image bounds.
44    ///
45    /// If you are flipping the image using `flip_x` or `flip_y`, you don't need
46    /// to adjust this field to account for the flip because it is adjusted
47    /// automatically.
48    pub hotspot: (u16, u16),
49}
50
51/// A custom cursor created from a URL. Note that this currently only works on the web.
52#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)]
53#[cfg_attr(
54    feature = "bevy_reflect",
55    derive(Reflect),
56    reflect(Debug, Default, Hash, PartialEq, Clone)
57)]
58pub struct CustomCursorUrl {
59    /// Web URL to an image to use as the cursor. PNGs are preferred. Cursor
60    /// creation can fail if the image is invalid or not reachable.
61    pub url: String,
62    /// X and Y coordinates of the hotspot in pixels. The hotspot must be within
63    /// the image bounds.
64    pub hotspot: (u16, u16),
65}
66
67/// Custom cursor image data.
68#[derive(Debug, Clone, PartialEq, Eq, Hash, FromTemplate)]
69#[cfg_attr(
70    feature = "bevy_reflect",
71    derive(Reflect),
72    reflect(Clone, PartialEq, Hash)
73)]
74pub enum CustomCursor {
75    #[default]
76    /// Use an image as the cursor.
77    Image(CustomCursorImage),
78    /// Use a URL to an image as the cursor. Note that this currently only works on the web.
79    Url(CustomCursorUrl),
80}
81
82impl From<CustomCursor> for CursorIcon {
83    fn from(cursor: CustomCursor) -> Self {
84        CursorIcon::Custom(cursor)
85    }
86}