diff options
author | Vlastimil Ovčáčík <vovcacik@github.ovcacik.org> | 2021-09-21 17:52:39 +0200 |
---|---|---|
committer | Junegunn Choi <junegunn.c@gmail.com> | 2021-10-03 01:39:30 +0900 |
commit | 0ff885461b0474b58f08d7c3f48992a0e1eafee0 (patch) | |
tree | 730a1209b4c5af4ac8233f15370fc8ea857722f9 /src/tui/tcell.go | |
parent | ca43f95fb1835f74f837e1599a3383b4a7123390 (diff) |
Add mouse support to the FullscreenRenderer
Diffstat (limited to 'src/tui/tcell.go')
-rw-r--r-- | src/tui/tcell.go | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/src/tui/tcell.go b/src/tui/tcell.go index dd0581b7..054c5504 100644 --- a/src/tui/tcell.go +++ b/src/tui/tcell.go @@ -185,14 +185,48 @@ func (r *FullscreenRenderer) GetChar() Event { // process mouse events: case *tcell.EventMouse: + // mouse down events have zeroed buttons, so we can't use them + // mouse up event consists of two events, 1. (main) event with modifier and other metadata, 2. event with zeroed buttons + // so mouse click is three consecutive events, but the first and last are indistinguishable from movement events (with released buttons) + // dragging has same structure, it only repeats the middle (main) event appropriately x, y := ev.Position() - button := ev.Buttons() mod := ev.Modifiers() != 0 - if button&tcell.WheelDown != 0 { + + // since we dont have mouse down events (unlike LightRenderer), we need to track state in prevButton + prevButton, button := r.prevMouseButton, ev.Buttons() + r.prevMouseButton = button + drag := prevButton == button + + switch { + case button&tcell.WheelDown != 0: return Event{Mouse, 0, &MouseEvent{y, x, -1, false, false, false, mod}} - } else if button&tcell.WheelUp != 0 { + case button&tcell.WheelUp != 0: return Event{Mouse, 0, &MouseEvent{y, x, +1, false, false, false, mod}} - } else if runtime.GOOS != "windows" { + case button&tcell.Button1 != 0 && !drag: + // all potential double click events put their 'line' coordinate in the clickY array + // double click event has two conditions, temporal and spatial, the first is checked here + now := time.Now() + if now.Sub(r.prevDownTime) < doubleClickDuration { + r.clickY = append(r.clickY, y) + } else { + r.clickY = []int{y} + } + r.prevDownTime = now + + // detect double clicks (also check for spatial condition) + n := len(r.clickY) + double := n > 1 && r.clickY[n-2] == r.clickY[n-1] + if double { + // make sure two consecutive double clicks require four clicks + r.clickY = []int{} + } + + // fire single or double click event + return Event{Mouse, 0, &MouseEvent{y, x, 0, true, !double, double, mod}} + case button&tcell.Button2 != 0 && !drag: + return Event{Mouse, 0, &MouseEvent{y, x, 0, false, true, false, mod}} + case runtime.GOOS != "windows": + // double and single taps on Windows don't quite work due to // the console acting on the events and not allowing us // to consume them. |