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}