Skip to content

Commit

Permalink
Add support for more mouse buttons.
Browse files Browse the repository at this point in the history
  • Loading branch information
xStrom committed Apr 19, 2020
1 parent d8b6e14 commit 04b5950
Show file tree
Hide file tree
Showing 17 changed files with 576 additions and 219 deletions.
10 changes: 5 additions & 5 deletions druid-shell/examples/shello.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ use druid_shell::kurbo::{Line, Rect, Vec2};
use druid_shell::piet::{Color, RenderContext};

use druid_shell::{
Application, Cursor, FileDialogOptions, FileSpec, HotKey, KeyEvent, KeyModifiers, Menu,
MouseEvent, SysMods, TimerToken, WinHandler, WindowBuilder, WindowHandle,
Application, ClickEvent, Cursor, FileDialogOptions, FileSpec, HotKey, KeyEvent, KeyModifiers,
Menu, MoveEvent, SysMods, TimerToken, WinHandler, WindowBuilder, WindowHandle,
};

const BG_COLOR: Color = Color::rgb8(0x27, 0x28, 0x22);
Expand Down Expand Up @@ -75,16 +75,16 @@ impl WinHandler for HelloState {
println!("mouse_wheel {:?} {:?}", delta, mods);
}

fn mouse_move(&mut self, event: &MouseEvent) {
fn mouse_move(&mut self, event: &MoveEvent) {
self.handle.set_cursor(&Cursor::Arrow);
println!("mouse_move {:?}", event);
}

fn mouse_down(&mut self, event: &MouseEvent) {
fn mouse_down(&mut self, event: &ClickEvent) {
println!("mouse_down {:?}", event);
}

fn mouse_up(&mut self, event: &MouseEvent) {
fn mouse_up(&mut self, event: &ClickEvent) {
println!("mouse_up {:?}", event);
}

Expand Down
2 changes: 1 addition & 1 deletion druid-shell/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,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::{ClickEvent, Cursor, MouseButton, MouseButtons, MoveEvent};
pub use window::{
IdleHandle, IdleToken, Text, TimerToken, WinHandler, WindowBuilder, WindowHandle,
};
217 changes: 204 additions & 13 deletions druid-shell/src/mouse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,50 +18,241 @@ 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 move event.
#[derive(Debug, Clone, PartialEq)]
pub struct MouseEvent {
pub struct MoveEvent {
/// 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 at the time of the event.
pub buttons: MouseButtons,
/// Keyboard modifiers at the time of the event.
pub mods: KeyModifiers,
}

/// Information about the mouse click event.
#[derive(Debug, Clone, PartialEq)]
pub struct ClickEvent {
/// The location of the mouse in the current window.
///
/// This is in px units not device pixels, that is, adjusted for hi-dpi.
pub pos: Point,
/// Mouse buttons being held down after the 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.
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.
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,
/// Some other unknown button.
Other,
}

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
}

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

/// 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 {
// TODO: Does this compile down well enough or should we do the bit work here?
self.add(button);
self
}

/// Builder-style method for removing the `button` from the set.
#[inline]
pub fn without(mut self, button: MouseButton) -> MouseButtons {
self.remove(button);
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 [`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)
}

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

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

/// Builder-style method for adding all the [`MouseButton`]s in `other`.
///
/// [`MouseButton`]: enum.MouseButton.html
#[inline]
pub fn with_other(mut self, other: MouseButtons) -> MouseButtons {
self.union(other);
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 04b5950

Please sign in to comment.