-
-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cursor icon support through Game trait #112
Changes from 3 commits
42aa6a3
9a2fbed
b60a31f
13429f2
66828da
21ce46f
6b7cced
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
use crate::graphics::window::winit; | ||
|
||
/// TODO | ||
#[derive(Debug, Clone, Copy, PartialEq)] | ||
pub enum CursorIcon { | ||
/// The platform-dependent default cursor. | ||
Default, | ||
/// A simple crosshair. | ||
Crosshair, | ||
/// A hand (often used to indicate links in web browsers). | ||
Hand, | ||
/// Hides the cursor. | ||
Hidden, | ||
/// Indicates something is to be moved. | ||
Move, | ||
} | ||
|
||
impl Default for CursorIcon { | ||
fn default() -> Self { | ||
Self::Default | ||
} | ||
} | ||
|
||
impl From<CursorIcon> for winit::window::CursorIcon { | ||
fn from(cursor_icon: CursorIcon) -> winit::window::CursorIcon { | ||
match cursor_icon { | ||
// If the cursor is hidden, it doesn't matter which type it is, so the default makes | ||
// the most sense. | ||
CursorIcon::Default | CursorIcon::Hidden => { | ||
winit::window::CursorIcon::Default | ||
} | ||
CursorIcon::Crosshair => winit::window::CursorIcon::Crosshair, | ||
CursorIcon::Hand => winit::window::CursorIcon::Hand, | ||
CursorIcon::Move => winit::window::CursorIcon::Move, | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -174,7 +174,7 @@ pub type Panel<'a, Message> = widget::Panel<'a, Message, Renderer>; | |
pub type Element<'a, Message> = self::core::Element<'a, Message, Renderer>; | ||
|
||
use crate::game::{self, Loop as _}; | ||
use crate::graphics::{Point, Window, WindowSettings}; | ||
use crate::graphics::{CursorIcon, Point, Window, WindowSettings}; | ||
use crate::input::{self, mouse, Input as _}; | ||
use crate::load::Task; | ||
use crate::ui::core::{Event, Interface, MouseCursor, Renderer as _}; | ||
|
@@ -277,7 +277,8 @@ pub trait UserInterface: Game { | |
struct Loop<UI: UserInterface> { | ||
renderer: UI::Renderer, | ||
messages: Vec<UI::Message>, | ||
mouse_cursor: MouseCursor, | ||
game_cursor: CursorIcon, | ||
ui_cursor: MouseCursor, | ||
cache: Option<core::Cache>, | ||
cursor_position: Point, | ||
events: Vec<Event>, | ||
|
@@ -291,7 +292,8 @@ impl<UI: UserInterface> game::Loop<UI> for Loop<UI> { | |
Loop { | ||
renderer, | ||
messages: Vec::new(), | ||
mouse_cursor: MouseCursor::OutOfBounds, | ||
game_cursor: CursorIcon::Default, | ||
ui_cursor: MouseCursor::OutOfBounds, | ||
cache: Some(cache), | ||
cursor_position: Point::new(0.0, 0.0), | ||
events: Vec::new(), | ||
|
@@ -338,23 +340,36 @@ impl<UI: UserInterface> game::Loop<UI> for Loop<UI> { | |
interface.on_event(event, cursor_position, messages) | ||
}); | ||
|
||
let new_cursor = interface.draw( | ||
let new_ui_cursor = interface.draw( | ||
&mut self.renderer, | ||
&mut window.frame(), | ||
cursor_position, | ||
); | ||
|
||
self.cache = Some(interface.cache()); | ||
|
||
if new_cursor != self.mouse_cursor { | ||
if new_cursor == MouseCursor::OutOfBounds { | ||
if new_ui_cursor != self.ui_cursor { | ||
if new_ui_cursor == MouseCursor::OutOfBounds { | ||
input.update(input::Event::Mouse(mouse::Event::CursorReturned)); | ||
} else if self.mouse_cursor == MouseCursor::OutOfBounds { | ||
} else if self.ui_cursor == MouseCursor::OutOfBounds { | ||
input.update(input::Event::Mouse(mouse::Event::CursorTaken)); | ||
} | ||
|
||
window.update_cursor(new_cursor.into()); | ||
self.mouse_cursor = new_cursor; | ||
self.ui_cursor = new_ui_cursor; | ||
} | ||
let new_game_cursor = ui.cursor_icon(); | ||
if new_game_cursor != self.game_cursor { | ||
self.game_cursor = new_game_cursor; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We may be able to move this inside the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in 13429f2. |
||
|
||
// TODO: Only update the cursor if it has changed once `MouseCursor` & `CursorIcon` merges | ||
// Use the game cursor if cursor is not on a UI element, use the mouse cursor otherwise | ||
if self.ui_cursor == MouseCursor::OutOfBounds { | ||
window.set_cursor_visible(self.game_cursor != CursorIcon::Hidden); | ||
window.update_cursor(self.game_cursor.into()); | ||
} else { | ||
window.set_cursor_visible(true); | ||
window.update_cursor(self.ui_cursor.into()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To avoid cursor flickering, it may be a good idea to save the last cursor and visibility in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in 13429f2. |
||
} | ||
|
||
for message in messages.drain(..) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then, we can make this take an
Option<winit::Window::CursorIcon>
and removeset_cursor_visible
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in 66828da.