Skip to main content

rusty_bubbletea/
mouse.rs

1//! Cleanroom Rust port of upstream Go source file: `mouse.go`
2//! Upstream Target Tag / Version: `v2.0.8`
3//!
4//! <public-docs>
5//! # Mouse Messages & Events
6//!
7//! Mouse button definitions, `Mouse` struct, and typed mouse messages (`MouseClickMsg`, `MouseReleaseMsg`, `MouseWheelMsg`, `MouseMotionMsg`).
8//! </public-docs>
9
10use crate::key::KeyMod;
11use std::fmt;
12
13/// MouseButton represents the button that was pressed during a mouse message.
14///
15/// This is based on X11 mouse button codes:
16///
17/// - `1` = left button
18/// - `2` = middle button (pressing the scroll wheel)
19/// - `3` = right button
20/// - `4` = turn scroll wheel up
21/// - `5` = turn scroll wheel down
22/// - `6` = push scroll wheel left
23/// - `7` = push scroll wheel right
24/// - `8` = 4th button (aka browser backward button)
25/// - `9` = 5th button (aka browser forward button)
26///
27/// Other buttons are not supported.
28#[derive(Debug, Clone, Copy, PartialEq, Eq)]
29pub enum MouseButton {
30    /// No button.
31    MouseNone = 0,
32    /// Left mouse button.
33    MouseLeft = 1,
34    /// Middle mouse button (scroll wheel press).
35    MouseMiddle = 2,
36    /// Right mouse button.
37    MouseRight = 3,
38    /// Scroll wheel up.
39    MouseWheelUp = 4,
40    /// Scroll wheel down.
41    MouseWheelDown = 5,
42    /// Scroll wheel left.
43    MouseWheelLeft = 6,
44    /// Scroll wheel right.
45    MouseWheelRight = 7,
46    /// Browser backward button.
47    MouseBackward = 8,
48    /// Browser forward button.
49    MouseForward = 9,
50    /// Button 10.
51    MouseButton10 = 10,
52    /// Button 11.
53    MouseButton11 = 11,
54}
55
56/// Mouse represents a mouse event. Use the specific message types
57/// (`MouseClickMsg`, `MouseReleaseMsg`, etc.) to match individual events.
58///
59/// The X and Y coordinates are zero-based, with (0,0) being the upper left
60/// corner of the terminal.
61#[derive(Debug, Clone, PartialEq, Eq)]
62pub struct Mouse {
63    /// Zero-based X coordinate (column).
64    pub x: usize,
65    /// Zero-based Y coordinate (row).
66    pub y: usize,
67    /// Button pressed/released.
68    pub button: MouseButton,
69    /// Key modifiers active.
70    pub mod_keys: KeyMod,
71}
72
73impl fmt::Display for Mouse {
74    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75        write!(f, "({};{}) {:?}", self.x, self.y, self.button)
76    }
77}
78
79/// MouseClickMsg represents a mouse button click message.
80#[derive(Debug, Clone, PartialEq, Eq)]
81pub struct MouseClickMsg(pub Mouse);
82
83impl fmt::Display for MouseClickMsg {
84    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85        write!(f, "{}", self.0)
86    }
87}
88
89/// MouseReleaseMsg represents a mouse button release message.
90#[derive(Debug, Clone, PartialEq, Eq)]
91pub struct MouseReleaseMsg(pub Mouse);
92
93impl fmt::Display for MouseReleaseMsg {
94    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95        write!(f, "{}", self.0)
96    }
97}
98
99/// MouseWheelMsg represents a mouse wheel message.
100#[derive(Debug, Clone, PartialEq, Eq)]
101pub struct MouseWheelMsg(pub Mouse);
102
103impl fmt::Display for MouseWheelMsg {
104    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105        write!(f, "{}", self.0)
106    }
107}
108
109/// MouseMotionMsg represents a mouse motion message.
110#[derive(Debug, Clone, PartialEq, Eq)]
111pub struct MouseMotionMsg(pub Mouse);
112
113impl fmt::Display for MouseMotionMsg {
114    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115        if self.0.button != MouseButton::MouseNone {
116            write!(f, "{}+motion", self.0)
117        } else {
118            write!(f, "{} motion", self.0)
119        }
120    }
121}
122
123/// MouseMsg enum abstraction covering click, release, wheel, and motion messages.
124#[derive(Debug, Clone, PartialEq, Eq)]
125pub enum MouseMsg {
126    /// Mouse click event.
127    Click(MouseClickMsg),
128    /// Mouse release event.
129    Release(MouseReleaseMsg),
130    /// Mouse wheel event.
131    Wheel(MouseWheelMsg),
132    /// Mouse motion event.
133    Motion(MouseMotionMsg),
134}
135
136impl MouseMsg {
137    /// Returns reference to underlying Mouse struct.
138    pub fn mouse(&self) -> &Mouse {
139        match self {
140            MouseMsg::Click(m) => &m.0,
141            MouseMsg::Release(m) => &m.0,
142            MouseMsg::Wheel(m) => &m.0,
143            MouseMsg::Motion(m) => &m.0,
144        }
145    }
146}
147
148impl fmt::Display for MouseMsg {
149    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
150        write!(f, "{}", self.mouse())
151    }
152}