Skip to content

Commit

Permalink
Add support for more mouse buttons and tracking holding.
Browse files Browse the repository at this point in the history
  • Loading branch information
xStrom committed Apr 30, 2020
1 parent 40cbcee commit 158ad19
Show file tree
Hide file tree
Showing 11 changed files with 557 additions and 228 deletions.
2 changes: 1 addition & 1 deletion druid-shell/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub use hotkey::{HotKey, KeyCompare, RawMods, SysMods};
pub use keyboard::{KeyEvent, KeyModifiers};
pub use keycodes::KeyCode;
pub use menu::Menu;
pub use mouse::{Cursor, MouseButton, MouseEvent};
pub use mouse::{Cursor, MouseButton, MouseButtons, MouseEvent};
pub use window::{
IdleHandle, IdleToken, Text, TimerToken, WinHandler, WindowBuilder, WindowHandle,
};
194 changes: 181 additions & 13 deletions druid-shell/src/mouse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,50 +18,218 @@ use crate::kurbo::Point;

use crate::keyboard::KeyModifiers;

/// The state of the mouse for a click, mouse-up, or move event.
/// Information about the mouse event.
#[derive(Debug, Clone, PartialEq)]
pub struct MouseEvent {
/// The location of the mouse in the current window.
///
/// This is in px units, that is, adjusted for hi-dpi.
/// This is in px units not device pixels, that is, adjusted for hi-dpi.
pub pos: Point,
/// Keyboard modifiers at the time of the mouse event.
/// Mouse buttons being held down during a move or after a click event.
/// Thus it will contain the `button` that triggered a mouse-down event,
/// and it will not contain the `button` that triggered a mouse-up event.
pub buttons: MouseButtons,
/// Keyboard modifiers at the time of the event.
pub mods: KeyModifiers,
/// The number of mouse clicks associated with this event. This will always
/// be `0` for a mouse-up event.
pub count: u32,
/// The currently pressed button in the case of a move or click event,
/// or the released button in the case of a mouse-up event.
/// be `0` for a mouse-up and mouse-move events.
pub count: u8,
/// The button that was pressed down in the case of mouse-down,
/// or the button that was released in the case of mouse-up.
/// This will always be `MouseButton::None` in the case of mouse-move.
pub button: MouseButton,
}

/// An indicator of which mouse button was pressed.
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
#[repr(u8)]
pub enum MouseButton {
/// Left mouse button.
Left,
/// Middle mouse button.
Middle,
/// Right mouse button.
Right,
/// Middle mouse button.
Middle,
/// First X button.
X1,
/// Second X button.
X2,
/// No mouse button.
None,
}

impl MouseButton {
/// Returns `true` if this is the left mouse button.
#[inline(always)]
/// Returns `true` if this is [`MouseButton::Left`].
///
/// [`MouseButton::Left`]: #variant.Left
#[inline]
pub fn is_left(self) -> bool {
self == MouseButton::Left
}

/// Returns `true` if this is the right mouse button.
#[inline(always)]
/// Returns `true` if this is [`MouseButton::Right`].
///
/// [`MouseButton::Right`]: #variant.Right
#[inline]
pub fn is_right(self) -> bool {
self == MouseButton::Right
}

/// Returns `true` if this is [`MouseButton::Middle`].
///
/// [`MouseButton::Middle`]: #variant.Middle
#[inline]
pub fn is_middle(self) -> bool {
self == MouseButton::Middle
}

/// Returns `true` if this is [`MouseButton::X1`].
///
/// [`MouseButton::X1`]: #variant.X1
#[inline]
pub fn is_x1(self) -> bool {
self == MouseButton::X1
}

/// Returns `true` if this is [`MouseButton::X2`].
///
/// [`MouseButton::X2`]: #variant.X2
#[inline]
pub fn is_x2(self) -> bool {
self == MouseButton::X2
}
}

/// A set of [`MouseButton`]s.
///
/// [`MouseButton`]: enum.MouseButton.html
#[derive(PartialEq, Eq, Clone, Copy, Default)]
pub struct MouseButtons(u8);

impl MouseButtons {
/// Create a new empty set.
#[inline]
pub fn new() -> MouseButtons {
MouseButtons(0)
}

/// Add the `button` to the set.
#[inline]
pub fn add(&mut self, button: MouseButton) {
self.0 |= 1 << button as u8;
}

/// Remove the `button` from the set.
#[inline]
pub fn remove(&mut self, button: MouseButton) {
self.0 &= !(1 << button as u8);
}

/// Builder-style method for adding the `button` to the set.
#[inline]
pub fn with(mut self, button: MouseButton) -> MouseButtons {
self.0 |= 1 << button as u8;
self
}

/// Builder-style method for removing the `button` from the set.
#[inline]
pub fn without(mut self, button: MouseButton) -> MouseButtons {
self.0 &= !(1 << button as u8);
self
}

/// Returns `true` if the `button` is in the set.
#[inline]
pub fn has(self, button: MouseButton) -> bool {
(self.0 & (1 << button as u8)) != 0
}

/// Returns `true` if any button is in the set.
#[inline]
pub fn has_any(self) -> bool {
self.0 != 0
}

/// Returns `true` if the set is empty.
#[inline]
pub fn has_none(self) -> bool {
self.0 == 0
}

/// Returns `true` if all the `buttons` are in the set.
#[inline]
pub fn has_all(self, buttons: MouseButtons) -> bool {
self.0 & buttons.0 == buttons.0
}

/// Returns `true` if [`MouseButton::Left`] is in the set.
///
/// [`MouseButton::Left`]: enum.MouseButton.html#variant.Left
#[inline]
pub fn has_left(self) -> bool {
self.has(MouseButton::Left)
}

/// Returns `true` if [`MouseButton::Right`] is in the set.
///
/// [`MouseButton::Right`]: enum.MouseButton.html#variant.Right
#[inline]
pub fn has_right(self) -> bool {
self.has(MouseButton::Right)
}

/// Returns `true` if [`MouseButton::Middle`] is in the set.
///
/// [`MouseButton::Middle`]: enum.MouseButton.html#variant.Middle
#[inline]
pub fn has_middle(self) -> bool {
self.has(MouseButton::Middle)
}

/// Returns `true` if [`MouseButton::X1`] is in the set.
///
/// [`MouseButton::X1`]: enum.MouseButton.html#variant.X1
#[inline]
pub fn has_x1(self) -> bool {
self.has(MouseButton::X1)
}

/// Returns `true` if [`MouseButton::X2`] is in the set.
///
/// [`MouseButton::X2`]: enum.MouseButton.html#variant.X2
#[inline]
pub fn has_x2(self) -> bool {
self.has(MouseButton::X2)
}

/// Adds all the [`MouseButton`]s in `other` to the set.
///
/// [`MouseButton`]: enum.MouseButton.html
pub fn extend(&mut self, other: MouseButtons) {
self.0 |= other.0;
}

/// Returns a union of the values in `self` and `other`.
///
/// [`MouseButton`]: enum.MouseButton.html
#[inline]
pub fn union(mut self, other: MouseButtons) -> MouseButtons {
self.0 |= other.0;
self
}

/// Clear the set.
#[inline]
pub fn clear(&mut self) {
self.0 = 0;
}
}

impl std::fmt::Debug for MouseButtons {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "MouseButtons({:06b})", self.0)
}
}

//NOTE: this currently only contains cursors that are included by default on
Expand Down
Loading

0 comments on commit 158ad19

Please sign in to comment.