Implement basic cursor availability

This commit is contained in:
Héctor Ramón Jiménez 2023-06-08 20:11:59 +02:00
parent c15f1b5f65
commit 34451bff18
No known key found for this signature in database
GPG key ID: 140CC052C94F138E
55 changed files with 731 additions and 886 deletions

View file

@ -5,9 +5,7 @@ use crate::overlay;
use crate::renderer;
use crate::widget;
use crate::widget::tree::{self, Tree};
use crate::{
Clipboard, Color, Layout, Length, Point, Rectangle, Shell, Widget,
};
use crate::{Clipboard, Color, Layout, Length, Rectangle, Shell, Widget};
use std::any::Any;
use std::borrow::Borrow;
@ -378,7 +376,7 @@ where
tree: &mut Tree,
event: Event,
layout: Layout<'_>,
cursor_position: Point,
cursor: mouse::Cursor,
renderer: &Renderer,
clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, B>,
@ -390,7 +388,7 @@ where
tree,
event,
layout,
cursor_position,
cursor,
renderer,
clipboard,
&mut local_shell,
@ -408,35 +406,23 @@ where
theme: &Renderer::Theme,
style: &renderer::Style,
layout: Layout<'_>,
cursor_position: Point,
cursor: mouse::Cursor,
viewport: &Rectangle,
) {
self.widget.draw(
tree,
renderer,
theme,
style,
layout,
cursor_position,
viewport,
)
self.widget
.draw(tree, renderer, theme, style, layout, cursor, viewport)
}
fn mouse_interaction(
&self,
tree: &Tree,
layout: Layout<'_>,
cursor_position: Point,
cursor: mouse::Cursor,
viewport: &Rectangle,
renderer: &Renderer,
) -> mouse::Interaction {
self.widget.mouse_interaction(
tree,
layout,
cursor_position,
viewport,
renderer,
)
self.widget
.mouse_interaction(tree, layout, cursor, viewport, renderer)
}
fn overlay<'b>(
@ -521,20 +507,14 @@ where
state: &mut Tree,
event: Event,
layout: Layout<'_>,
cursor_position: Point,
cursor: mouse::Cursor,
renderer: &Renderer,
clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>,
) -> event::Status {
self.element.widget.on_event(
state,
event,
layout,
cursor_position,
renderer,
clipboard,
shell,
)
self.element
.widget
.on_event(state, event, layout, cursor, renderer, clipboard, shell)
}
fn draw(
@ -544,7 +524,7 @@ where
theme: &Renderer::Theme,
style: &renderer::Style,
layout: Layout<'_>,
cursor_position: Point,
cursor: mouse::Cursor,
viewport: &Rectangle,
) {
fn explain_layout<Renderer: crate::Renderer>(
@ -567,15 +547,9 @@ where
}
}
self.element.widget.draw(
state,
renderer,
theme,
style,
layout,
cursor_position,
viewport,
);
self.element
.widget
.draw(state, renderer, theme, style, layout, cursor, viewport);
explain_layout(renderer, self.color, layout);
}
@ -584,17 +558,13 @@ where
&self,
state: &Tree,
layout: Layout<'_>,
cursor_position: Point,
cursor: mouse::Cursor,
viewport: &Rectangle,
renderer: &Renderer,
) -> mouse::Interaction {
self.element.widget.mouse_interaction(
state,
layout,
cursor_position,
viewport,
renderer,
)
self.element
.widget
.mouse_interaction(state, layout, cursor, viewport, renderer)
}
fn overlay<'b>(

View file

@ -2,10 +2,12 @@
pub mod click;
mod button;
mod cursor;
mod event;
mod interaction;
pub use button::Button;
pub use click::Click;
pub use cursor::Cursor;
pub use event::{Event, ScrollDelta};
pub use interaction::Interaction;

51
core/src/mouse/cursor.rs Normal file
View file

@ -0,0 +1,51 @@
use crate::{Point, Rectangle, Vector};
/// The mouse cursor state.
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Cursor {
/// The cursor has a defined position.
Available(Point),
/// The cursor is currently unavailable (i.e. out of bounds or busy).
Unavailable,
}
impl Cursor {
/// Returns the absolute position of the [`Cursor`], if available.
pub fn position(self) -> Option<Point> {
match self {
Cursor::Available(position) => Some(position),
Cursor::Unavailable => None,
}
}
/// Returns the absolute position of the [`Cursor`], if available and inside
/// the given bounds.
///
/// If the [`Cursor`] is not over the provided bounds, this method will
/// return `None`.
pub fn position_over(self, bounds: &Rectangle) -> Option<Point> {
self.position().filter(|p| bounds.contains(*p))
}
/// Returns the relative position of the [`Cursor`] inside the given bounds,
/// if available.
///
/// If the [`Cursor`] is not over the provided bounds, this method will
/// return `None`.
pub fn position_in(self, bounds: &Rectangle) -> Option<Point> {
self.position_over(bounds)
.map(|p| p - Vector::new(bounds.x, bounds.y))
}
/// Returns the relative position of the [`Cursor`] from the given origin,
/// if available.
pub fn position_from(self, origin: Point) -> Option<Point> {
self.position().map(|p| p - Vector::new(origin.x, origin.y))
}
/// Returns true if the [`Cursor`] is over the given `bounds`.
pub fn is_over(self, bounds: &Rectangle) -> bool {
self.position_over(bounds).is_some()
}
}

View file

@ -38,7 +38,7 @@ where
theme: &Renderer::Theme,
style: &renderer::Style,
layout: Layout<'_>,
cursor_position: Point,
cursor: mouse::Cursor,
);
/// Applies a [`widget::Operation`] to the [`Overlay`].
@ -66,7 +66,7 @@ where
&mut self,
_event: Event,
_layout: Layout<'_>,
_cursor_position: Point,
_cursor: mouse::Cursor,
_renderer: &Renderer,
_clipboard: &mut dyn Clipboard,
_shell: &mut Shell<'_, Message>,
@ -80,7 +80,7 @@ where
fn mouse_interaction(
&self,
_layout: Layout<'_>,
_cursor_position: Point,
_cursor: mouse::Cursor,
_viewport: &Rectangle,
_renderer: &Renderer,
) -> mouse::Interaction {

View file

@ -68,35 +68,25 @@ where
&mut self,
event: Event,
layout: Layout<'_>,
cursor_position: Point,
cursor: mouse::Cursor,
renderer: &Renderer,
clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>,
) -> event::Status {
self.overlay.on_event(
event,
layout,
cursor_position,
renderer,
clipboard,
shell,
)
self.overlay
.on_event(event, layout, cursor, renderer, clipboard, shell)
}
/// Returns the current [`mouse::Interaction`] of the [`Element`].
pub fn mouse_interaction(
&self,
layout: Layout<'_>,
cursor_position: Point,
cursor: mouse::Cursor,
viewport: &Rectangle,
renderer: &Renderer,
) -> mouse::Interaction {
self.overlay.mouse_interaction(
layout,
cursor_position,
viewport,
renderer,
)
self.overlay
.mouse_interaction(layout, cursor, viewport, renderer)
}
/// Draws the [`Element`] and its children using the given [`Layout`].
@ -106,10 +96,9 @@ where
theme: &Renderer::Theme,
style: &renderer::Style,
layout: Layout<'_>,
cursor_position: Point,
cursor: mouse::Cursor,
) {
self.overlay
.draw(renderer, theme, style, layout, cursor_position)
self.overlay.draw(renderer, theme, style, layout, cursor)
}
/// Applies a [`widget::Operation`] to the [`Element`].
@ -215,7 +204,7 @@ where
&mut self,
event: Event,
layout: Layout<'_>,
cursor_position: Point,
cursor: mouse::Cursor,
renderer: &Renderer,
clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, B>,
@ -226,7 +215,7 @@ where
let event_status = self.content.on_event(
event,
layout,
cursor_position,
cursor,
renderer,
clipboard,
&mut local_shell,
@ -240,16 +229,12 @@ where
fn mouse_interaction(
&self,
layout: Layout<'_>,
cursor_position: Point,
cursor: mouse::Cursor,
viewport: &Rectangle,
renderer: &Renderer,
) -> mouse::Interaction {
self.content.mouse_interaction(
layout,
cursor_position,
viewport,
renderer,
)
self.content
.mouse_interaction(layout, cursor, viewport, renderer)
}
fn draw(
@ -258,10 +243,9 @@ where
theme: &Renderer::Theme,
style: &renderer::Style,
layout: Layout<'_>,
cursor_position: Point,
cursor: mouse::Cursor,
) {
self.content
.draw(renderer, theme, style, layout, cursor_position)
self.content.draw(renderer, theme, style, layout, cursor)
}
fn is_over(&self, layout: Layout<'_>, cursor_position: Point) -> bool {

View file

@ -81,7 +81,7 @@ where
&mut self,
event: Event,
layout: Layout<'_>,
cursor_position: Point,
cursor: mouse::Cursor,
renderer: &Renderer,
clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>,
@ -93,7 +93,7 @@ where
child.on_event(
event.clone(),
layout,
cursor_position,
cursor,
renderer,
clipboard,
shell,
@ -108,17 +108,17 @@ where
theme: &<Renderer as crate::Renderer>::Theme,
style: &renderer::Style,
layout: Layout<'_>,
cursor_position: Point,
cursor: mouse::Cursor,
) {
for (child, layout) in self.children.iter().zip(layout.children()) {
child.draw(renderer, theme, style, layout, cursor_position);
child.draw(renderer, theme, style, layout, cursor);
}
}
fn mouse_interaction(
&self,
layout: Layout<'_>,
cursor_position: Point,
cursor: mouse::Cursor,
viewport: &Rectangle,
renderer: &Renderer,
) -> mouse::Interaction {
@ -126,12 +126,7 @@ where
.iter()
.zip(layout.children())
.map(|(child, layout)| {
child.mouse_interaction(
layout,
cursor_position,
viewport,
renderer,
)
child.mouse_interaction(layout, cursor, viewport, renderer)
})
.max()
.unwrap_or_default()

View file

@ -15,7 +15,7 @@ use crate::layout::{self, Layout};
use crate::mouse;
use crate::overlay;
use crate::renderer;
use crate::{Clipboard, Length, Point, Rectangle, Shell};
use crate::{Clipboard, Length, Rectangle, Shell};
/// A component that displays information and allows interaction.
///
@ -67,7 +67,7 @@ where
theme: &Renderer::Theme,
style: &renderer::Style,
layout: Layout<'_>,
cursor_position: Point,
cursor: mouse::Cursor,
viewport: &Rectangle,
);
@ -111,7 +111,7 @@ where
_state: &mut Tree,
_event: Event,
_layout: Layout<'_>,
_cursor_position: Point,
_cursor: mouse::Cursor,
_renderer: &Renderer,
_clipboard: &mut dyn Clipboard,
_shell: &mut Shell<'_, Message>,
@ -126,7 +126,7 @@ where
&self,
_state: &Tree,
_layout: Layout<'_>,
_cursor_position: Point,
_cursor: mouse::Cursor,
_viewport: &Rectangle,
_renderer: &Renderer,
) -> mouse::Interaction {

View file

@ -1,12 +1,11 @@
//! Write some text for your users to read.
use crate::alignment;
use crate::layout;
use crate::mouse;
use crate::renderer;
use crate::text;
use crate::widget::Tree;
use crate::{
Color, Element, Layout, Length, Pixels, Point, Rectangle, Size, Widget,
};
use crate::{Color, Element, Layout, Length, Pixels, Rectangle, Size, Widget};
use std::borrow::Cow;
@ -163,7 +162,7 @@ where
theme: &Renderer::Theme,
style: &renderer::Style,
layout: Layout<'_>,
_cursor_position: Point,
_cursor_position: mouse::Cursor,
_viewport: &Rectangle,
) {
draw(