forked from charmbracelet/bubbletea
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mouse.go
108 lines (95 loc) · 1.92 KB
/
mouse.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package tea
import "errors"
type MouseMsg MouseEvent
// MouseEvent represents a mouse event, which could be a click, a scroll wheel
// movement, a cursor movement, or a combination.
type MouseEvent struct {
X int
Y int
Type MouseEventType
Alt bool
Ctrl bool
}
// String returns a string representation of a mouse event.
func (m MouseEvent) String() (s string) {
if m.Ctrl {
s += "ctrl+"
}
if m.Alt {
s += "alt+"
}
s += mouseEventTypes[m.Type]
return s
}
// MouseEventType indicates the type of mouse event occurring.
type MouseEventType int
const (
MouseUnknown MouseEventType = iota
MouseLeft
MouseRight
MouseMiddle
MouseRelease
MouseWheelUp
MouseWheelDown
MouseMotion
)
var mouseEventTypes = map[MouseEventType]string{
MouseUnknown: "unknown",
MouseLeft: "left",
MouseRight: "right",
MouseMiddle: "middle",
MouseRelease: "release",
MouseWheelUp: "wheel up",
MouseWheelDown: "wheel down",
MouseMotion: "motion",
}
// Parse an X10-encoded mouse event; the simplest kind. The last release of
// X10 was December 1986, by the way.
//
// X10 mouse events look like:
//
// ESC [M Cb Cx Cy
//
func parseX10MouseEvent(buf []byte) (m MouseEvent, err error) {
if len(buf) != 6 || string(buf[:3]) != "\x1b[M" {
return m, errors.New("not an X10 mouse event")
}
e := buf[3] - 32
switch e {
case 35:
m.Type = MouseMotion
case 64:
m.Type = MouseWheelUp
case 65:
m.Type = MouseWheelDown
default:
switch e & 3 {
case 0:
if e&64 != 0 {
m.Type = MouseWheelUp
} else {
m.Type = MouseLeft
}
case 1:
if e&64 != 0 {
m.Type = MouseWheelDown
} else {
m.Type = MouseMiddle
}
case 2:
m.Type = MouseRight
case 3:
m.Type = MouseRelease
}
}
if e&8 != 0 {
m.Alt = true
}
if e&16 != 0 {
m.Ctrl = true
}
// (1,1) is the upper left. We subtract 1 to normalize it to (0,0).
m.X = int(buf[4]) - 32 - 1
m.Y = int(buf[5]) - 32 - 1
return m, nil
}