1use vt100::MouseProtocolEncoding;
2
3#[derive(Debug, Clone, Copy, PartialEq)]
5pub enum TerminalMouseButton {
6 Left,
7 Middle,
8 Right,
9}
10
11impl TerminalMouseButton {
12 fn code(self) -> u8 {
14 match self {
15 Self::Left => 0,
16 Self::Middle => 1,
17 Self::Right => 2,
18 }
19 }
20}
21
22pub fn encode_mouse_press(
24 row: usize,
25 col: usize,
26 button: TerminalMouseButton,
27 encoding: MouseProtocolEncoding,
28) -> String {
29 match encoding {
30 MouseProtocolEncoding::Sgr => {
31 let sgr_row = row.saturating_add(1);
32 let sgr_col = col.saturating_add(1);
33 format!("\x1b[<{};{};{}M", button.code(), sgr_col, sgr_row)
34 }
35 _ => {
36 let button_byte = button.code().saturating_add(32);
37 let col_byte = col.saturating_add(1).min(255) as u8;
38 let row_byte = row.saturating_add(1).min(255) as u8;
39 format!(
40 "\x1b[M{}{}{}",
41 button_byte as char, col_byte as char, row_byte as char
42 )
43 }
44 }
45}
46
47pub fn encode_mouse_release(
49 row: usize,
50 col: usize,
51 button: TerminalMouseButton,
52 encoding: MouseProtocolEncoding,
53) -> String {
54 match encoding {
55 MouseProtocolEncoding::Sgr => {
56 let sgr_row = row.saturating_add(1);
58 let sgr_col = col.saturating_add(1);
59 format!("\x1b[<{};{};{}m", button.code(), sgr_col, sgr_row)
60 }
61 _ => {
62 let button_byte = 35u8; let col_byte = col.saturating_add(1).min(255) as u8;
65 let row_byte = row.saturating_add(1).min(255) as u8;
66 format!(
67 "\x1b[M{}{}{}",
68 button_byte as char, col_byte as char, row_byte as char
69 )
70 }
71 }
72}
73
74pub fn encode_mouse_move(
81 row: usize,
82 col: usize,
83 button: Option<TerminalMouseButton>,
84 encoding: MouseProtocolEncoding,
85) -> String {
86 let code = match button {
88 Some(b) => b.code() + 32,
89 None => 3 + 32, };
91
92 match encoding {
93 MouseProtocolEncoding::Sgr => {
94 let sgr_row = row.saturating_add(1);
95 let sgr_col = col.saturating_add(1);
96 format!("\x1b[<{};{};{}M", code, sgr_col, sgr_row)
97 }
98 _ => {
99 let button_byte = code.saturating_add(32);
100 let col_byte = col.saturating_add(1).min(255) as u8;
101 let row_byte = row.saturating_add(1).min(255) as u8;
102 format!(
103 "\x1b[M{}{}{}",
104 button_byte as char, col_byte as char, row_byte as char
105 )
106 }
107 }
108}
109
110pub fn encode_wheel_event(
114 row: usize,
115 col: usize,
116 delta_y: f64,
117 encoding: MouseProtocolEncoding,
118) -> String {
119 match encoding {
121 MouseProtocolEncoding::Sgr => {
122 let button = if delta_y > 0.0 { 64 } else { 65 };
123 let sgr_row = row.saturating_add(1);
124 let sgr_col = col.saturating_add(1);
125 format!("\x1b[<{};{};{}M", button, sgr_col, sgr_row)
127 }
128 _ => {
130 let button_byte = if delta_y > 0.0 { 96u8 } else { 97u8 };
135 let col_byte = col.saturating_add(1).min(255) as u8;
136 let row_byte = row.saturating_add(1).min(255) as u8;
137 format!(
138 "\x1b[M{}{}{}",
139 button_byte as char, col_byte as char, row_byte as char
140 )
141 }
142 }
143}