okami.mom/ultraviolet
git clone https://git.nkp.pet/okami.mom/ultraviolet
6603726
upstream
1package uv 2 3import ( 4"github.com/charmbracelet/x/ansi" 5) 6 7// MouseMode represents the mouse tracking mode for the terminal. 8type MouseMode uint8 9 10// Mouse tracking modes. 11// 12// These determine which mouse events the terminal reports. 13const ( 14MouseModeNone MouseMode = iota // Disable mouse tracking. 15MouseModePress // Press only (DEC mode 9). Reports button press events. 16MouseModeClick // Click tracking (DEC mode 1000). Reports button press and release. 17MouseModeDrag // Drag tracking (DEC mode 1002). Reports press, release, and drag. 18MouseModeMotion // Motion tracking (DEC mode 1003). Reports all mouse events including motion. 19) 20 21// MouseEncoding represents the encoding used for mouse events. 22type MouseEncoding uint8 23 24// Mouse encodings. 25// 26// These determine how mouse coordinates and buttons are encoded in the 27// terminal's escape sequences. The encoding is only meaningful when mouse 28// tracking is enabled via [MouseMode]. 29const ( 30MouseEncodingLegacy MouseEncoding = iota // Legacy X10-compatible encoding. Coordinates limited to 223. 31MouseEncodingSGR // SGR encoding (DEC mode 1006). No coordinate limit, distinguishes press/release. 32MouseEncodingSGRPixel // SGR-pixel encoding (DEC mode 1016). Reports pixel coordinates. 33 34// TODO: support these additional encodings in the future. 35// MouseEncodingUTF8 // UTF-8 encoding (DEC mode 1005). Coordinates limited to 223. 36// MouseEncodingUrxvt // urxvt encoding (DEC mode 1015). No coordinate limit. 37// MouseEncodingSGRPixel // SGR-pixel encoding (DEC mode 1016). Reports pixel coordinates. 38) 39 40// MouseButton represents the button that was pressed during a mouse message. 41type MouseButton = ansi.MouseButton 42 43// Mouse event buttons 44// 45// This is based on X11 mouse button codes. 46// 47// 1 = left button 48// 2 = middle button (pressing the scroll wheel) 49// 3 = right button 50// 4 = turn scroll wheel up 51// 5 = turn scroll wheel down 52// 6 = push scroll wheel left 53// 7 = push scroll wheel right 54// 8 = 4th button (aka browser backward button) 55// 9 = 5th button (aka browser forward button) 56// 10 57// 11 58// 59// Other buttons are not supported. 60const ( 61MouseNone = ansi .MouseNone 62MouseLeft = ansi .MouseLeft 63MouseMiddle = ansi .MouseMiddle 64MouseRight = ansi .MouseRight 65MouseWheelUp = ansi .MouseWheelUp 66MouseWheelDown = ansi .MouseWheelDown 67MouseWheelLeft = ansi .MouseWheelLeft 68MouseWheelRight = ansi .MouseWheelRight 69MouseBackward = ansi .MouseBackward 70MouseForward = ansi .MouseForward 71MouseButton10 = ansi .MouseButton10 72MouseButton11 = ansi .MouseButton11 73) 74 75// Mouse represents a Mouse message. Use [MouseEvent] to represent all mouse 76// messages. 77// 78// The X and Y coordinates are zero-based, with (0,0) being the upper left 79// corner of the terminal. When using [MouseEncodingSGRPixel] (DEC mode 1016), 80// X and Y are in pixel coordinates; otherwise they are in cell coordinates. 81// 82// // Catch all mouse events 83// switch Event := Event.(type) { 84// case MouseEvent: 85// m := Event.Mouse() 86// fmt.Println("Mouse event:", m.X, m.Y, m) 87// } 88// 89// // Only catch mouse click events 90// switch Event := Event.(type) { 91// case MouseClickEvent: 92// fmt.Println("Mouse click event:", Event.X, Event.Y, Event) 93// } 94type Mouse struct { 95X ,Y int 96Button MouseButton 97Mod KeyMod 98} 99 100// String returns a string representation of the mouse message. 101func (m Mouse )String () (s string ) { 102if m .Mod .Contains (ModCtrl ) { 103s += "ctrl+" 104 } 105if m .Mod .Contains (ModAlt ) { 106s += "alt+" 107 } 108if m .Mod .Contains (ModShift ) { 109s += "shift+" 110 } 111 112str := m .Button .String () 113if str == "" { 114s += "unknown" 115 }else if str != "none" {// motion events don't have a button 116s += str 117 } 118 119return s 120} 121 122// MousePixelToCell converts a mouse event with pixel coordinates to cell 123// coordinates. 124// 125// This is only meaningful when using [MouseEncodingSGRPixel] encoding, which 126// reports mouse coordinates in pixels rather than cell units. The conversion 127// is based on the terminal's reported pixel dimensions and cell dimensions. 128// 129// On Windows, or other platforms where [Terminal.GetWinsize] doesn't report 130// pixel dimensions, you can query for the terminal window pixel dimensions via 131// [ansi.WindowOp](4) and get back a [PixelSizeEvent] with the pixel 132// dimensions. You can then construct a [Winsize] struct with the pixel 133// dimensions and the cell dimensions from [Terminal.GetWinsize] and pass it to 134// this function. 135func MousePixelToCell (m Mouse ,ws * Winsize )Mouse { 136var col ,row int 137if ws .Xpixel > 0 { 138col = m .X * int (ws .Col )/ int (ws .Xpixel ) 139 } 140if ws .Ypixel > 0 { 141row = m .Y * int (ws .Row )/ int (ws .Ypixel ) 142 } 143 144return Mouse { 145X :col , 146Y :row , 147Button :m .Button , 148Mod :m .Mod , 149 } 150}