Skip to main content

pebble/wgpu/
cursor.rs

1//! Mirrors `winit::window::CursorIcon` and `winit::window::CursorGrabMode`
2//! exactly, so [`Window`](super::window::Window)'s cursor methods never need
3//! a raw `winit` type. Convert into winit via `.into()`.
4
5/// The shape of the mouse cursor — mirrors `winit::window::CursorIcon`
6/// exactly (same variants, same names).
7#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
8pub enum CursorIcon {
9    #[default]
10    Default,
11    ContextMenu,
12    Help,
13    Pointer,
14    Progress,
15    Wait,
16    Cell,
17    Crosshair,
18    Text,
19    VerticalText,
20    Alias,
21    Copy,
22    Move,
23    NoDrop,
24    NotAllowed,
25    Grab,
26    Grabbing,
27    EResize,
28    NResize,
29    NeResize,
30    NwResize,
31    SResize,
32    SeResize,
33    SwResize,
34    WResize,
35    EwResize,
36    NsResize,
37    NeswResize,
38    NwseResize,
39    ColResize,
40    RowResize,
41    AllScroll,
42    ZoomIn,
43    ZoomOut,
44    DndAsk,
45    AllResize,
46}
47
48impl From<CursorIcon> for winit::window::CursorIcon {
49    fn from(value: CursorIcon) -> Self {
50        match value {
51            CursorIcon::Default => Self::Default,
52            CursorIcon::ContextMenu => Self::ContextMenu,
53            CursorIcon::Help => Self::Help,
54            CursorIcon::Pointer => Self::Pointer,
55            CursorIcon::Progress => Self::Progress,
56            CursorIcon::Wait => Self::Wait,
57            CursorIcon::Cell => Self::Cell,
58            CursorIcon::Crosshair => Self::Crosshair,
59            CursorIcon::Text => Self::Text,
60            CursorIcon::VerticalText => Self::VerticalText,
61            CursorIcon::Alias => Self::Alias,
62            CursorIcon::Copy => Self::Copy,
63            CursorIcon::Move => Self::Move,
64            CursorIcon::NoDrop => Self::NoDrop,
65            CursorIcon::NotAllowed => Self::NotAllowed,
66            CursorIcon::Grab => Self::Grab,
67            CursorIcon::Grabbing => Self::Grabbing,
68            CursorIcon::EResize => Self::EResize,
69            CursorIcon::NResize => Self::NResize,
70            CursorIcon::NeResize => Self::NeResize,
71            CursorIcon::NwResize => Self::NwResize,
72            CursorIcon::SResize => Self::SResize,
73            CursorIcon::SeResize => Self::SeResize,
74            CursorIcon::SwResize => Self::SwResize,
75            CursorIcon::WResize => Self::WResize,
76            CursorIcon::EwResize => Self::EwResize,
77            CursorIcon::NsResize => Self::NsResize,
78            CursorIcon::NeswResize => Self::NeswResize,
79            CursorIcon::NwseResize => Self::NwseResize,
80            CursorIcon::ColResize => Self::ColResize,
81            CursorIcon::RowResize => Self::RowResize,
82            CursorIcon::AllScroll => Self::AllScroll,
83            CursorIcon::ZoomIn => Self::ZoomIn,
84            CursorIcon::ZoomOut => Self::ZoomOut,
85            CursorIcon::DndAsk => Self::DndAsk,
86            CursorIcon::AllResize => Self::AllResize,
87        }
88    }
89}
90
91/// How the cursor is confined while the window has focus — mirrors
92/// `winit::window::CursorGrabMode` exactly.
93#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
94pub enum CursorGrabMode {
95    /// No grabbing — the cursor can leave the window freely. The default.
96    #[default]
97    None,
98    /// Confined to the window area, but still free to move within it.
99    /// Not guaranteed to also hide the cursor — pair with
100    /// `Window::set_cursor_visible(false)` if that's the goal.
101    Confined,
102    /// Locked in place at its current position. Not implemented on every
103    /// platform (X11/Windows) — see `Window::set_cursor_grab`'s return value.
104    Locked,
105}
106
107impl From<CursorGrabMode> for winit::window::CursorGrabMode {
108    fn from(value: CursorGrabMode) -> Self {
109        match value {
110            CursorGrabMode::None => Self::None,
111            CursorGrabMode::Confined => Self::Confined,
112            CursorGrabMode::Locked => Self::Locked,
113        }
114    }
115}
116
117#[cfg(test)]
118mod tests {
119    use super::*;
120
121    #[test]
122    fn cursor_icon_conversion_is_positional_not_coincidental() {
123        assert_eq!(winit::window::CursorIcon::from(CursorIcon::Default), winit::window::CursorIcon::Default);
124        assert_eq!(winit::window::CursorIcon::from(CursorIcon::Pointer), winit::window::CursorIcon::Pointer);
125        assert_eq!(winit::window::CursorIcon::from(CursorIcon::NwseResize), winit::window::CursorIcon::NwseResize);
126        assert_eq!(winit::window::CursorIcon::from(CursorIcon::AllResize), winit::window::CursorIcon::AllResize);
127    }
128
129    #[test]
130    fn cursor_grab_mode_conversion_round_trips() {
131        assert_eq!(winit::window::CursorGrabMode::from(CursorGrabMode::None), winit::window::CursorGrabMode::None);
132        assert_eq!(winit::window::CursorGrabMode::from(CursorGrabMode::Confined), winit::window::CursorGrabMode::Confined);
133        assert_eq!(winit::window::CursorGrabMode::from(CursorGrabMode::Locked), winit::window::CursorGrabMode::Locked);
134    }
135}