summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2023-06-08 20:35:40 +0200
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2023-06-08 20:35:40 +0200
commitaba98e49654852281ed17bedd1becac6f9db8700 (patch)
tree661d5d42cfa968e43bb0751836de3d68cb95c59c
parent57db196c3a169fe1ecd654e9b58ce66defa5dd7e (diff)
downloadiced-aba98e49654852281ed17bedd1becac6f9db8700.tar.gz
iced-aba98e49654852281ed17bedd1becac6f9db8700.tar.bz2
iced-aba98e49654852281ed17bedd1becac6f9db8700.zip
Extend cursor availability to the shell level
-rw-r--r--core/src/mouse/cursor.rs3
-rw-r--r--examples/integration/src/main.rs5
-rw-r--r--runtime/src/program/state.rs10
-rw-r--r--runtime/src/user_interface.rs67
-rw-r--r--winit/src/application.rs8
-rw-r--r--winit/src/application/state.rs29
6 files changed, 73 insertions, 49 deletions
diff --git a/core/src/mouse/cursor.rs b/core/src/mouse/cursor.rs
index 223ed96d..203526e9 100644
--- a/core/src/mouse/cursor.rs
+++ b/core/src/mouse/cursor.rs
@@ -1,12 +1,13 @@
use crate::{Point, Rectangle, Vector};
/// The mouse cursor state.
-#[derive(Debug, Clone, Copy, PartialEq)]
+#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub enum Cursor {
/// The cursor has a defined position.
Available(Point),
/// The cursor is currently unavailable (i.e. out of bounds or busy).
+ #[default]
Unavailable,
}
diff --git a/examples/integration/src/main.rs b/examples/integration/src/main.rs
index c935aca7..daecfeb2 100644
--- a/examples/integration/src/main.rs
+++ b/examples/integration/src/main.rs
@@ -6,6 +6,7 @@ use scene::Scene;
use iced_wgpu::graphics::Viewport;
use iced_wgpu::{wgpu, Backend, Renderer, Settings};
+use iced_winit::core::mouse;
use iced_winit::core::renderer;
use iced_winit::core::{Color, Size};
use iced_winit::runtime::program;
@@ -194,10 +195,10 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
// We update iced
let _ = state.update(
viewport.logical_size(),
- conversion::cursor_position(
+ mouse::Cursor::Available(conversion::cursor_position(
cursor_position,
viewport.scale_factor(),
- ),
+ )),
&mut renderer,
&Theme::Dark,
&renderer::Style { text_color: Color::WHITE },
diff --git a/runtime/src/program/state.rs b/runtime/src/program/state.rs
index 2fa9934d..d83e3f54 100644
--- a/runtime/src/program/state.rs
+++ b/runtime/src/program/state.rs
@@ -1,7 +1,7 @@
use crate::core::event::{self, Event};
use crate::core::mouse;
use crate::core::renderer;
-use crate::core::{Clipboard, Point, Size};
+use crate::core::{Clipboard, Size};
use crate::user_interface::{self, UserInterface};
use crate::{Command, Debug, Program};
@@ -88,7 +88,7 @@ where
pub fn update(
&mut self,
bounds: Size,
- cursor_position: Point,
+ cursor: mouse::Cursor,
renderer: &mut P::Renderer,
theme: &<P::Renderer as iced_core::Renderer>::Theme,
style: &renderer::Style,
@@ -108,7 +108,7 @@ where
let (_, event_statuses) = user_interface.update(
&self.queued_events,
- cursor_position,
+ cursor,
renderer,
clipboard,
&mut messages,
@@ -131,7 +131,7 @@ where
let command = if messages.is_empty() {
debug.draw_started();
self.mouse_interaction =
- user_interface.draw(renderer, theme, style, cursor_position);
+ user_interface.draw(renderer, theme, style, cursor);
debug.draw_finished();
self.cache = Some(user_interface.into_cache());
@@ -163,7 +163,7 @@ where
debug.draw_started();
self.mouse_interaction =
- user_interface.draw(renderer, theme, style, cursor_position);
+ user_interface.draw(renderer, theme, style, cursor);
debug.draw_finished();
self.cache = Some(user_interface.into_cache());
diff --git a/runtime/src/user_interface.rs b/runtime/src/user_interface.rs
index 7dee13bc..68ff6158 100644
--- a/runtime/src/user_interface.rs
+++ b/runtime/src/user_interface.rs
@@ -5,7 +5,7 @@ use crate::core::mouse;
use crate::core::renderer;
use crate::core::widget;
use crate::core::window;
-use crate::core::{Clipboard, Point, Rectangle, Size, Vector};
+use crate::core::{Clipboard, Rectangle, Size, Vector};
use crate::core::{Element, Layout, Shell};
/// A set of interactive graphical elements with a specific [`Layout`].
@@ -128,7 +128,9 @@ where
/// # pub fn view(&self) -> iced_core::Element<(), Renderer> { unimplemented!() }
/// # pub fn update(&mut self, _: ()) {}
/// # }
- /// use iced_runtime::core::{clipboard, Size, Point};
+ /// use iced_runtime::core::clipboard;
+ /// use iced_runtime::core::mouse;
+ /// use iced_runtime::core::Size;
/// use iced_runtime::user_interface::{self, UserInterface};
/// use iced_wgpu::Renderer;
///
@@ -136,7 +138,7 @@ where
/// let mut cache = user_interface::Cache::new();
/// let mut renderer = Renderer::new();
/// let mut window_size = Size::new(1024.0, 768.0);
- /// let mut cursor_position = Point::default();
+ /// let mut cursor = mouse::Cursor::default();
/// let mut clipboard = clipboard::Null;
///
/// // Initialize our event storage
@@ -156,7 +158,7 @@ where
/// // Update the user interface
/// let (state, event_statuses) = user_interface.update(
/// &events,
- /// cursor_position,
+ /// cursor,
/// &mut renderer,
/// &mut clipboard,
/// &mut messages
@@ -173,7 +175,7 @@ where
pub fn update(
&mut self,
events: &[Event],
- cursor_position: Point,
+ cursor: mouse::Cursor,
renderer: &mut Renderer,
clipboard: &mut dyn Clipboard,
messages: &mut Vec<Message>,
@@ -203,7 +205,7 @@ where
let event_status = overlay.on_event(
event,
Layout::new(&layout),
- mouse::Cursor::Available(cursor_position),
+ cursor,
renderer,
clipboard,
&mut shell,
@@ -255,19 +257,22 @@ where
let base_cursor = manual_overlay
.as_ref()
.filter(|overlay| {
- overlay.is_over(Layout::new(&layout), cursor_position)
+ cursor
+ .position()
+ .map(|cursor_position| {
+ overlay
+ .is_over(Layout::new(&layout), cursor_position)
+ })
+ .unwrap_or_default()
})
.map(|_| mouse::Cursor::Unavailable)
- .unwrap_or(mouse::Cursor::Available(cursor_position));
+ .unwrap_or(cursor);
self.overlay = Some(layout);
(base_cursor, event_statuses)
} else {
- (
- mouse::Cursor::Available(cursor_position),
- vec![event::Status::Ignored; events.len()],
- )
+ (cursor, vec![event::Status::Ignored; events.len()])
};
let _ = ManuallyDrop::into_inner(manual_overlay);
@@ -359,8 +364,9 @@ where
/// # pub fn update(&mut self, _: ()) {}
/// # }
/// use iced_runtime::core::clipboard;
+ /// use iced_runtime::core::mouse;
/// use iced_runtime::core::renderer;
- /// use iced_runtime::core::{Element, Size, Point};
+ /// use iced_runtime::core::{Element, Size};
/// use iced_runtime::user_interface::{self, UserInterface};
/// use iced_wgpu::{Renderer, Theme};
///
@@ -368,7 +374,7 @@ where
/// let mut cache = user_interface::Cache::new();
/// let mut renderer = Renderer::new();
/// let mut window_size = Size::new(1024.0, 768.0);
- /// let mut cursor_position = Point::default();
+ /// let mut cursor = mouse::Cursor::default();
/// let mut clipboard = clipboard::Null;
/// let mut events = Vec::new();
/// let mut messages = Vec::new();
@@ -387,14 +393,14 @@ where
/// // Update the user interface
/// let event_statuses = user_interface.update(
/// &events,
- /// cursor_position,
+ /// cursor,
/// &mut renderer,
/// &mut clipboard,
/// &mut messages
/// );
///
/// // Draw the user interface
- /// let mouse_cursor = user_interface.draw(&mut renderer, &theme, &renderer::Style::default(), cursor_position);
+ /// let mouse_interaction = user_interface.draw(&mut renderer, &theme, &renderer::Style::default(), cursor);
///
/// cache = user_interface.into_cache();
///
@@ -411,7 +417,7 @@ where
renderer: &mut Renderer,
theme: &Renderer::Theme,
style: &renderer::Style,
- cursor_position: Point,
+ cursor: mouse::Cursor,
) -> mouse::Interaction {
// TODO: Move to shell level (?)
renderer.clear();
@@ -427,19 +433,24 @@ where
overlay.layout(renderer, self.bounds, Vector::ZERO)
});
- let cursor = if overlay
- .is_over(Layout::new(&overlay_layout), cursor_position)
+ let cursor = if cursor
+ .position()
+ .map(|cursor_position| {
+ overlay
+ .is_over(Layout::new(&overlay_layout), cursor_position)
+ })
+ .unwrap_or_default()
{
mouse::Cursor::Unavailable
} else {
- mouse::Cursor::Available(cursor_position)
+ cursor
};
self.overlay = Some(overlay_layout);
cursor
} else {
- mouse::Cursor::Available(cursor_position)
+ cursor
};
self.root.as_widget().draw(
@@ -480,7 +491,7 @@ where
.map(|overlay| {
let overlay_interaction = overlay.mouse_interaction(
Layout::new(layout),
- mouse::Cursor::Available(cursor_position),
+ cursor,
&viewport,
renderer,
);
@@ -493,11 +504,19 @@ where
theme,
style,
Layout::new(layout),
- mouse::Cursor::Available(cursor_position),
+ cursor,
);
});
- if overlay.is_over(Layout::new(layout), cursor_position)
+ if cursor
+ .position()
+ .map(|cursor_position| {
+ overlay.is_over(
+ Layout::new(layout),
+ cursor_position,
+ )
+ })
+ .unwrap_or_default()
{
overlay_interaction
} else {
diff --git a/winit/src/application.rs b/winit/src/application.rs
index 4147be17..be416ac8 100644
--- a/winit/src/application.rs
+++ b/winit/src/application.rs
@@ -356,7 +356,7 @@ async fn run_instance<A, E, C>(
let (interface_state, statuses) = user_interface.update(
&events,
- state.cursor_position(),
+ state.cursor(),
&mut renderer,
&mut clipboard,
&mut messages,
@@ -422,7 +422,7 @@ async fn run_instance<A, E, C>(
let (interface_state, _) = user_interface.update(
&[redraw_event.clone()],
- state.cursor_position(),
+ state.cursor(),
&mut renderer,
&mut clipboard,
&mut messages,
@@ -435,7 +435,7 @@ async fn run_instance<A, E, C>(
&renderer::Style {
text_color: state.text_color(),
},
- state.cursor_position(),
+ state.cursor(),
);
debug.draw_finished();
@@ -508,7 +508,7 @@ async fn run_instance<A, E, C>(
&renderer::Style {
text_color: state.text_color(),
},
- state.cursor_position(),
+ state.cursor(),
);
if new_mouse_interaction != mouse_interaction {
diff --git a/winit/src/application/state.rs b/winit/src/application/state.rs
index c37ccca6..967f43f2 100644
--- a/winit/src/application/state.rs
+++ b/winit/src/application/state.rs
@@ -1,7 +1,8 @@
use crate::application::{self, StyleSheet as _};
use crate::conversion;
use crate::core;
-use crate::core::{Color, Point, Size};
+use crate::core::mouse;
+use crate::core::{Color, Size};
use crate::graphics::Viewport;
use crate::runtime::Debug;
use crate::Application;
@@ -20,7 +21,7 @@ where
scale_factor: f64,
viewport: Viewport,
viewport_version: usize,
- cursor_position: winit::dpi::PhysicalPosition<f64>,
+ cursor_position: Option<winit::dpi::PhysicalPosition<f64>>,
modifiers: winit::event::ModifiersState,
theme: <A::Renderer as core::Renderer>::Theme,
appearance: application::Appearance,
@@ -52,8 +53,7 @@ where
scale_factor,
viewport,
viewport_version: 0,
- // TODO: Encode cursor availability in the type-system
- cursor_position: winit::dpi::PhysicalPosition::new(-1.0, -1.0),
+ cursor_position: None,
modifiers: winit::event::ModifiersState::default(),
theme,
appearance,
@@ -89,11 +89,16 @@ where
}
/// Returns the current cursor position of the [`State`].
- pub fn cursor_position(&self) -> Point {
- conversion::cursor_position(
- self.cursor_position,
- self.viewport.scale_factor(),
- )
+ pub fn cursor(&self) -> mouse::Cursor {
+ self.cursor_position
+ .map(|cursor_position| {
+ conversion::cursor_position(
+ cursor_position,
+ self.viewport.scale_factor(),
+ )
+ })
+ .map(mouse::Cursor::Available)
+ .unwrap_or(mouse::Cursor::Unavailable)
}
/// Returns the current keyboard modifiers of the [`State`].
@@ -153,12 +158,10 @@ where
| WindowEvent::Touch(Touch {
location: position, ..
}) => {
- self.cursor_position = *position;
+ self.cursor_position = Some(*position);
}
WindowEvent::CursorLeft { .. } => {
- // TODO: Encode cursor availability in the type-system
- self.cursor_position =
- winit::dpi::PhysicalPosition::new(-1.0, -1.0);
+ self.cursor_position = None;
}
WindowEvent::ModifiersChanged(new_modifiers) => {
self.modifiers = *new_modifiers;