move custom mouse cursor functionality to separate struct
this is to not have the main Mouse struct be tied to our indexed-colour Bitmap graphics implementation (i'm not currently ready to try to generify this either ...)
This commit is contained in:
parent
888b5057e4
commit
28d1b7230e
197
ggdt/src/system/input_devices/mouse/cursor.rs
Normal file
197
ggdt/src/system/input_devices/mouse/cursor.rs
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
use crate::graphics::*;
|
||||||
|
use crate::math::*;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const DEFAULT_MOUSE_CURSOR_HOTSPOT_X: u32 = 0;
|
||||||
|
const DEFAULT_MOUSE_CURSOR_HOTSPOT_Y: u32 = 0;
|
||||||
|
const DEFAULT_MOUSE_CURSOR_WIDTH: usize = 16;
|
||||||
|
const DEFAULT_MOUSE_CURSOR_HEIGHT: usize = 16;
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
const DEFAULT_MOUSE_CURSOR: [u8; DEFAULT_MOUSE_CURSOR_WIDTH * DEFAULT_MOUSE_CURSOR_HEIGHT] = [
|
||||||
|
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x0f, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
||||||
|
];
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct CustomMouseCursor {
|
||||||
|
last_x: i32,
|
||||||
|
last_y: i32,
|
||||||
|
cursor: Bitmap,
|
||||||
|
cursor_background: Bitmap,
|
||||||
|
cursor_hotspot_x: u32,
|
||||||
|
cursor_hotspot_y: u32,
|
||||||
|
cursor_enabled: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CustomMouseCursor {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
let (cursor, cursor_background, cursor_hotspot_x, cursor_hotspot_y) = Self::get_default_mouse_cursor();
|
||||||
|
|
||||||
|
CustomMouseCursor {
|
||||||
|
last_x: 0,
|
||||||
|
last_y: 0,
|
||||||
|
cursor,
|
||||||
|
cursor_background,
|
||||||
|
cursor_hotspot_x,
|
||||||
|
cursor_hotspot_y,
|
||||||
|
cursor_enabled: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a reference to the current mouse cursor bitmap.
|
||||||
|
#[inline]
|
||||||
|
pub fn cursor_bitmap(&self) -> &Bitmap {
|
||||||
|
&self.cursor
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the current mouse cursor's "hotspot" x coordinate.
|
||||||
|
#[inline]
|
||||||
|
pub fn cursor_hotspot_x(&self) -> u32 {
|
||||||
|
self.cursor_hotspot_x
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the current mouse cursor's "hotspot" y coordinate.
|
||||||
|
#[inline]
|
||||||
|
pub fn cursor_hotspot_y(&self) -> u32 {
|
||||||
|
self.cursor_hotspot_y
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if mouse cursor bitmap rendering is enabled.
|
||||||
|
#[inline]
|
||||||
|
pub fn is_cursor_enabled(&self) -> bool {
|
||||||
|
self.cursor_enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Enables or disables mouse cursor bitmap rendering.
|
||||||
|
#[inline]
|
||||||
|
pub fn enable_cursor(&mut self, enable: bool) {
|
||||||
|
self.cursor_enabled = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the [`Bitmap`] used to display the mouse cursor and the "hotspot" coordinate. The
|
||||||
|
/// bitmap provided here should be set up to use color 255 as the transparent color.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `cursor`: the bitmap to be used to display the mouse cursor on screen
|
||||||
|
/// * `hotspot_x`: the "hotspot" x coordinate
|
||||||
|
/// * `hotspot_y`: the "hotspot" y coordinate.
|
||||||
|
pub fn set_mouse_cursor(&mut self, cursor: Bitmap, hotspot_x: u32, hotspot_y: u32) {
|
||||||
|
self.cursor = cursor;
|
||||||
|
self.cursor_background = Bitmap::new(self.cursor.width(), self.cursor.height()).unwrap();
|
||||||
|
self.cursor_hotspot_x = hotspot_x;
|
||||||
|
self.cursor_hotspot_y = hotspot_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Resets the mouse cursor bitmap and "hotspot" coordinate back to the default settings.
|
||||||
|
pub fn set_default_mouse_cursor(&mut self) {
|
||||||
|
let (cursor, background, hotspot_x, hotspot_y) = Self::get_default_mouse_cursor();
|
||||||
|
self.cursor = cursor;
|
||||||
|
self.cursor_background = background;
|
||||||
|
self.cursor_hotspot_x = hotspot_x;
|
||||||
|
self.cursor_hotspot_y = hotspot_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn get_cursor_render_position(&self) -> (i32, i32) {
|
||||||
|
(
|
||||||
|
self.last_x - self.cursor_hotspot_x as i32,
|
||||||
|
self.last_y - self.cursor_hotspot_y as i32,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Renders the mouse cursor bitmap onto the destination bitmap at the mouse's current
|
||||||
|
/// position. The destination bitmap specified is usually the [`SystemResources`]'s video
|
||||||
|
/// backbuffer bitmap. The background on the destination bitmap is saved internally and a
|
||||||
|
/// subsequent call to [`Self::hide`] will restore the background.
|
||||||
|
///
|
||||||
|
/// If mouse cursor rendering is not currently enabled, this method does nothing.
|
||||||
|
///
|
||||||
|
/// Applications will not normally need to call this method, as if mouse cursor rendering is
|
||||||
|
/// enabled, this will be automatically handled by [`SystemResources::display`].
|
||||||
|
///
|
||||||
|
/// [`SystemResources`]: crate::system::SystemResources
|
||||||
|
/// [`SystemResources::display`]: crate::system::SystemResources::display
|
||||||
|
pub fn render(&mut self, dest: &mut Bitmap) {
|
||||||
|
if !self.cursor_enabled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let (x, y) = self.get_cursor_render_position();
|
||||||
|
|
||||||
|
// preserve existing background first
|
||||||
|
self.cursor_background.blit_region(
|
||||||
|
BlitMethod::Solid,
|
||||||
|
&dest,
|
||||||
|
&Rect::new(x, y, self.cursor.width(), self.cursor.height()),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
|
dest.blit(BlitMethod::Transparent(255), &self.cursor, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Restores the original destination bitmap contents where the mouse cursor bitmap was
|
||||||
|
/// rendered to during the previous call to [`Self::render`]. The destination bitmap
|
||||||
|
/// specified is usually the [`SystemResources`]'s video backbuffer bitmap.
|
||||||
|
///
|
||||||
|
/// If mouse cursor rendering is not currently enabled, this method does nothing.
|
||||||
|
///
|
||||||
|
/// Applications will not normally need to call this method, as if mouse cursor rendering is
|
||||||
|
/// enabled, this will be automatically handled by [`SystemResources::display`].
|
||||||
|
///
|
||||||
|
/// [`SystemResources`]: crate::system::SystemResources
|
||||||
|
/// [`SystemResources::display`]: crate::system::SystemResources::display
|
||||||
|
pub fn hide(&mut self, dest: &mut Bitmap) {
|
||||||
|
if !self.cursor_enabled {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let (x, y) = self.get_cursor_render_position();
|
||||||
|
dest.blit(BlitMethod::Solid, &self.cursor_background, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Updates current state from the given [`Mouse`] device's state, ensuring that subsequent calls to render
|
||||||
|
/// a custom mouse cursor reflect the current mouse state. Application's should not normally need to call
|
||||||
|
/// this directly as it will be called by [`SystemResources::update`].
|
||||||
|
///
|
||||||
|
/// [`SystemResources::update`]: crate::system::SystemResources::update
|
||||||
|
pub fn update(&mut self, mouse: &Mouse) {
|
||||||
|
self.last_x = mouse.x;
|
||||||
|
self.last_y = mouse.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_default_mouse_cursor() -> (Bitmap, Bitmap, u32, u32) {
|
||||||
|
let mut cursor = Bitmap::new(
|
||||||
|
DEFAULT_MOUSE_CURSOR_WIDTH as u32,
|
||||||
|
DEFAULT_MOUSE_CURSOR_HEIGHT as u32,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
cursor.pixels_mut().copy_from_slice(&DEFAULT_MOUSE_CURSOR);
|
||||||
|
|
||||||
|
let cursor_background = Bitmap::new(cursor.width(), cursor.height()).unwrap();
|
||||||
|
|
||||||
|
(
|
||||||
|
cursor,
|
||||||
|
cursor_background,
|
||||||
|
DEFAULT_MOUSE_CURSOR_HOTSPOT_X,
|
||||||
|
DEFAULT_MOUSE_CURSOR_HOTSPOT_Y,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,36 +5,13 @@ use crate::system::MouseEvent;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub use self::buttons::*;
|
pub use self::buttons::*;
|
||||||
|
pub use self::cursor::*;
|
||||||
|
|
||||||
pub mod buttons;
|
pub mod buttons;
|
||||||
|
pub mod cursor;
|
||||||
|
|
||||||
const MAX_BUTTONS: usize = 32;
|
const MAX_BUTTONS: usize = 32;
|
||||||
|
|
||||||
const DEFAULT_MOUSE_CURSOR_HOTSPOT_X: u32 = 0;
|
|
||||||
const DEFAULT_MOUSE_CURSOR_HOTSPOT_Y: u32 = 0;
|
|
||||||
const DEFAULT_MOUSE_CURSOR_WIDTH: usize = 16;
|
|
||||||
const DEFAULT_MOUSE_CURSOR_HEIGHT: usize = 16;
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
const DEFAULT_MOUSE_CURSOR: [u8; DEFAULT_MOUSE_CURSOR_WIDTH * DEFAULT_MOUSE_CURSOR_HEIGHT] = [
|
|
||||||
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x00, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x00, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x00, 0x0f, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x00, 0x0f, 0x0f, 0x00, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
|
||||||
];
|
|
||||||
|
|
||||||
/// Holds the current state of the mouse.
|
/// Holds the current state of the mouse.
|
||||||
///
|
///
|
||||||
/// Must be explicitly updated each frame by calling `handle_event` each frame for all SDL2 events
|
/// Must be explicitly updated each frame by calling `handle_event` each frame for all SDL2 events
|
||||||
|
@ -49,29 +26,16 @@ pub struct Mouse {
|
||||||
x_delta: i32,
|
x_delta: i32,
|
||||||
y_delta: i32,
|
y_delta: i32,
|
||||||
buttons: [ButtonState; MAX_BUTTONS],
|
buttons: [ButtonState; MAX_BUTTONS],
|
||||||
cursor: Bitmap,
|
|
||||||
cursor_background: Bitmap,
|
|
||||||
cursor_hotspot_x: u32,
|
|
||||||
cursor_hotspot_y: u32,
|
|
||||||
cursor_enabled: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mouse {
|
impl Mouse {
|
||||||
pub fn new() -> Mouse {
|
pub fn new() -> Mouse {
|
||||||
let (cursor, cursor_background, cursor_hotspot_x, cursor_hotspot_y) =
|
|
||||||
Self::get_default_mouse_cursor();
|
|
||||||
|
|
||||||
Mouse {
|
Mouse {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
x_delta: 0,
|
x_delta: 0,
|
||||||
y_delta: 0,
|
y_delta: 0,
|
||||||
buttons: [ButtonState::Idle; MAX_BUTTONS],
|
buttons: [ButtonState::Idle; MAX_BUTTONS],
|
||||||
cursor,
|
|
||||||
cursor_background,
|
|
||||||
cursor_hotspot_x,
|
|
||||||
cursor_hotspot_y,
|
|
||||||
cursor_enabled: false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,137 +95,6 @@ impl Mouse {
|
||||||
self.buttons[button] == ButtonState::Released
|
self.buttons[button] == ButtonState::Released
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference to the current mouse cursor bitmap.
|
|
||||||
#[inline]
|
|
||||||
pub fn cursor_bitmap(&self) -> &Bitmap {
|
|
||||||
&self.cursor
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the current mouse cursor's "hotspot" x coordinate.
|
|
||||||
#[inline]
|
|
||||||
pub fn cursor_hotspot_x(&self) -> u32 {
|
|
||||||
self.cursor_hotspot_x
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the current mouse cursor's "hotspot" y coordinate.
|
|
||||||
#[inline]
|
|
||||||
pub fn cursor_hotspot_y(&self) -> u32 {
|
|
||||||
self.cursor_hotspot_y
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if mouse cursor bitmap rendering is enabled.
|
|
||||||
#[inline]
|
|
||||||
pub fn is_cursor_enabled(&self) -> bool {
|
|
||||||
self.cursor_enabled
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Enables or disables mouse cursor bitmap rendering.
|
|
||||||
#[inline]
|
|
||||||
pub fn enable_cursor(&mut self, enable: bool) {
|
|
||||||
self.cursor_enabled = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the [`Bitmap`] used to display the mouse cursor and the "hotspot" coordinate. The
|
|
||||||
/// bitmap provided here should be set up to use color 255 as the transparent color.
|
|
||||||
///
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `cursor`: the bitmap to be used to display the mouse cursor on screen
|
|
||||||
/// * `hotspot_x`: the "hotspot" x coordinate
|
|
||||||
/// * `hotspot_y`: the "hotspot" y coordinate.
|
|
||||||
pub fn set_mouse_cursor(&mut self, cursor: Bitmap, hotspot_x: u32, hotspot_y: u32) {
|
|
||||||
self.cursor = cursor;
|
|
||||||
self.cursor_background = Bitmap::new(self.cursor.width(), self.cursor.height()).unwrap();
|
|
||||||
self.cursor_hotspot_x = hotspot_x;
|
|
||||||
self.cursor_hotspot_y = hotspot_y;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Resets the mouse cursor bitmap and "hotspot" coordinate back to the default settings.
|
|
||||||
pub fn set_default_mouse_cursor(&mut self) {
|
|
||||||
let (cursor, background, hotspot_x, hotspot_y) = Self::get_default_mouse_cursor();
|
|
||||||
self.cursor = cursor;
|
|
||||||
self.cursor_background = background;
|
|
||||||
self.cursor_hotspot_x = hotspot_x;
|
|
||||||
self.cursor_hotspot_y = hotspot_y;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_default_mouse_cursor() -> (Bitmap, Bitmap, u32, u32) {
|
|
||||||
let mut cursor = Bitmap::new(
|
|
||||||
DEFAULT_MOUSE_CURSOR_WIDTH as u32,
|
|
||||||
DEFAULT_MOUSE_CURSOR_HEIGHT as u32,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
cursor.pixels_mut().copy_from_slice(&DEFAULT_MOUSE_CURSOR);
|
|
||||||
|
|
||||||
let cursor_background = Bitmap::new(cursor.width(), cursor.height()).unwrap();
|
|
||||||
|
|
||||||
(
|
|
||||||
cursor,
|
|
||||||
cursor_background,
|
|
||||||
DEFAULT_MOUSE_CURSOR_HOTSPOT_X,
|
|
||||||
DEFAULT_MOUSE_CURSOR_HOTSPOT_Y,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn get_cursor_render_position(&self) -> (i32, i32) {
|
|
||||||
(
|
|
||||||
self.x - self.cursor_hotspot_x as i32,
|
|
||||||
self.y - self.cursor_hotspot_y as i32,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Renders the mouse cursor bitmap onto the destination bitmap at the mouse's current
|
|
||||||
/// position. The destination bitmap specified is assumed to be the [`System`]'s video
|
|
||||||
/// backbuffer bitmap. The background on the destination bitmap is saved internally and a
|
|
||||||
/// subsequent call to [`Mouse::hide_cursor`] will restore the background.
|
|
||||||
///
|
|
||||||
/// If mouse cursor rendering is not currently enabled, this method does nothing.
|
|
||||||
///
|
|
||||||
/// Applications will not normally need to call this method, as if mouse cursor rendering is
|
|
||||||
/// enabled, this will be automatically handled by [`System::display`].
|
|
||||||
///
|
|
||||||
/// [`System`]: crate::System
|
|
||||||
/// [`System::display`]: crate::System::display
|
|
||||||
pub fn render_cursor(&mut self, dest: &mut Bitmap) {
|
|
||||||
if !self.cursor_enabled {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let (x, y) = self.get_cursor_render_position();
|
|
||||||
|
|
||||||
// preserve existing background first
|
|
||||||
self.cursor_background.blit_region(
|
|
||||||
BlitMethod::Solid,
|
|
||||||
&dest,
|
|
||||||
&Rect::new(x, y, self.cursor.width(), self.cursor.height()),
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
|
|
||||||
dest.blit(BlitMethod::Transparent(255), &self.cursor, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Restores the original destination bitmap contents where the mouse cursor bitmap was
|
|
||||||
/// rendered to during the previous call to [`Mouse::render_cursor`]. The destination bitmap
|
|
||||||
/// specified is assumed to be the [`System`]'s video backbuffer bitmap.
|
|
||||||
///
|
|
||||||
/// If mouse cursor rendering is not currently enabled, this method does nothing.
|
|
||||||
///
|
|
||||||
/// Applications will not normally need to call this method, as if mouse cursor rendering is
|
|
||||||
/// enabled, this will be automatically handled by [`System::display`].
|
|
||||||
///
|
|
||||||
/// [`System`]: crate::System
|
|
||||||
/// [`System::display`]: crate::System::display
|
|
||||||
pub fn hide_cursor(&mut self, dest: &mut Bitmap) {
|
|
||||||
if !self.cursor_enabled {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let (x, y) = self.get_cursor_render_position();
|
|
||||||
dest.blit(BlitMethod::Solid, &self.cursor_background, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_button_state(&mut self, button: u32, is_pressed: bool) {
|
fn update_button_state(&mut self, button: u32, is_pressed: bool) {
|
||||||
let button_state = &mut self.buttons[button as usize];
|
let button_state = &mut self.buttons[button as usize];
|
||||||
*button_state = if is_pressed {
|
*button_state = if is_pressed {
|
||||||
|
|
|
@ -165,6 +165,7 @@ impl SystemResourcesConfig for DosLikeConfig {
|
||||||
|
|
||||||
let keyboard = Keyboard::new();
|
let keyboard = Keyboard::new();
|
||||||
let mouse = Mouse::new();
|
let mouse = Mouse::new();
|
||||||
|
let cursor = CustomMouseCursor::new();
|
||||||
|
|
||||||
Ok(DosLike {
|
Ok(DosLike {
|
||||||
sdl_canvas,
|
sdl_canvas,
|
||||||
|
@ -178,6 +179,7 @@ impl SystemResourcesConfig for DosLikeConfig {
|
||||||
font,
|
font,
|
||||||
keyboard,
|
keyboard,
|
||||||
mouse,
|
mouse,
|
||||||
|
cursor,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,6 +220,10 @@ pub struct DosLike {
|
||||||
/// The current mouse state. To ensure it is updated each frame, you should call
|
/// The current mouse state. To ensure it is updated each frame, you should call
|
||||||
/// [`System::do_events`] or [`System::do_events_with`] each frame.
|
/// [`System::do_events`] or [`System::do_events_with`] each frame.
|
||||||
pub mouse: Mouse,
|
pub mouse: Mouse,
|
||||||
|
|
||||||
|
/// Manages custom mouse cursor graphics and state. Use this to set/unset a custom mouse cursor bitmap.
|
||||||
|
/// When set, rendering should occur automatically during calls to [`SystemResources::display`].
|
||||||
|
pub cursor: CustomMouseCursor,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for DosLike {
|
impl std::fmt::Debug for DosLike {
|
||||||
|
@ -236,6 +242,8 @@ impl std::fmt::Debug for DosLike {
|
||||||
|
|
||||||
impl SystemResources for DosLike {
|
impl SystemResources for DosLike {
|
||||||
fn update(&mut self) -> Result<(), SystemResourcesError> {
|
fn update(&mut self) -> Result<(), SystemResourcesError> {
|
||||||
|
self.cursor.update(&self.mouse);
|
||||||
|
|
||||||
match self.audio_queue.apply(&mut self.audio) {
|
match self.audio_queue.apply(&mut self.audio) {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(error) => Err(SystemResourcesError::AudioDeviceError(error))
|
Err(error) => Err(SystemResourcesError::AudioDeviceError(error))
|
||||||
|
@ -245,7 +253,7 @@ impl SystemResources for DosLike {
|
||||||
/// Takes the `video` backbuffer bitmap and `palette` and renders it to the window, up-scaled
|
/// Takes the `video` backbuffer bitmap and `palette` and renders it to the window, up-scaled
|
||||||
/// to fill the window (preserving aspect ratio of course).
|
/// to fill the window (preserving aspect ratio of course).
|
||||||
fn display(&mut self) -> Result<(), SystemResourcesError> {
|
fn display(&mut self) -> Result<(), SystemResourcesError> {
|
||||||
self.mouse.render_cursor(&mut self.video);
|
self.cursor.render(&mut self.video);
|
||||||
|
|
||||||
// convert application framebuffer to 32-bit RGBA pixels, and then upload it to the SDL
|
// convert application framebuffer to 32-bit RGBA pixels, and then upload it to the SDL
|
||||||
// texture so it will be displayed on screen
|
// texture so it will be displayed on screen
|
||||||
|
@ -262,7 +270,7 @@ impl SystemResources for DosLike {
|
||||||
}
|
}
|
||||||
self.sdl_canvas.present();
|
self.sdl_canvas.present();
|
||||||
|
|
||||||
self.mouse.hide_cursor(&mut self.video);
|
self.cursor.hide(&mut self.video);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue