summaryrefslogtreecommitdiffstats
path: root/core/src/mouse
diff options
context:
space:
mode:
authorLibravatar Bingus <shankern@protonmail.com>2023-07-12 12:23:18 -0700
committerLibravatar Bingus <shankern@protonmail.com>2023-07-12 12:23:18 -0700
commit633f405f3f78bc7f82d2b2061491b0e011137451 (patch)
tree5ebfc1f45d216a5c14a90492563599e6969eab4d /core/src/mouse
parent41836dd80d0534608e7aedfbf2319c540a23de1a (diff)
parent21bd51426d900e271206f314e0c915dd41065521 (diff)
downloadiced-633f405f3f78bc7f82d2b2061491b0e011137451.tar.gz
iced-633f405f3f78bc7f82d2b2061491b0e011137451.tar.bz2
iced-633f405f3f78bc7f82d2b2061491b0e011137451.zip
Merge remote-tracking branch 'origin/master' into feat/multi-window-support
# Conflicts: # Cargo.toml # core/src/window/icon.rs # core/src/window/id.rs # core/src/window/position.rs # core/src/window/settings.rs # examples/integration/src/main.rs # examples/integration_opengl/src/main.rs # glutin/src/application.rs # native/src/subscription.rs # native/src/window.rs # runtime/src/window/action.rs # src/lib.rs # src/window.rs # winit/Cargo.toml # winit/src/application.rs # winit/src/icon.rs # winit/src/settings.rs # winit/src/window.rs
Diffstat (limited to 'core/src/mouse')
-rw-r--r--core/src/mouse/button.rs2
-rw-r--r--core/src/mouse/click.rs76
-rw-r--r--core/src/mouse/cursor.rs52
-rw-r--r--core/src/mouse/interaction.rs10
4 files changed, 132 insertions, 8 deletions
diff --git a/core/src/mouse/button.rs b/core/src/mouse/button.rs
index aeb8a55d..3eec7f42 100644
--- a/core/src/mouse/button.rs
+++ b/core/src/mouse/button.rs
@@ -11,5 +11,5 @@ pub enum Button {
Middle,
/// Some other button.
- Other(u8),
+ Other(u16),
}
diff --git a/core/src/mouse/click.rs b/core/src/mouse/click.rs
new file mode 100644
index 00000000..4a7d796c
--- /dev/null
+++ b/core/src/mouse/click.rs
@@ -0,0 +1,76 @@
+//! Track mouse clicks.
+use crate::time::Instant;
+use crate::Point;
+
+/// A mouse click.
+#[derive(Debug, Clone, Copy)]
+pub struct Click {
+ kind: Kind,
+ position: Point,
+ time: Instant,
+}
+
+/// The kind of mouse click.
+#[derive(Debug, Clone, Copy)]
+pub enum Kind {
+ /// A single click
+ Single,
+
+ /// A double click
+ Double,
+
+ /// A triple click
+ Triple,
+}
+
+impl Kind {
+ fn next(&self) -> Kind {
+ match self {
+ Kind::Single => Kind::Double,
+ Kind::Double => Kind::Triple,
+ Kind::Triple => Kind::Double,
+ }
+ }
+}
+
+impl Click {
+ /// Creates a new [`Click`] with the given position and previous last
+ /// [`Click`].
+ pub fn new(position: Point, previous: Option<Click>) -> Click {
+ let time = Instant::now();
+
+ let kind = if let Some(previous) = previous {
+ if previous.is_consecutive(position, time) {
+ previous.kind.next()
+ } else {
+ Kind::Single
+ }
+ } else {
+ Kind::Single
+ };
+
+ Click {
+ kind,
+ position,
+ time,
+ }
+ }
+
+ /// Returns the [`Kind`] of [`Click`].
+ pub fn kind(&self) -> Kind {
+ self.kind
+ }
+
+ fn is_consecutive(&self, new_position: Point, time: Instant) -> bool {
+ let duration = if time > self.time {
+ Some(time - self.time)
+ } else {
+ None
+ };
+
+ self.position == new_position
+ && duration
+ .map(|duration| duration.as_millis() <= 300)
+ .unwrap_or(false)
+ }
+}
diff --git a/core/src/mouse/cursor.rs b/core/src/mouse/cursor.rs
new file mode 100644
index 00000000..203526e9
--- /dev/null
+++ b/core/src/mouse/cursor.rs
@@ -0,0 +1,52 @@
+use crate::{Point, Rectangle, Vector};
+
+/// The mouse cursor state.
+#[derive(Debug, Clone, Copy, PartialEq, Default)]
+pub enum Cursor {
+ /// The cursor has a defined position.
+ Available(Point),
+
+ /// The cursor is currently unavailable (i.e. out of bounds or busy).
+ #[default]
+ 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()
+ }
+}
diff --git a/core/src/mouse/interaction.rs b/core/src/mouse/interaction.rs
index 664147a7..072033fd 100644
--- a/core/src/mouse/interaction.rs
+++ b/core/src/mouse/interaction.rs
@@ -1,7 +1,8 @@
/// The interaction of a mouse cursor.
-#[derive(Debug, Eq, PartialEq, Clone, Copy, PartialOrd, Ord)]
+#[derive(Debug, Eq, PartialEq, Clone, Copy, PartialOrd, Ord, Default)]
#[allow(missing_docs)]
pub enum Interaction {
+ #[default]
Idle,
Pointer,
Grab,
@@ -11,10 +12,5 @@ pub enum Interaction {
Grabbing,
ResizingHorizontally,
ResizingVertically,
-}
-
-impl Default for Interaction {
- fn default() -> Interaction {
- Interaction::Idle
- }
+ NotAllowed,
}