mirage-engine 0.1.1

Mirage, an immediate-mode 3D engine for simple games on desktop and the browser
Documentation
//! What the pointer is drawn as, and what the window and the UI each name
//! it.

/// What the pointer is drawn as, which
/// [`FrameContext::set_cursor`](crate::FrameContext::set_cursor) takes.
///
/// Required if you want the pointer to show what it is over: the hand over
/// what the player can press, the closed hand while they hold it.
/// [`Cursor::Held`] draws no pointer and holds it in place.
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub enum Cursor {
    /// The arrow, which a frame that sets no cursor draws.
    #[default]
    Arrow,
    /// The hand, over what the player can press.
    Pointer,
    /// The open hand, over what the player can take hold of.
    Grab,
    /// The closed hand, over what the player has taken hold of.
    Grabbing,
    /// The crosshair, over a position the player chooses exactly.
    Crosshair,
    /// The upright line, over text the player selects.
    Text,
    /// The four arrows, over what the player moves.
    Move,
    /// The circle with a line across it, over what the player cannot use.
    NotAllowed,
    /// The clock, while the game does work the player waits on.
    Wait,
    /// No pointer at all: it is hidden and held in place, and a frame
    /// reads how far it moved rather than where it is.
    Held,
}

impl Cursor {
    /// Whether this cursor holds the pointer in place, so that only its
    /// movement reaches the game.
    pub(crate) fn holds_pointer(self) -> bool {
        matches!(self, Self::Held)
    }

    /// This cursor as the window names it, or `None` where the window
    /// draws no pointer at all.
    #[cfg(not(feature = "ui"))]
    pub(crate) fn window_icon(self) -> Option<winit::window::CursorIcon> {
        Some(match self {
            Self::Arrow => winit::window::CursorIcon::Default,
            Self::Pointer => winit::window::CursorIcon::Pointer,
            Self::Grab => winit::window::CursorIcon::Grab,
            Self::Grabbing => winit::window::CursorIcon::Grabbing,
            Self::Crosshair => winit::window::CursorIcon::Crosshair,
            Self::Text => winit::window::CursorIcon::Text,
            Self::Move => winit::window::CursorIcon::Move,
            Self::NotAllowed => winit::window::CursorIcon::NotAllowed,
            Self::Wait => winit::window::CursorIcon::Wait,
            Self::Held => return None,
        })
    }

    /// This cursor as the UI names it; a held pointer is the UI's own
    /// `None`, which it draws nothing for.
    #[cfg(feature = "ui")]
    pub(crate) fn ui_icon(self) -> egui::CursorIcon {
        match self {
            Self::Arrow => egui::CursorIcon::Default,
            Self::Pointer => egui::CursorIcon::PointingHand,
            Self::Grab => egui::CursorIcon::Grab,
            Self::Grabbing => egui::CursorIcon::Grabbing,
            Self::Crosshair => egui::CursorIcon::Crosshair,
            Self::Text => egui::CursorIcon::Text,
            Self::Move => egui::CursorIcon::Move,
            Self::NotAllowed => egui::CursorIcon::NotAllowed,
            Self::Wait => egui::CursorIcon::Wait,
            Self::Held => egui::CursorIcon::None,
        }
    }

    /// The cursor nearest `icon`, or `None` where the UI set no cursor of
    /// its own.
    ///
    /// The UI's own `None` hides the pointer rather than holding it in
    /// place, so it is nearest [`Cursor::Arrow`] and a window hiding the
    /// pointer reads back as the arrow.
    #[cfg(feature = "ui")]
    pub(crate) fn of_ui(icon: egui::CursorIcon) -> Option<Self> {
        use egui::CursorIcon as Ui;

        match icon {
            Ui::Default => None,
            Ui::PointingHand => Some(Self::Pointer),
            Ui::Grab => Some(Self::Grab),
            Ui::Grabbing => Some(Self::Grabbing),
            Ui::Cell | Ui::Crosshair => Some(Self::Crosshair),
            Ui::Text | Ui::VerticalText => Some(Self::Text),
            Ui::NoDrop | Ui::NotAllowed => Some(Self::NotAllowed),
            Ui::Progress | Ui::Wait => Some(Self::Wait),
            Ui::AllScroll
            | Ui::Move
            | Ui::ResizeColumn
            | Ui::ResizeEast
            | Ui::ResizeHorizontal
            | Ui::ResizeNeSw
            | Ui::ResizeNorth
            | Ui::ResizeNorthEast
            | Ui::ResizeNorthWest
            | Ui::ResizeNwSe
            | Ui::ResizeRow
            | Ui::ResizeSouth
            | Ui::ResizeSouthEast
            | Ui::ResizeSouthWest
            | Ui::ResizeVertical
            | Ui::ResizeWest => Some(Self::Move),
            Ui::Alias
            | Ui::ContextMenu
            | Ui::Copy
            | Ui::Help
            | Ui::None
            | Ui::ZoomIn
            | Ui::ZoomOut => Some(Self::Arrow),
        }
    }
}