Extend cursor availability to the shell level
This commit is contained in:
parent
57db196c3a
commit
aba98e4965
6 changed files with 73 additions and 49 deletions
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 },
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue