1
0
mirror of https://github.com/mum4k/termdash.git synced 2025-04-25 13:48:50 +08:00
2020-02-29 02:02:05 -05:00

179 lines
5.6 KiB
Go

package tcell
import (
"image"
"github.com/gdamore/tcell"
"github.com/mum4k/termdash/keyboard"
"github.com/mum4k/termdash/mouse"
"github.com/mum4k/termdash/terminal/terminalapi"
)
// tcell representation of the space key
var tcellSpaceKey = tcell.Key(' ')
// tcellToTd maps tcell key values to the termdash format.
var tcellToTd = map[tcell.Key]keyboard.Key{
tcellSpaceKey: keyboard.KeySpace,
tcell.KeyF1: keyboard.KeyF1,
tcell.KeyF2: keyboard.KeyF2,
tcell.KeyF3: keyboard.KeyF3,
tcell.KeyF4: keyboard.KeyF4,
tcell.KeyF5: keyboard.KeyF5,
tcell.KeyF6: keyboard.KeyF6,
tcell.KeyF7: keyboard.KeyF7,
tcell.KeyF8: keyboard.KeyF8,
tcell.KeyF9: keyboard.KeyF9,
tcell.KeyF10: keyboard.KeyF10,
tcell.KeyF11: keyboard.KeyF11,
tcell.KeyF12: keyboard.KeyF12,
tcell.KeyInsert: keyboard.KeyInsert,
tcell.KeyDelete: keyboard.KeyDelete,
tcell.KeyHome: keyboard.KeyHome,
tcell.KeyEnd: keyboard.KeyEnd,
tcell.KeyPgUp: keyboard.KeyPgUp,
tcell.KeyPgDn: keyboard.KeyPgDn,
tcell.KeyUp: keyboard.KeyArrowUp,
tcell.KeyDown: keyboard.KeyArrowDown,
tcell.KeyLeft: keyboard.KeyArrowLeft,
tcell.KeyRight: keyboard.KeyArrowRight,
tcell.KeyEnter: keyboard.KeyEnter,
tcell.KeyCtrlA: keyboard.KeyCtrlA,
tcell.KeyCtrlB: keyboard.KeyCtrlB,
tcell.KeyCtrlC: keyboard.KeyCtrlC,
tcell.KeyCtrlD: keyboard.KeyCtrlD,
tcell.KeyCtrlE: keyboard.KeyCtrlE,
tcell.KeyCtrlF: keyboard.KeyCtrlF,
tcell.KeyCtrlG: keyboard.KeyCtrlG,
tcell.KeyCtrlJ: keyboard.KeyCtrlJ,
tcell.KeyCtrlK: keyboard.KeyCtrlK,
tcell.KeyCtrlL: keyboard.KeyCtrlL,
tcell.KeyCtrlN: keyboard.KeyCtrlN,
tcell.KeyCtrlO: keyboard.KeyCtrlO,
tcell.KeyCtrlP: keyboard.KeyCtrlP,
tcell.KeyCtrlQ: keyboard.KeyCtrlQ,
tcell.KeyCtrlR: keyboard.KeyCtrlR,
tcell.KeyCtrlS: keyboard.KeyCtrlS,
tcell.KeyCtrlT: keyboard.KeyCtrlT,
tcell.KeyCtrlU: keyboard.KeyCtrlU,
tcell.KeyCtrlV: keyboard.KeyCtrlV,
tcell.KeyCtrlW: keyboard.KeyCtrlW,
tcell.KeyCtrlX: keyboard.KeyCtrlX,
tcell.KeyCtrlY: keyboard.KeyCtrlY,
tcell.KeyCtrlZ: keyboard.KeyCtrlZ,
tcell.KeyBackspace: keyboard.KeyBackspace,
tcell.KeyTab: keyboard.KeyTab,
tcell.KeyEscape: keyboard.KeyEsc,
tcell.KeyCtrlBackslash: keyboard.KeyCtrlBackslash,
tcell.KeyCtrlRightSq: keyboard.KeyCtrlRsqBracket,
tcell.KeyCtrlUnderscore: keyboard.KeyCtrlUnderscore,
tcell.KeyBackspace2: keyboard.KeyBackspace2,
tcell.KeyCtrlSpace: keyboard.KeyCtrlSpace,
}
// convKey converts a tcell keyboard event to the termdash format.
func convKey(event *tcell.EventKey) terminalapi.Event {
tcellKey := event.Key()
if tcellKey == tcell.KeyRune {
ch := event.Rune()
return &terminalapi.Keyboard{
Key: keyboard.Key(ch),
}
}
k, ok := tcellToTd[tcellKey]
if !ok {
return terminalapi.NewErrorf("unknown keyboard key '%v' in a keyboard event", tcellKey)
}
return &terminalapi.Keyboard{
Key: k,
}
}
// convMouse converts a tcell mouse event to the termdash format.
func convMouse(event *tcell.EventMouse) terminalapi.Event {
var button mouse.Button
x, y := event.Position()
tcellBtn := event.Buttons()
// tcell uses signed int16 for button masks, and negative values are invalid
if tcellBtn < 0 {
return terminalapi.NewErrorf("unknown mouse key %v in a mouse event", tcellBtn)
}
// Get wheel events
if tcellBtn&tcell.WheelUp != 0 {
button = mouse.ButtonWheelUp
} else if tcellBtn&tcell.WheelDown != 0 {
button = mouse.ButtonWheelDown
}
// Return wheel event if found
if button > 0 {
return &terminalapi.Mouse{
Position: image.Point{X: x, Y: y},
Button: button,
}
}
// Get only button events, not wheel events
tcellBtn &= tcell.ButtonMask(0xff)
switch tcellBtn = event.Buttons(); tcellBtn {
case tcell.ButtonNone:
button = mouse.ButtonRelease
case tcell.Button1:
button = mouse.ButtonLeft
case tcell.Button2:
button = mouse.ButtonRight
case tcell.Button3:
button = mouse.ButtonMiddle
default:
// Do nothing, since tcell allows multiple buttons to be pressed at the same time
// Maybe refactor terminalapi to handle multiple mouse buttons being pressed at the same time (e.g. M1 + M2)
}
return &terminalapi.Mouse{
Position: image.Point{X: x, Y: y},
Button: button,
}
}
// convResize converts a tcell resize event to the termdash format.
func convResize(event *tcell.EventResize) terminalapi.Event {
w, h := event.Size()
size := image.Point{X: w, Y: h}
if size.X < 0 || size.Y < 0 {
return terminalapi.NewErrorf("terminal resized to negative size: %v", size)
}
return &terminalapi.Resize{
Size: size,
}
}
// toTermdashEvents converts a tcell event to the termdash event format.
func toTermdashEvents(event tcell.Event) []terminalapi.Event {
switch event := event.(type) {
case *tcell.EventInterrupt:
return []terminalapi.Event{
terminalapi.NewError("event type EventInterrupt isn't supported"),
}
case *tcell.EventKey:
return []terminalapi.Event{convKey(event)}
case *tcell.EventMouse:
return []terminalapi.Event{convMouse(event)}
case *tcell.EventResize:
return []terminalapi.Event{convResize(event)}
case *tcell.EventError:
return []terminalapi.Event{
terminalapi.NewErrorf("encountered tcell error event: %v", event),
}
default:
return []terminalapi.Event{
terminalapi.NewErrorf("unknown tcell event type: %v", event),
}
}
}