Fix dropdown mouse capture behavior
This commit is contained in:
parent
a8fe476d77
commit
6d9b735867
4 changed files with 43 additions and 8 deletions
|
@ -1,3 +1,6 @@
|
|||
v0.2.2 (WIP)
|
||||
- Fix dropdown mouse capture behavior
|
||||
|
||||
v0.2.1 (2020-01-01)
|
||||
- Add initial mouse support (some widgets are unsupported)
|
||||
- Add window size change handler
|
||||
|
|
|
@ -85,6 +85,9 @@ type Application struct {
|
|||
// be forwarded).
|
||||
mouseCapture func(event *EventMouse) *EventMouse
|
||||
|
||||
// A temporary capture function overriding the above.
|
||||
tempMouseCapture func(event *EventMouse) *EventMouse
|
||||
|
||||
lastMouseX, lastMouseY int
|
||||
lastMouseBtn tcell.ButtonMask
|
||||
lastMouseTarget Primitive // nil if none
|
||||
|
@ -124,7 +127,9 @@ func (a *Application) GetInputCapture() func(event *tcell.EventKey) *tcell.Event
|
|||
// choose to forward that event (or a different one) by returning it or stop
|
||||
// the event processing by returning nil.
|
||||
func (a *Application) SetMouseCapture(capture func(event *EventMouse) *EventMouse) *Application {
|
||||
a.Lock()
|
||||
a.mouseCapture = capture
|
||||
a.Unlock()
|
||||
return a
|
||||
}
|
||||
|
||||
|
@ -134,6 +139,22 @@ func (a *Application) GetMouseCapture() func(event *EventMouse) *EventMouse {
|
|||
return a.mouseCapture
|
||||
}
|
||||
|
||||
// SetTemporaryMouseCapture temporarily overrides the normal capture function.
|
||||
// Calling this function from anywhere other than a widget may result in
|
||||
// unexpected behavior.
|
||||
func (a *Application) SetTemporaryMouseCapture(capture func(event *EventMouse) *EventMouse) *Application {
|
||||
a.Lock()
|
||||
a.tempMouseCapture = capture
|
||||
a.Unlock()
|
||||
return a
|
||||
}
|
||||
|
||||
// GetTemporaryMouseCapture returns the function installed with
|
||||
// SetTemporaryMouseCapture() or nil if no such function has been installed.
|
||||
func (a *Application) GetTemporaryMouseCapture() func(event *EventMouse) *EventMouse {
|
||||
return a.tempMouseCapture
|
||||
}
|
||||
|
||||
// SetScreen allows you to provide your own tcell.Screen object. For most
|
||||
// applications, this is not needed and you should be familiar with
|
||||
// tcell.Screen when using this function.
|
||||
|
@ -263,6 +284,7 @@ EventLoop:
|
|||
p := a.focus
|
||||
inputCapture := a.inputCapture
|
||||
mouseCapture := a.mouseCapture
|
||||
tempMouseCapture := a.tempMouseCapture
|
||||
screen := a.screen
|
||||
root := a.root
|
||||
a.RUnlock()
|
||||
|
@ -373,6 +395,13 @@ EventLoop:
|
|||
event2 := NewEventMouse(event, ptarget, a, act)
|
||||
|
||||
// Intercept event.
|
||||
if tempMouseCapture != nil {
|
||||
event2 = tempMouseCapture(event2)
|
||||
if event2 == nil {
|
||||
a.draw()
|
||||
continue // Don't forward event.
|
||||
}
|
||||
}
|
||||
if mouseCapture != nil {
|
||||
event2 = mouseCapture(event2)
|
||||
if event2 == nil {
|
||||
|
|
|
@ -108,7 +108,7 @@ func main() {
|
|||
|
||||
app.SetMouseCapture(func(event *cview.EventMouse) *cview.EventMouse {
|
||||
atX, atY := event.Position()
|
||||
if event.Action()&cview.MouseClick != 0 && atY == screenHeight-1 {
|
||||
if event.Action()&cview.MouseDown != 0 && atY == screenHeight-1 {
|
||||
slideClicked := -1
|
||||
for i, region := range slideRegions {
|
||||
if atX >= region {
|
||||
|
|
17
dropdown.go
17
dropdown.go
|
@ -440,7 +440,7 @@ func (d *DropDown) openList(setFocus func(Primitive), app *Application) {
|
|||
d.list.SetSelectedFunc(func(index int, mainText, secondaryText string, shortcut rune) {
|
||||
// An option was selected. Close the list again.
|
||||
d.currentOption = index
|
||||
d.closeList(setFocus)
|
||||
d.closeList(setFocus, app)
|
||||
|
||||
// Trigger "selected" event.
|
||||
if d.selected != nil {
|
||||
|
@ -461,14 +461,14 @@ func (d *DropDown) openList(setFocus func(Primitive), app *Application) {
|
|||
d.evalPrefix()
|
||||
} else if event.Key() == tcell.KeyEscape {
|
||||
d.currentOption = optionBefore
|
||||
d.closeList(setFocus)
|
||||
d.closeList(setFocus, app)
|
||||
} else {
|
||||
d.prefix = ""
|
||||
}
|
||||
return event
|
||||
})
|
||||
if app != nil {
|
||||
app.SetMouseCapture(func(event *EventMouse) *EventMouse {
|
||||
app.SetTemporaryMouseCapture(func(event *EventMouse) *EventMouse {
|
||||
if d.open {
|
||||
// Forward the mouse event to the list.
|
||||
atX, atY := event.Position()
|
||||
|
@ -490,8 +490,7 @@ func (d *DropDown) openList(setFocus func(Primitive), app *Application) {
|
|||
// Mouse not within the list.
|
||||
if event.Action()&MouseDown != 0 {
|
||||
// If a mouse button was pressed, cancel this capture.
|
||||
app.SetMouseCapture(nil)
|
||||
d.closeList(event.SetFocus)
|
||||
d.closeList(event.SetFocus, app)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -501,7 +500,11 @@ func (d *DropDown) openList(setFocus func(Primitive), app *Application) {
|
|||
setFocus(d.list)
|
||||
}
|
||||
|
||||
func (d *DropDown) closeList(setFocus func(Primitive)) {
|
||||
func (d *DropDown) closeList(setFocus func(Primitive), app *Application) {
|
||||
if app != nil {
|
||||
app.SetTemporaryMouseCapture(nil)
|
||||
}
|
||||
|
||||
d.open = false
|
||||
if d.list.HasFocus() {
|
||||
setFocus(d)
|
||||
|
@ -532,7 +535,7 @@ func (d *DropDown) MouseHandler() func(event *EventMouse) {
|
|||
//d.open = !d.open
|
||||
//event.SetFocus(d)
|
||||
if d.open {
|
||||
d.closeList(event.SetFocus)
|
||||
d.closeList(event.SetFocus, event.Application())
|
||||
} else {
|
||||
d.openList(event.SetFocus, event.Application())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue