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};
|
use crate::{Point, Rectangle, Vector};
|
||||||
|
|
||||||
/// The mouse cursor state.
|
/// The mouse cursor state.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
||||||
pub enum Cursor {
|
pub enum Cursor {
|
||||||
/// The cursor has a defined position.
|
/// The cursor has a defined position.
|
||||||
Available(Point),
|
Available(Point),
|
||||||
|
|
||||||
/// The cursor is currently unavailable (i.e. out of bounds or busy).
|
/// The cursor is currently unavailable (i.e. out of bounds or busy).
|
||||||
|
#[default]
|
||||||
Unavailable,
|
Unavailable,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ use scene::Scene;
|
||||||
|
|
||||||
use iced_wgpu::graphics::Viewport;
|
use iced_wgpu::graphics::Viewport;
|
||||||
use iced_wgpu::{wgpu, Backend, Renderer, Settings};
|
use iced_wgpu::{wgpu, Backend, Renderer, Settings};
|
||||||
|
use iced_winit::core::mouse;
|
||||||
use iced_winit::core::renderer;
|
use iced_winit::core::renderer;
|
||||||
use iced_winit::core::{Color, Size};
|
use iced_winit::core::{Color, Size};
|
||||||
use iced_winit::runtime::program;
|
use iced_winit::runtime::program;
|
||||||
|
|
@ -194,10 +195,10 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
// We update iced
|
// We update iced
|
||||||
let _ = state.update(
|
let _ = state.update(
|
||||||
viewport.logical_size(),
|
viewport.logical_size(),
|
||||||
conversion::cursor_position(
|
mouse::Cursor::Available(conversion::cursor_position(
|
||||||
cursor_position,
|
cursor_position,
|
||||||
viewport.scale_factor(),
|
viewport.scale_factor(),
|
||||||
),
|
)),
|
||||||
&mut renderer,
|
&mut renderer,
|
||||||
&Theme::Dark,
|
&Theme::Dark,
|
||||||
&renderer::Style { text_color: Color::WHITE },
|
&renderer::Style { text_color: Color::WHITE },
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::core::event::{self, Event};
|
use crate::core::event::{self, Event};
|
||||||
use crate::core::mouse;
|
use crate::core::mouse;
|
||||||
use crate::core::renderer;
|
use crate::core::renderer;
|
||||||
use crate::core::{Clipboard, Point, Size};
|
use crate::core::{Clipboard, Size};
|
||||||
use crate::user_interface::{self, UserInterface};
|
use crate::user_interface::{self, UserInterface};
|
||||||
use crate::{Command, Debug, Program};
|
use crate::{Command, Debug, Program};
|
||||||
|
|
||||||
|
|
@ -88,7 +88,7 @@ where
|
||||||
pub fn update(
|
pub fn update(
|
||||||
&mut self,
|
&mut self,
|
||||||
bounds: Size,
|
bounds: Size,
|
||||||
cursor_position: Point,
|
cursor: mouse::Cursor,
|
||||||
renderer: &mut P::Renderer,
|
renderer: &mut P::Renderer,
|
||||||
theme: &<P::Renderer as iced_core::Renderer>::Theme,
|
theme: &<P::Renderer as iced_core::Renderer>::Theme,
|
||||||
style: &renderer::Style,
|
style: &renderer::Style,
|
||||||
|
|
@ -108,7 +108,7 @@ where
|
||||||
|
|
||||||
let (_, event_statuses) = user_interface.update(
|
let (_, event_statuses) = user_interface.update(
|
||||||
&self.queued_events,
|
&self.queued_events,
|
||||||
cursor_position,
|
cursor,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
&mut messages,
|
&mut messages,
|
||||||
|
|
@ -131,7 +131,7 @@ where
|
||||||
let command = if messages.is_empty() {
|
let command = if messages.is_empty() {
|
||||||
debug.draw_started();
|
debug.draw_started();
|
||||||
self.mouse_interaction =
|
self.mouse_interaction =
|
||||||
user_interface.draw(renderer, theme, style, cursor_position);
|
user_interface.draw(renderer, theme, style, cursor);
|
||||||
debug.draw_finished();
|
debug.draw_finished();
|
||||||
|
|
||||||
self.cache = Some(user_interface.into_cache());
|
self.cache = Some(user_interface.into_cache());
|
||||||
|
|
@ -163,7 +163,7 @@ where
|
||||||
|
|
||||||
debug.draw_started();
|
debug.draw_started();
|
||||||
self.mouse_interaction =
|
self.mouse_interaction =
|
||||||
user_interface.draw(renderer, theme, style, cursor_position);
|
user_interface.draw(renderer, theme, style, cursor);
|
||||||
debug.draw_finished();
|
debug.draw_finished();
|
||||||
|
|
||||||
self.cache = Some(user_interface.into_cache());
|
self.cache = Some(user_interface.into_cache());
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use crate::core::mouse;
|
||||||
use crate::core::renderer;
|
use crate::core::renderer;
|
||||||
use crate::core::widget;
|
use crate::core::widget;
|
||||||
use crate::core::window;
|
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};
|
use crate::core::{Element, Layout, Shell};
|
||||||
|
|
||||||
/// A set of interactive graphical elements with a specific [`Layout`].
|
/// 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 view(&self) -> iced_core::Element<(), Renderer> { unimplemented!() }
|
||||||
/// # pub fn update(&mut self, _: ()) {}
|
/// # 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_runtime::user_interface::{self, UserInterface};
|
||||||
/// use iced_wgpu::Renderer;
|
/// use iced_wgpu::Renderer;
|
||||||
///
|
///
|
||||||
|
|
@ -136,7 +138,7 @@ where
|
||||||
/// let mut cache = user_interface::Cache::new();
|
/// let mut cache = user_interface::Cache::new();
|
||||||
/// let mut renderer = Renderer::new();
|
/// let mut renderer = Renderer::new();
|
||||||
/// let mut window_size = Size::new(1024.0, 768.0);
|
/// 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 clipboard = clipboard::Null;
|
||||||
///
|
///
|
||||||
/// // Initialize our event storage
|
/// // Initialize our event storage
|
||||||
|
|
@ -156,7 +158,7 @@ where
|
||||||
/// // Update the user interface
|
/// // Update the user interface
|
||||||
/// let (state, event_statuses) = user_interface.update(
|
/// let (state, event_statuses) = user_interface.update(
|
||||||
/// &events,
|
/// &events,
|
||||||
/// cursor_position,
|
/// cursor,
|
||||||
/// &mut renderer,
|
/// &mut renderer,
|
||||||
/// &mut clipboard,
|
/// &mut clipboard,
|
||||||
/// &mut messages
|
/// &mut messages
|
||||||
|
|
@ -173,7 +175,7 @@ where
|
||||||
pub fn update(
|
pub fn update(
|
||||||
&mut self,
|
&mut self,
|
||||||
events: &[Event],
|
events: &[Event],
|
||||||
cursor_position: Point,
|
cursor: mouse::Cursor,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
messages: &mut Vec<Message>,
|
messages: &mut Vec<Message>,
|
||||||
|
|
@ -203,7 +205,7 @@ where
|
||||||
let event_status = overlay.on_event(
|
let event_status = overlay.on_event(
|
||||||
event,
|
event,
|
||||||
Layout::new(&layout),
|
Layout::new(&layout),
|
||||||
mouse::Cursor::Available(cursor_position),
|
cursor,
|
||||||
renderer,
|
renderer,
|
||||||
clipboard,
|
clipboard,
|
||||||
&mut shell,
|
&mut shell,
|
||||||
|
|
@ -255,19 +257,22 @@ where
|
||||||
let base_cursor = manual_overlay
|
let base_cursor = manual_overlay
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.filter(|overlay| {
|
.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)
|
.map(|_| mouse::Cursor::Unavailable)
|
||||||
.unwrap_or(mouse::Cursor::Available(cursor_position));
|
.unwrap_or(cursor);
|
||||||
|
|
||||||
self.overlay = Some(layout);
|
self.overlay = Some(layout);
|
||||||
|
|
||||||
(base_cursor, event_statuses)
|
(base_cursor, event_statuses)
|
||||||
} else {
|
} else {
|
||||||
(
|
(cursor, vec![event::Status::Ignored; events.len()])
|
||||||
mouse::Cursor::Available(cursor_position),
|
|
||||||
vec![event::Status::Ignored; events.len()],
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let _ = ManuallyDrop::into_inner(manual_overlay);
|
let _ = ManuallyDrop::into_inner(manual_overlay);
|
||||||
|
|
@ -359,8 +364,9 @@ where
|
||||||
/// # pub fn update(&mut self, _: ()) {}
|
/// # pub fn update(&mut self, _: ()) {}
|
||||||
/// # }
|
/// # }
|
||||||
/// use iced_runtime::core::clipboard;
|
/// use iced_runtime::core::clipboard;
|
||||||
|
/// use iced_runtime::core::mouse;
|
||||||
/// use iced_runtime::core::renderer;
|
/// 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_runtime::user_interface::{self, UserInterface};
|
||||||
/// use iced_wgpu::{Renderer, Theme};
|
/// use iced_wgpu::{Renderer, Theme};
|
||||||
///
|
///
|
||||||
|
|
@ -368,7 +374,7 @@ where
|
||||||
/// let mut cache = user_interface::Cache::new();
|
/// let mut cache = user_interface::Cache::new();
|
||||||
/// let mut renderer = Renderer::new();
|
/// let mut renderer = Renderer::new();
|
||||||
/// let mut window_size = Size::new(1024.0, 768.0);
|
/// 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 clipboard = clipboard::Null;
|
||||||
/// let mut events = Vec::new();
|
/// let mut events = Vec::new();
|
||||||
/// let mut messages = Vec::new();
|
/// let mut messages = Vec::new();
|
||||||
|
|
@ -387,14 +393,14 @@ where
|
||||||
/// // Update the user interface
|
/// // Update the user interface
|
||||||
/// let event_statuses = user_interface.update(
|
/// let event_statuses = user_interface.update(
|
||||||
/// &events,
|
/// &events,
|
||||||
/// cursor_position,
|
/// cursor,
|
||||||
/// &mut renderer,
|
/// &mut renderer,
|
||||||
/// &mut clipboard,
|
/// &mut clipboard,
|
||||||
/// &mut messages
|
/// &mut messages
|
||||||
/// );
|
/// );
|
||||||
///
|
///
|
||||||
/// // Draw the user interface
|
/// // 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();
|
/// cache = user_interface.into_cache();
|
||||||
///
|
///
|
||||||
|
|
@ -411,7 +417,7 @@ where
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
theme: &Renderer::Theme,
|
theme: &Renderer::Theme,
|
||||||
style: &renderer::Style,
|
style: &renderer::Style,
|
||||||
cursor_position: Point,
|
cursor: mouse::Cursor,
|
||||||
) -> mouse::Interaction {
|
) -> mouse::Interaction {
|
||||||
// TODO: Move to shell level (?)
|
// TODO: Move to shell level (?)
|
||||||
renderer.clear();
|
renderer.clear();
|
||||||
|
|
@ -427,19 +433,24 @@ where
|
||||||
overlay.layout(renderer, self.bounds, Vector::ZERO)
|
overlay.layout(renderer, self.bounds, Vector::ZERO)
|
||||||
});
|
});
|
||||||
|
|
||||||
let cursor = if overlay
|
let cursor = if cursor
|
||||||
.is_over(Layout::new(&overlay_layout), cursor_position)
|
.position()
|
||||||
|
.map(|cursor_position| {
|
||||||
|
overlay
|
||||||
|
.is_over(Layout::new(&overlay_layout), cursor_position)
|
||||||
|
})
|
||||||
|
.unwrap_or_default()
|
||||||
{
|
{
|
||||||
mouse::Cursor::Unavailable
|
mouse::Cursor::Unavailable
|
||||||
} else {
|
} else {
|
||||||
mouse::Cursor::Available(cursor_position)
|
cursor
|
||||||
};
|
};
|
||||||
|
|
||||||
self.overlay = Some(overlay_layout);
|
self.overlay = Some(overlay_layout);
|
||||||
|
|
||||||
cursor
|
cursor
|
||||||
} else {
|
} else {
|
||||||
mouse::Cursor::Available(cursor_position)
|
cursor
|
||||||
};
|
};
|
||||||
|
|
||||||
self.root.as_widget().draw(
|
self.root.as_widget().draw(
|
||||||
|
|
@ -480,7 +491,7 @@ where
|
||||||
.map(|overlay| {
|
.map(|overlay| {
|
||||||
let overlay_interaction = overlay.mouse_interaction(
|
let overlay_interaction = overlay.mouse_interaction(
|
||||||
Layout::new(layout),
|
Layout::new(layout),
|
||||||
mouse::Cursor::Available(cursor_position),
|
cursor,
|
||||||
&viewport,
|
&viewport,
|
||||||
renderer,
|
renderer,
|
||||||
);
|
);
|
||||||
|
|
@ -493,11 +504,19 @@ where
|
||||||
theme,
|
theme,
|
||||||
style,
|
style,
|
||||||
Layout::new(layout),
|
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
|
overlay_interaction
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -356,7 +356,7 @@ async fn run_instance<A, E, C>(
|
||||||
|
|
||||||
let (interface_state, statuses) = user_interface.update(
|
let (interface_state, statuses) = user_interface.update(
|
||||||
&events,
|
&events,
|
||||||
state.cursor_position(),
|
state.cursor(),
|
||||||
&mut renderer,
|
&mut renderer,
|
||||||
&mut clipboard,
|
&mut clipboard,
|
||||||
&mut messages,
|
&mut messages,
|
||||||
|
|
@ -422,7 +422,7 @@ async fn run_instance<A, E, C>(
|
||||||
|
|
||||||
let (interface_state, _) = user_interface.update(
|
let (interface_state, _) = user_interface.update(
|
||||||
&[redraw_event.clone()],
|
&[redraw_event.clone()],
|
||||||
state.cursor_position(),
|
state.cursor(),
|
||||||
&mut renderer,
|
&mut renderer,
|
||||||
&mut clipboard,
|
&mut clipboard,
|
||||||
&mut messages,
|
&mut messages,
|
||||||
|
|
@ -435,7 +435,7 @@ async fn run_instance<A, E, C>(
|
||||||
&renderer::Style {
|
&renderer::Style {
|
||||||
text_color: state.text_color(),
|
text_color: state.text_color(),
|
||||||
},
|
},
|
||||||
state.cursor_position(),
|
state.cursor(),
|
||||||
);
|
);
|
||||||
debug.draw_finished();
|
debug.draw_finished();
|
||||||
|
|
||||||
|
|
@ -508,7 +508,7 @@ async fn run_instance<A, E, C>(
|
||||||
&renderer::Style {
|
&renderer::Style {
|
||||||
text_color: state.text_color(),
|
text_color: state.text_color(),
|
||||||
},
|
},
|
||||||
state.cursor_position(),
|
state.cursor(),
|
||||||
);
|
);
|
||||||
|
|
||||||
if new_mouse_interaction != mouse_interaction {
|
if new_mouse_interaction != mouse_interaction {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
use crate::application::{self, StyleSheet as _};
|
use crate::application::{self, StyleSheet as _};
|
||||||
use crate::conversion;
|
use crate::conversion;
|
||||||
use crate::core;
|
use crate::core;
|
||||||
use crate::core::{Color, Point, Size};
|
use crate::core::mouse;
|
||||||
|
use crate::core::{Color, Size};
|
||||||
use crate::graphics::Viewport;
|
use crate::graphics::Viewport;
|
||||||
use crate::runtime::Debug;
|
use crate::runtime::Debug;
|
||||||
use crate::Application;
|
use crate::Application;
|
||||||
|
|
@ -20,7 +21,7 @@ where
|
||||||
scale_factor: f64,
|
scale_factor: f64,
|
||||||
viewport: Viewport,
|
viewport: Viewport,
|
||||||
viewport_version: usize,
|
viewport_version: usize,
|
||||||
cursor_position: winit::dpi::PhysicalPosition<f64>,
|
cursor_position: Option<winit::dpi::PhysicalPosition<f64>>,
|
||||||
modifiers: winit::event::ModifiersState,
|
modifiers: winit::event::ModifiersState,
|
||||||
theme: <A::Renderer as core::Renderer>::Theme,
|
theme: <A::Renderer as core::Renderer>::Theme,
|
||||||
appearance: application::Appearance,
|
appearance: application::Appearance,
|
||||||
|
|
@ -52,8 +53,7 @@ where
|
||||||
scale_factor,
|
scale_factor,
|
||||||
viewport,
|
viewport,
|
||||||
viewport_version: 0,
|
viewport_version: 0,
|
||||||
// TODO: Encode cursor availability in the type-system
|
cursor_position: None,
|
||||||
cursor_position: winit::dpi::PhysicalPosition::new(-1.0, -1.0),
|
|
||||||
modifiers: winit::event::ModifiersState::default(),
|
modifiers: winit::event::ModifiersState::default(),
|
||||||
theme,
|
theme,
|
||||||
appearance,
|
appearance,
|
||||||
|
|
@ -89,11 +89,16 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the current cursor position of the [`State`].
|
/// Returns the current cursor position of the [`State`].
|
||||||
pub fn cursor_position(&self) -> Point {
|
pub fn cursor(&self) -> mouse::Cursor {
|
||||||
conversion::cursor_position(
|
self.cursor_position
|
||||||
self.cursor_position,
|
.map(|cursor_position| {
|
||||||
self.viewport.scale_factor(),
|
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`].
|
/// Returns the current keyboard modifiers of the [`State`].
|
||||||
|
|
@ -153,12 +158,10 @@ where
|
||||||
| WindowEvent::Touch(Touch {
|
| WindowEvent::Touch(Touch {
|
||||||
location: position, ..
|
location: position, ..
|
||||||
}) => {
|
}) => {
|
||||||
self.cursor_position = *position;
|
self.cursor_position = Some(*position);
|
||||||
}
|
}
|
||||||
WindowEvent::CursorLeft { .. } => {
|
WindowEvent::CursorLeft { .. } => {
|
||||||
// TODO: Encode cursor availability in the type-system
|
self.cursor_position = None;
|
||||||
self.cursor_position =
|
|
||||||
winit::dpi::PhysicalPosition::new(-1.0, -1.0);
|
|
||||||
}
|
}
|
||||||
WindowEvent::ModifiersChanged(new_modifiers) => {
|
WindowEvent::ModifiersChanged(new_modifiers) => {
|
||||||
self.modifiers = *new_modifiers;
|
self.modifiers = *new_modifiers;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue