Get mouse actions rather than just mouse state

This commit is contained in:
Chris Miller 2019-11-05 06:03:04 +00:00 committed by Trevor Slocum
parent 806d63d900
commit ad59b43801
6 changed files with 65 additions and 10 deletions

View File

@ -84,6 +84,10 @@ type Application struct {
// event to be forwarded to the default mouse handler (nil if nothing should
// be forwarded).
mouseCapture func(event EventMouse) EventMouse
lastMouseX, lastMouseY int
lastMouseBtn tcell.ButtonMask
lastMouseTarget Primitive // nil if none
}
// EventKey is the key input event info. This exists for some consistency with
@ -91,11 +95,22 @@ type Application struct {
// compatibility.
type EventKey = *tcell.EventKey
// MouseAction are bit flags indicating what the mouse is logically doing.
type MouseAction int
const (
MouseDown MouseAction = 1 << iota
MouseUp
MouseClick // Button1 only.
MouseMove // The mouse position changed.
)
// EventMouse is the mouse event info.
type EventMouse struct {
*tcell.EventMouse
Target Primitive
Application *Application
Action MouseAction
}
// IsZero returns true if this is a zero object.
@ -347,11 +362,46 @@ EventLoop:
a.draw()
case *tcell.EventMouse:
atX, atY := event.Position()
ptarget := a.GetPrimitiveAtPoint(atX, atY) // p under mouse.
if ptarget == nil {
ptarget = p // Fallback to focused.
btn := event.Buttons()
var ptarget Primitive
if a.lastMouseBtn != 0 {
// While a button is down, the same primitive gets events.
ptarget = a.lastMouseTarget
}
event2 := EventMouse{event, ptarget, a}
if ptarget == nil {
ptarget = a.GetPrimitiveAtPoint(atX, atY) // p under mouse.
if ptarget == nil {
ptarget = p // Fallback to focused.
}
}
a.lastMouseTarget = ptarget
// Calculate mouse actions.
var act MouseAction
if atX != a.lastMouseX || atY != a.lastMouseY {
act |= MouseMove
a.lastMouseX = atX
a.lastMouseY = atY
}
btnDiff := btn ^ a.lastMouseBtn
if btnDiff != 0 {
if btn&btnDiff != 0 {
act |= MouseDown
}
if a.lastMouseBtn&btnDiff != 0 {
act |= MouseUp
}
if a.lastMouseBtn == tcell.Button1 && btn == 0 {
if ptarget == a.GetPrimitiveAtPoint(atX, atY) {
// Only if Button1 and mouse up over same p.
act |= MouseClick
}
}
a.lastMouseBtn = btn
}
event2 := EventMouse{event, ptarget, a, act}
// Intercept event.
if mouseCapture != nil {

View File

@ -140,7 +140,7 @@ func (b *Button) InputHandler() func(event *tcell.EventKey, setFocus func(p Prim
func (b *Button) MouseHandler() func(event EventMouse) {
return b.WrapMouseHandler(func(event EventMouse) {
// Process mouse event.
if event.Buttons()&tcell.Button1 != 0 {
if event.Action&MouseClick != 0 {
if b.selected != nil {
b.selected()
}

View File

@ -206,7 +206,7 @@ func (c *Checkbox) InputHandler() func(event *tcell.EventKey, setFocus func(p Pr
func (c *Checkbox) MouseHandler() func(event EventMouse) {
return c.WrapMouseHandler(func(event EventMouse) {
// Process mouse event.
if event.Buttons()&tcell.Button1 != 0 {
if event.Action&MouseClick != 0 {
c.checked = !c.checked
if c.changed != nil {
c.changed(c.checked)

View File

@ -476,12 +476,17 @@ func (d *DropDown) openList(setFocus func(Primitive), app *Application) {
if atX >= x && atY >= y && atX < x+w && atY < y+h {
// Mouse is within the list.
if handler := d.list.MouseHandler(); handler != nil {
if event.Action&MouseUp != 0 {
// Treat mouse up as click here.
// This allows you to expand and select in one go.
event.Action |= MouseClick
}
handler(event)
return EventMouse{} // handled
}
} else {
// Mouse not within the list.
if event.Buttons() != 0 {
if event.Action&MouseDown != 0 {
// If a mouse button was pressed, cancel this capture.
app.SetMouseCapture(nil)
d.closeList(event.SetFocus)
@ -521,7 +526,7 @@ func (d *DropDown) HasFocus() bool {
func (d *DropDown) MouseHandler() func(event EventMouse) {
return d.WrapMouseHandler(func(event EventMouse) {
// Process mouse event.
if event.Buttons()&tcell.Button1 != 0 {
if event.Action&MouseDown != 0 && event.Buttons()&tcell.Button1 != 0 {
//d.open = !d.open
//event.SetFocus(d)
if d.open {

View File

@ -596,7 +596,7 @@ func (i *InputField) InputHandler() func(event *tcell.EventKey, setFocus func(p
func (i *InputField) MouseHandler() func(event EventMouse) {
return i.WrapMouseHandler(func(event EventMouse) {
// Process mouse event.
if event.Buttons()&tcell.Button1 != 0 {
if event.Action&MouseDown != 0 {
event.SetFocus(i)
}
})

View File

@ -572,7 +572,7 @@ func (l *List) indexAtPoint(atX, atY int) int {
func (l *List) MouseHandler() func(event EventMouse) {
return l.WrapMouseHandler(func(event EventMouse) {
// Process mouse event.
if event.Buttons()&tcell.Button1 != 0 {
if event.Action&MouseClick != 0 {
atX, atY := event.Position()
index := l.indexAtPoint(atX, atY)
if index != -1 {