diff --git a/examples/integration/src/main.rs b/examples/integration/src/main.rs
index 4c4b6d84..33d4c361 100644
--- a/examples/integration/src/main.rs
+++ b/examples/integration/src/main.rs
@@ -5,9 +5,10 @@ use controls::Controls;
use scene::Scene;
use iced_wgpu::{wgpu, Backend, Renderer, Settings, Viewport};
-use iced_winit::{futures, program, winit, Debug, Size};
+use iced_winit::{conversion, futures, program, winit, Debug, Size};
use winit::{
+ dpi::PhysicalPosition,
event::{Event, ModifiersState, WindowEvent},
event_loop::{ControlFlow, EventLoop},
};
@@ -24,6 +25,7 @@ pub fn main() {
Size::new(physical_size.width, physical_size.height),
window.scale_factor(),
);
+ let mut cursor_position = PhysicalPosition::new(-1.0, -1.0);
let mut modifiers = ModifiersState::default();
// Initialize wgpu
@@ -79,6 +81,7 @@ pub fn main() {
let mut state = program::State::new(
controls,
viewport.logical_size(),
+ conversion::cursor_position(cursor_position, viewport.scale_factor()),
&mut renderer,
&mut debug,
);
@@ -91,6 +94,9 @@ pub fn main() {
match event {
Event::WindowEvent { event, .. } => {
match event {
+ WindowEvent::CursorMoved { position, .. } => {
+ cursor_position = position;
+ }
WindowEvent::ModifiersChanged(new_modifiers) => {
modifiers = new_modifiers;
}
@@ -105,7 +111,6 @@ pub fn main() {
WindowEvent::CloseRequested => {
*control_flow = ControlFlow::Exit;
}
-
_ => {}
}
@@ -123,8 +128,12 @@ pub fn main() {
if !state.is_queue_empty() {
// We update iced
let _ = state.update(
- None,
viewport.logical_size(),
+ conversion::cursor_position(
+ cursor_position,
+ viewport.scale_factor(),
+ ),
+ None,
&mut renderer,
&mut debug,
);
diff --git a/glutin/src/application.rs b/glutin/src/application.rs
index 93877734..3be9b65f 100644
--- a/glutin/src/application.rs
+++ b/glutin/src/application.rs
@@ -70,6 +70,7 @@ pub fn run(
};
let clipboard = Clipboard::new(&context.window());
+ let mut cursor_position = glutin::dpi::PhysicalPosition::new(-1.0, -1.0);
let mut mouse_interaction = mouse::Interaction::default();
let mut modifiers = glutin::event::ModifiersState::default();
@@ -90,6 +91,7 @@ pub fn run(
let mut state = program::State::new(
application,
viewport.logical_size(),
+ conversion::cursor_position(cursor_position, viewport.scale_factor()),
&mut renderer,
&mut debug,
);
@@ -103,8 +105,12 @@ pub fn run(
let command = runtime.enter(|| {
state.update(
- clipboard.as_ref().map(|c| c as _),
viewport.logical_size(),
+ conversion::cursor_position(
+ cursor_position,
+ viewport.scale_factor(),
+ ),
+ clipboard.as_ref().map(|c| c as _),
&mut renderer,
&mut debug,
)
@@ -159,11 +165,14 @@ pub fn run(
// The queue is empty, therefore this will never produce
// a `Command`.
//
- // TODO: Properly queue `WindowResized` and `CursorMoved`
- // events.
+ // TODO: Properly queue `WindowResized`
let _ = state.update(
- clipboard.as_ref().map(|c| c as _),
viewport.logical_size(),
+ conversion::cursor_position(
+ cursor_position,
+ viewport.scale_factor(),
+ ),
+ clipboard.as_ref().map(|c| c as _),
&mut renderer,
&mut debug,
);
@@ -225,6 +234,7 @@ pub fn run(
context.window(),
scale_factor,
control_flow,
+ &mut cursor_position,
&mut modifiers,
&mut viewport,
&mut resized,
diff --git a/native/src/program/state.rs b/native/src/program/state.rs
index bb428198..fdc42e8b 100644
--- a/native/src/program/state.rs
+++ b/native/src/program/state.rs
@@ -1,5 +1,5 @@
use crate::{
- Cache, Clipboard, Command, Debug, Event, Program, Renderer, Size,
+ Cache, Clipboard, Command, Debug, Event, Point, Program, Renderer, Size,
UserInterface,
};
@@ -31,6 +31,7 @@ where
pub fn new(
mut program: P,
bounds: Size,
+ cursor_position: Point,
renderer: &mut P::Renderer,
debug: &mut Debug,
) -> Self {
@@ -43,7 +44,7 @@ where
);
debug.draw_started();
- let primitive = user_interface.draw(renderer);
+ let primitive = user_interface.draw(renderer, cursor_position);
debug.draw_finished();
let cache = Some(user_interface.into_cache());
@@ -104,8 +105,9 @@ where
/// [`Program`]: trait.Program.html
pub fn update(
&mut self,
- clipboard: Option<&dyn Clipboard>,
bounds: Size,
+ cursor_position: Point,
+ clipboard: Option<&dyn Clipboard>,
renderer: &mut P::Renderer,
debug: &mut Debug,
) -> Option> {
@@ -120,6 +122,7 @@ where
debug.event_processing_started();
let mut messages = user_interface.update(
self.queued_events.drain(..),
+ cursor_position,
clipboard,
renderer,
);
@@ -128,7 +131,7 @@ where
if messages.is_empty() {
debug.draw_started();
- self.primitive = user_interface.draw(renderer);
+ self.primitive = user_interface.draw(renderer, cursor_position);
debug.draw_finished();
self.cache = Some(user_interface.into_cache());
@@ -159,7 +162,7 @@ where
);
debug.draw_started();
- self.primitive = user_interface.draw(renderer);
+ self.primitive = user_interface.draw(renderer, cursor_position);
debug.draw_finished();
self.cache = Some(user_interface.into_cache());
diff --git a/native/src/user_interface.rs b/native/src/user_interface.rs
index e963b601..b9646043 100644
--- a/native/src/user_interface.rs
+++ b/native/src/user_interface.rs
@@ -1,4 +1,4 @@
-use crate::{layout, mouse, Clipboard, Element, Event, Layout, Point, Size};
+use crate::{layout, Clipboard, Element, Event, Layout, Point, Size};
use std::hash::Hasher;
@@ -23,7 +23,6 @@ pub struct UserInterface<'a, Message, Renderer> {
root: Element<'a, Message, Renderer>,
layout: layout::Node,
bounds: Size,
- cursor_position: Point,
}
impl<'a, Message, Renderer> UserInterface<'a, Message, Renderer>
@@ -115,7 +114,6 @@ where
root,
layout,
bounds,
- cursor_position: cache.cursor_position,
}
}
@@ -132,7 +130,7 @@ where
/// completing [the previous example](#example):
///
/// ```no_run
- /// use iced_native::{UserInterface, Cache, Size};
+ /// use iced_native::{UserInterface, Cache, Size, Point};
/// use iced_wgpu::Renderer;
///
/// # mod iced_wgpu {
@@ -154,6 +152,7 @@ where
/// let mut cache = Cache::new();
/// let mut renderer = Renderer::new();
/// let mut window_size = Size::new(1024.0, 768.0);
+ /// let mut cursor_position = Point::default();
///
/// // Initialize our event storage
/// let mut events = Vec::new();
@@ -169,7 +168,12 @@ where
/// );
///
/// // Update the user interface
- /// let messages = user_interface.update(events.drain(..), None, &renderer);
+ /// let messages = user_interface.update(
+ /// events.drain(..),
+ /// cursor_position,
+ /// None,
+ /// &renderer,
+ /// );
///
/// cache = user_interface.into_cache();
///
@@ -182,20 +186,17 @@ where
pub fn update(
&mut self,
events: impl IntoIterator- ,
+ cursor_position: Point,
clipboard: Option<&dyn Clipboard>,
renderer: &Renderer,
) -> Vec {
let mut messages = Vec::new();
for event in events {
- if let Event::Mouse(mouse::Event::CursorMoved { x, y }) = event {
- self.cursor_position = Point::new(x, y);
- }
-
self.root.widget.on_event(
event,
Layout::new(&self.layout),
- self.cursor_position,
+ cursor_position,
&mut messages,
renderer,
clipboard,
@@ -219,7 +220,7 @@ where
/// [completing the last example](#example-1):
///
/// ```no_run
- /// use iced_native::{UserInterface, Cache, Size};
+ /// use iced_native::{UserInterface, Cache, Size, Point};
/// use iced_wgpu::Renderer;
///
/// # mod iced_wgpu {
@@ -241,6 +242,7 @@ where
/// let mut cache = 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 events = Vec::new();
///
/// loop {
@@ -253,10 +255,15 @@ where
/// &mut renderer,
/// );
///
- /// let messages = user_interface.update(events.drain(..), None, &renderer);
+ /// let messages = user_interface.update(
+ /// events.drain(..),
+ /// cursor_position,
+ /// None,
+ /// &renderer,
+ /// );
///
/// // Draw the user interface
- /// let mouse_cursor = user_interface.draw(&mut renderer);
+ /// let mouse_cursor = user_interface.draw(&mut renderer, cursor_position);
///
/// cache = user_interface.into_cache();
///
@@ -268,12 +275,16 @@ where
/// // Flush rendering operations...
/// }
/// ```
- pub fn draw(&self, renderer: &mut Renderer) -> Renderer::Output {
+ pub fn draw(
+ &self,
+ renderer: &mut Renderer,
+ cursor_position: Point,
+ ) -> Renderer::Output {
self.root.widget.draw(
renderer,
&Renderer::Defaults::default(),
Layout::new(&self.layout),
- self.cursor_position,
+ cursor_position,
)
}
@@ -287,7 +298,6 @@ where
hash: self.hash,
layout: self.layout,
bounds: self.bounds,
- cursor_position: self.cursor_position,
}
}
}
@@ -300,7 +310,6 @@ pub struct Cache {
hash: u64,
layout: layout::Node,
bounds: Size,
- cursor_position: Point,
}
impl Cache {
@@ -316,7 +325,6 @@ impl Cache {
hash: 0,
layout: layout::Node::new(Size::new(0.0, 0.0)),
bounds: Size::ZERO,
- cursor_position: Point::new(-1.0, -1.0),
}
}
}
@@ -329,7 +337,7 @@ impl Default for Cache {
impl PartialEq for Cache {
fn eq(&self, other: &Cache) -> bool {
- self.hash == other.hash && self.cursor_position == other.cursor_position
+ self.hash == other.hash
}
}
diff --git a/winit/src/application.rs b/winit/src/application.rs
index cb1bbf1e..5b93c8af 100644
--- a/winit/src/application.rs
+++ b/winit/src/application.rs
@@ -148,6 +148,7 @@ pub fn run(
.expect("Open window");
let clipboard = Clipboard::new(&window);
+ let mut cursor_position = winit::dpi::PhysicalPosition::new(-1.0, -1.0);
let mut mouse_interaction = mouse::Interaction::default();
let mut modifiers = winit::event::ModifiersState::default();
@@ -171,6 +172,7 @@ pub fn run(
let mut state = program::State::new(
application,
viewport.logical_size(),
+ conversion::cursor_position(cursor_position, viewport.scale_factor()),
&mut renderer,
&mut debug,
);
@@ -184,8 +186,12 @@ pub fn run(
let command = runtime.enter(|| {
state.update(
- clipboard.as_ref().map(|c| c as _),
viewport.logical_size(),
+ conversion::cursor_position(
+ cursor_position,
+ viewport.scale_factor(),
+ ),
+ clipboard.as_ref().map(|c| c as _),
&mut renderer,
&mut debug,
)
@@ -240,11 +246,14 @@ pub fn run(
// The queue is empty, therefore this will never produce
// a `Command`.
//
- // TODO: Properly queue `WindowResized` and `CursorMoved`
- // events.
+ // TODO: Properly queue `WindowResized`
let _ = state.update(
- clipboard.as_ref().map(|c| c as _),
viewport.logical_size(),
+ conversion::cursor_position(
+ cursor_position,
+ viewport.scale_factor(),
+ ),
+ clipboard.as_ref().map(|c| c as _),
&mut renderer,
&mut debug,
);
@@ -304,6 +313,7 @@ pub fn run(
&window,
scale_factor,
control_flow,
+ &mut cursor_position,
&mut modifiers,
&mut viewport,
&mut resized,
@@ -332,6 +342,7 @@ pub fn handle_window_event(
window: &winit::window::Window,
scale_factor: f64,
control_flow: &mut winit::event_loop::ControlFlow,
+ cursor_position: &mut winit::dpi::PhysicalPosition,
modifiers: &mut winit::event::ModifiersState,
viewport: &mut Viewport,
resized: &mut bool,
@@ -352,6 +363,9 @@ pub fn handle_window_event(
WindowEvent::CloseRequested => {
*control_flow = ControlFlow::Exit;
}
+ WindowEvent::CursorMoved { position, .. } => {
+ *cursor_position = *position;
+ }
WindowEvent::ModifiersChanged(new_modifiers) => {
*modifiers = *new_modifiers;
}
diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs
index b887db6e..80727bd8 100644
--- a/winit/src/conversion.rs
+++ b/winit/src/conversion.rs
@@ -4,7 +4,7 @@
//! [`iced_native`]: https://github.com/hecrj/iced/tree/master/native
use crate::{
keyboard::{self, KeyCode, ModifiersState},
- mouse, window, Event, Mode,
+ mouse, window, Event, Mode, Point,
};
/// Converts a winit window event into an iced event.
@@ -174,6 +174,16 @@ pub fn modifiers_state(
}
}
+/// Converts a physical cursor position to a logical `Point`.
+pub fn cursor_position(
+ position: winit::dpi::PhysicalPosition,
+ scale_factor: f64,
+) -> Point {
+ let logical_position = position.to_logical(scale_factor);
+
+ Point::new(logical_position.x, logical_position.y)
+}
+
/// Converts a `VirtualKeyCode` from [`winit`] to an [`iced_native`] key code.
///
/// [`winit`]: https://github.com/rust-windowing/winit