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 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
package ansi
import (
"fmt"
)
// MouseButton represents the button that was pressed during a mouse message.
type MouseButton byte
// Mouse event buttons
//
// This is based on X11 mouse button codes.
//
// 1 = left button
// 2 = middle button (pressing the scroll wheel)
// 3 = right button
// 4 = turn scroll wheel up
// 5 = turn scroll wheel down
// 6 = push scroll wheel left
// 7 = push scroll wheel right
// 8 = 4th button (aka browser backward button)
// 9 = 5th button (aka browser forward button)
// 10
// 11
//
// Other buttons are not supported.
const (
MouseNone MouseButton = iota
MouseButton1
MouseButton2
MouseButton3
MouseButton4
MouseButton5
MouseButton6
MouseButton7
MouseButton8
MouseButton9
MouseButton10
MouseButton11
MouseLeft = MouseButton1
MouseMiddle = MouseButton2
MouseRight = MouseButton3
MouseWheelUp = MouseButton4
MouseWheelDown = MouseButton5
MouseWheelLeft = MouseButton6
MouseWheelRight = MouseButton7
MouseBackward = MouseButton8
MouseForward = MouseButton9
MouseRelease = MouseNone
)
var mouseButtons = map[MouseButton]string{
MouseNone: "none",
MouseLeft: "left",
MouseMiddle: "middle",
MouseRight: "right",
MouseWheelUp: "wheelup",
MouseWheelDown: "wheeldown",
MouseWheelLeft: "wheelleft",
MouseWheelRight: "wheelright",
MouseBackward: "backward",
MouseForward: "forward",
MouseButton10: "button10",
MouseButton11: "button11",
}
// String returns a string representation of the mouse button.
func (b MouseButton) String() string {
return mouseButtons[b]
}
// EncodeMouseButton returns a byte representing a mouse button.
// The button is a bitmask of the following leftmost values:
//
// - The first two bits are the button number:
// 0 = left button, wheel up, or button no. 8 aka (backwards)
// 1 = middle button, wheel down, or button no. 9 aka (forwards)
// 2 = right button, wheel left, or button no. 10
// 3 = release event, wheel right, or button no. 11
//
// - The third bit indicates whether the shift key was pressed.
//
// - The fourth bit indicates the alt key was pressed.
//
// - The fifth bit indicates the control key was pressed.
//
// - The sixth bit indicates motion events. Combined with button number 3, i.e.
// release event, it represents a drag event.
//
// - The seventh bit indicates a wheel event.
//
// - The eighth bit indicates additional buttons.
//
// If button is [MouseNone], and motion is false, this returns a release event.
// If button is undefined, this function returns 0xff.
func EncodeMouseButton(b MouseButton, motion, shift, alt, ctrl bool) (m byte) {
// mouse bit shifts
const (
bitShift = 0b0000_0100
bitAlt = 0b0000_1000
bitCtrl = 0b0001_0000
bitMotion = 0b0010_0000
bitWheel = 0b0100_0000
bitAdd = 0b1000_0000 // additional buttons 8-11
bitsMask = 0b0000_0011
)
if b == MouseNone {
m = bitsMask
} else if b >= MouseLeft && b <= MouseRight {
m = byte(b - MouseLeft)
} else if b >= MouseWheelUp && b <= MouseWheelRight {
m = byte(b - MouseWheelUp)
m |= bitWheel
} else if b >= MouseBackward && b <= MouseButton11 {
m = byte(b - MouseBackward)
m |= bitAdd
} else {
m = 0xff // invalid button
}
if shift {
m |= bitShift
}
if alt {
m |= bitAlt
}
if ctrl {
m |= bitCtrl
}
if motion {
m |= bitMotion
}
return m
}
// x10Offset is the offset for X10 mouse events.
// See https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking
const x10Offset = 32
// MouseX10 returns an escape sequence representing a mouse event in X10 mode.
// Note that this requires the terminal support X10 mouse modes.
//
// CSI M Cb Cx Cy
//
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking
func MouseX10(b byte, x, y int) string {
return "\x1b[M" + string(b+x10Offset) + string(byte(x)+x10Offset+1) + string(byte(y)+x10Offset+1)
}
// MouseSgr returns an escape sequence representing a mouse event in SGR mode.
//
// CSI < Cb ; Cx ; Cy M
// CSI < Cb ; Cx ; Cy m (release)
//
// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking
func MouseSgr(b byte, x, y int, release bool) string {
s := 'M'
if release {
s = 'm'
}
if x < 0 {
x = -x
}
if y < 0 {
y = -y
}
return fmt.Sprintf("\x1b[<%d;%d;%d%c", b, x+1, y+1, s)
}
|