diff options
author | 2021-10-18 16:43:18 +0700 | |
---|---|---|
committer | 2021-10-18 16:43:18 +0700 | |
commit | be97a5d502df8c8b23704f5a8a0d425f4eff2215 (patch) | |
tree | 187f0477534c5d5c783ef06686e2209bbf4f3b80 | |
parent | 7a876c8b2918ae90cedfd82d1881cf6406811eeb (diff) | |
download | iced-be97a5d502df8c8b23704f5a8a0d425f4eff2215.tar.gz iced-be97a5d502df8c8b23704f5a8a0d425f4eff2215.tar.bz2 iced-be97a5d502df8c8b23704f5a8a0d425f4eff2215.zip |
Introduce `mouse_interaction` method to `Widget` trait
-rw-r--r-- | examples/integration_opengl/src/main.rs | 1 | ||||
-rw-r--r-- | examples/integration_wgpu/src/main.rs | 1 | ||||
-rw-r--r-- | glutin/src/application.rs | 29 | ||||
-rw-r--r-- | native/src/element.rs | 32 | ||||
-rw-r--r-- | native/src/overlay.rs | 15 | ||||
-rw-r--r-- | native/src/overlay/element.rs | 13 | ||||
-rw-r--r-- | native/src/program/state.rs | 17 | ||||
-rw-r--r-- | native/src/user_interface.rs | 25 | ||||
-rw-r--r-- | native/src/widget.rs | 13 | ||||
-rw-r--r-- | winit/src/application.rs | 27 |
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( |