summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/integration_opengl/src/main.rs1
-rw-r--r--examples/integration_wgpu/src/main.rs1
-rw-r--r--glutin/src/application.rs29
-rw-r--r--native/src/element.rs32
-rw-r--r--native/src/overlay.rs15
-rw-r--r--native/src/overlay/element.rs13
-rw-r--r--native/src/program/state.rs17
-rw-r--r--native/src/user_interface.rs25
-rw-r--r--native/src/widget.rs13
-rw-r--r--winit/src/application.rs27
10 files changed, 152 insertions, 21 deletions
diff --git a/examples/integration_opengl/src/main.rs b/examples/integration_opengl/src/main.rs
index bab6331e..ef79b889 100644
--- a/examples/integration_opengl/src/main.rs
+++ b/examples/integration_opengl/src/main.rs
@@ -68,7 +68,6 @@ 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,
);
diff --git a/examples/integration_wgpu/src/main.rs b/examples/integration_wgpu/src/main.rs
index 9980acc2..c2c857d2 100644
--- a/examples/integration_wgpu/src/main.rs
+++ b/examples/integration_wgpu/src/main.rs
@@ -93,7 +93,6 @@ 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,
);
diff --git a/glutin/src/application.rs b/glutin/src/application.rs
index 508dfe04..5d10e96a 100644
--- a/glutin/src/application.rs
+++ b/glutin/src/application.rs
@@ -1,4 +1,5 @@
//! Create interactive, native cross-platform applications.
+use crate::mouse;
use crate::{Error, Executor, Runtime};
pub use iced_winit::Application;
@@ -179,9 +180,7 @@ async fn run_instance<A, E, C>(
&mut debug,
));
- // TODO
- // let mut mouse_interaction = mouse::Interaction::default();
-
+ let mut mouse_interaction = mouse::Interaction::default();
let mut events = Vec::new();
let mut messages = Vec::new();
@@ -245,9 +244,18 @@ async fn run_instance<A, E, C>(
}
debug.draw_started();
- user_interface.draw(&mut renderer, state.cursor_position());
+ let new_mouse_interaction =
+ user_interface.draw(&mut renderer, state.cursor_position());
debug.draw_finished();
+ if new_mouse_interaction != mouse_interaction {
+ context.window().set_cursor_icon(
+ conversion::mouse_interaction(new_mouse_interaction),
+ );
+
+ mouse_interaction = new_mouse_interaction;
+ }
+
context.window().request_redraw();
}
event::Event::PlatformSpecific(event::PlatformSpecific::MacOS(
@@ -289,9 +297,20 @@ async fn run_instance<A, E, C>(
debug.layout_finished();
debug.draw_started();
- user_interface.draw(&mut renderer, state.cursor_position());
+ let new_mouse_interaction = user_interface
+ .draw(&mut renderer, state.cursor_position());
debug.draw_finished();
+ if new_mouse_interaction != mouse_interaction {
+ context.window().set_cursor_icon(
+ conversion::mouse_interaction(
+ new_mouse_interaction,
+ ),
+ );
+
+ mouse_interaction = new_mouse_interaction;
+ }
+
context.resize(glutin::dpi::PhysicalSize::new(
physical_size.width,
physical_size.height,
diff --git a/native/src/element.rs b/native/src/element.rs
index 3ecd8e26..44b6d1ec 100644
--- a/native/src/element.rs
+++ b/native/src/element.rs
@@ -1,5 +1,6 @@
use crate::event::{self, Event};
use crate::layout;
+use crate::mouse;
use crate::overlay;
use crate::renderer;
use crate::{
@@ -251,6 +252,16 @@ where
.draw(renderer, style, layout, cursor_position, viewport)
}
+ pub fn mouse_interaction(
+ &self,
+ layout: Layout<'_>,
+ viewport: &Rectangle,
+ cursor_position: Point,
+ ) -> mouse::Interaction {
+ self.widget
+ .mouse_interaction(layout, viewport, cursor_position)
+ }
+
/// Computes the _layout_ hash of the [`Element`].
pub fn hash_layout(&self, state: &mut Hasher) {
self.widget.hash_layout(state);
@@ -346,6 +357,16 @@ where
.draw(renderer, style, layout, cursor_position, viewport)
}
+ fn mouse_interaction(
+ &self,
+ layout: Layout<'_>,
+ viewport: &Rectangle,
+ cursor_position: Point,
+ ) -> mouse::Interaction {
+ self.widget
+ .mouse_interaction(layout, viewport, cursor_position)
+ }
+
fn hash_layout(&self, state: &mut Hasher) {
self.widget.hash_layout(state);
}
@@ -426,6 +447,17 @@ where
) {
}
+ fn mouse_interaction(
+ &self,
+ layout: Layout<'_>,
+ viewport: &Rectangle,
+ cursor_position: Point,
+ ) -> mouse::Interaction {
+ self.element
+ .widget
+ .mouse_interaction(layout, viewport, cursor_position)
+ }
+
fn hash_layout(&self, state: &mut Hasher) {
self.element.widget.hash_layout(state);
}
diff --git a/native/src/overlay.rs b/native/src/overlay.rs
index 25b49adf..70e3305b 100644
--- a/native/src/overlay.rs
+++ b/native/src/overlay.rs
@@ -8,8 +8,9 @@ pub use menu::Menu;
use crate::event::{self, Event};
use crate::layout;
+use crate::mouse;
use crate::renderer;
-use crate::{Clipboard, Hasher, Layout, Point, Size};
+use crate::{Clipboard, Hasher, Layout, Point, Rectangle, Size};
/// An interactive component that can be displayed on top of other widgets.
pub trait Overlay<Message, Renderer>
@@ -74,4 +75,16 @@ where
) -> event::Status {
event::Status::Ignored
}
+
+ /// Returns the current [`mouse::Interaction`] of the [`Widget`].
+ ///
+ /// By default, it returns [`mouse::Interaction::Idle`].
+ fn mouse_interaction(
+ &self,
+ _layout: Layout<'_>,
+ _viewport: &Rectangle,
+ _cursor_position: Point,
+ ) -> mouse::Interaction {
+ mouse::Interaction::Idle
+ }
}
diff --git a/native/src/overlay/element.rs b/native/src/overlay/element.rs
index bf3fb3f0..988cca09 100644
--- a/native/src/overlay/element.rs
+++ b/native/src/overlay/element.rs
@@ -2,8 +2,9 @@ pub use crate::Overlay;
use crate::event::{self, Event};
use crate::layout;
+use crate::mouse;
use crate::renderer;
-use crate::{Clipboard, Hasher, Layout, Point, Size, Vector};
+use crate::{Clipboard, Hasher, Layout, Point, Rectangle, Size, Vector};
/// A generic [`Overlay`].
#[allow(missing_debug_implementations)]
@@ -68,6 +69,16 @@ where
)
}
+ pub fn mouse_interaction(
+ &self,
+ layout: Layout<'_>,
+ viewport: &Rectangle,
+ cursor_position: Point,
+ ) -> mouse::Interaction {
+ self.overlay
+ .mouse_interaction(layout, viewport, cursor_position)
+ }
+
/// Draws the [`Element`] and its children using the given [`Layout`].
pub fn draw(
&self,
diff --git a/native/src/program/state.rs b/native/src/program/state.rs
index 55308a92..26c0eb21 100644
--- a/native/src/program/state.rs
+++ b/native/src/program/state.rs
@@ -1,3 +1,4 @@
+use crate::mouse;
use crate::{
Cache, Clipboard, Command, Debug, Event, Point, Program, Size,
UserInterface,
@@ -14,6 +15,7 @@ where
cache: Option<Cache>,
queued_events: Vec<Event>,
queued_messages: Vec<P::Message>,
+ mouse_interaction: mouse::Interaction,
}
impl<P> State<P>
@@ -25,11 +27,10 @@ where
pub fn new(
mut program: P,
bounds: Size,
- cursor_position: Point,
renderer: &mut P::Renderer,
debug: &mut Debug,
) -> Self {
- let mut user_interface = build_user_interface(
+ let user_interface = build_user_interface(
&mut program,
Cache::default(),
renderer,
@@ -44,6 +45,7 @@ where
cache,
queued_events: Vec::new(),
queued_messages: Vec::new(),
+ mouse_interaction: mouse::Interaction::Idle,
}
}
@@ -71,6 +73,11 @@ where
self.queued_events.is_empty() && self.queued_messages.is_empty()
}
+ /// Returns the current [`mouse::Interaction`] of the [`State`].
+ pub fn mouse_interaction(&self) -> mouse::Interaction {
+ self.mouse_interaction
+ }
+
/// Processes all the queued events and messages, rebuilding and redrawing
/// the widgets of the linked [`Program`] if necessary.
///
@@ -109,7 +116,8 @@ where
if messages.is_empty() {
debug.draw_started();
- user_interface.draw(renderer, cursor_position);
+ self.mouse_interaction =
+ user_interface.draw(renderer, cursor_position);
debug.draw_finished();
self.cache = Some(user_interface.into_cache());
@@ -140,7 +148,8 @@ where
);
debug.draw_started();
- user_interface.draw(renderer, cursor_position);
+ self.mouse_interaction =
+ 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 2f76c084..d9338524 100644
--- a/native/src/user_interface.rs
+++ b/native/src/user_interface.rs
@@ -1,5 +1,6 @@
use crate::event::{self, Event};
use crate::layout;
+use crate::mouse;
use crate::overlay;
use crate::renderer;
use crate::{Clipboard, Element, Layout, Point, Rectangle, Size, Vector};
@@ -330,7 +331,11 @@ where
/// // Flush rendering operations...
/// }
/// ```
- pub fn draw(&mut self, renderer: &mut Renderer, cursor_position: Point) {
+ pub fn draw(
+ &mut self,
+ renderer: &mut Renderer,
+ cursor_position: Point,
+ ) -> mouse::Interaction {
// TODO: Move to shell level (?)
renderer.clear();
@@ -346,6 +351,12 @@ where
renderer,
);
+ let mouse_interaction = overlay.mouse_interaction(
+ Layout::new(&layer.layout),
+ &viewport,
+ cursor_position,
+ );
+
let overlay_bounds = layer.layout.bounds();
renderer.with_layer(
@@ -363,12 +374,12 @@ where
self.overlay = Some(layer);
- Some(overlay_bounds)
+ Some((overlay_bounds, mouse_interaction))
} else {
None
};
- if let Some(overlay_bounds) = overlay {
+ if let Some((overlay_bounds, overlay_interaction)) = overlay {
let base_cursor = if overlay_bounds.contains(cursor_position) {
Point::new(-1.0, -1.0)
} else {
@@ -382,6 +393,8 @@ where
base_cursor,
&viewport,
);
+
+ overlay_interaction
} else {
self.root.widget.draw(
renderer,
@@ -390,6 +403,12 @@ where
cursor_position,
&viewport,
);
+
+ self.root.widget.mouse_interaction(
+ Layout::new(&self.base.layout),
+ &viewport,
+ cursor_position,
+ )
}
}
diff --git a/native/src/widget.rs b/native/src/widget.rs
index 9a494771..9999701e 100644
--- a/native/src/widget.rs
+++ b/native/src/widget.rs
@@ -80,6 +80,7 @@ pub use tooltip::Tooltip;
use crate::event::{self, Event};
use crate::layout;
+use crate::mouse;
use crate::overlay;
use crate::renderer;
use crate::{Clipboard, Hasher, Layout, Length, Point, Rectangle};
@@ -175,6 +176,18 @@ where
event::Status::Ignored
}
+ /// Returns the current [`mouse::Interaction`] of the [`Widget`].
+ ///
+ /// By default, it returns [`mouse::Interaction::Idle`].
+ fn mouse_interaction(
+ &self,
+ _layout: Layout<'_>,
+ _viewport: &Rectangle,
+ _cursor_position: Point,
+ ) -> mouse::Interaction {
+ mouse::Interaction::Idle
+ }
+
/// Returns the overlay of the [`Widget`], if there is any.
fn overlay(
&mut self,
diff --git a/winit/src/application.rs b/winit/src/application.rs
index 70562627..9d787933 100644
--- a/winit/src/application.rs
+++ b/winit/src/application.rs
@@ -5,6 +5,7 @@ pub use state::State;
use crate::clipboard::{self, Clipboard};
use crate::conversion;
+use crate::mouse;
use crate::{
Color, Command, Debug, Error, Executor, Mode, Proxy, Runtime, Settings,
Size, Subscription,
@@ -252,9 +253,7 @@ async fn run_instance<A, E, C>(
&mut debug,
));
- // TODO
- // let mut mouse_interaction = mouse::Interaction::default();
-
+ let mut mouse_interaction = mouse::Interaction::default();
let mut events = Vec::new();
let mut messages = Vec::new();
@@ -317,9 +316,18 @@ async fn run_instance<A, E, C>(
}
debug.draw_started();
- user_interface.draw(&mut renderer, state.cursor_position());
+ let new_mouse_interaction =
+ user_interface.draw(&mut renderer, state.cursor_position());
debug.draw_finished();
+ if new_mouse_interaction != mouse_interaction {
+ window.set_cursor_icon(conversion::mouse_interaction(
+ new_mouse_interaction,
+ ));
+
+ mouse_interaction = new_mouse_interaction;
+ }
+
window.request_redraw();
}
event::Event::PlatformSpecific(event::PlatformSpecific::MacOS(
@@ -356,7 +364,16 @@ async fn run_instance<A, E, C>(
debug.layout_finished();
debug.draw_started();
- user_interface.draw(&mut renderer, state.cursor_position());
+ let new_mouse_interaction = user_interface
+ .draw(&mut renderer, state.cursor_position());
+
+ if new_mouse_interaction != mouse_interaction {
+ window.set_cursor_icon(conversion::mouse_interaction(
+ new_mouse_interaction,
+ ));
+
+ mouse_interaction = new_mouse_interaction;
+ }
debug.draw_finished();
compositor.configure_surface(