jroimartin / gocui

Minimalist Go package aimed at creating Console User Interfaces.
BSD 3-Clause "New" or "Revised" License
9.92k stars 608 forks source link

Expose termbox events to keybinding handlers #97

Closed Benaiah closed 7 years ago

Benaiah commented 7 years ago

I'm trying to add mouse-based view selection to https://github.com/asciimoo/wuzz, and I'm running into trouble. I can add a MouseRelease keybinding fine, and when I click in the text of a selected view it works perfectly. The issue is that, given a gocui.Gui g, I can't add a global keybinding that sets the view with g.ViewByPosition within the key handler, since it doesn't expose the underlying termbox event, and I thus can't access the X/Y position of the mouse. As far as I can tell, fixing this in wuzz would require either replacing gocui's event handler entirely or running two termbox event polls simultaneously, both of which are unattractive options.

My only other option is to add a "select this view" keybinding fired on gocui.MouseRelease for every visible view, which is possible but definitely not a preferable way of doing it.

It's a bit of predicament, since I can see why you wouldn't want to change the g.SetKeybinding API at this point, but as it stands it makes the gocui mouse events mostly useless - there's no way at all to tell the mouse position outside of which view it was in, and even doing that is more awkward than it needs to be.

Any thoughts on how to approach this? I'd be happy to contribute, but the problem is more one of API design than technical problems, and I thought I'd get input from people working on gocui rather than send a PR out of the blue.

jroimartin commented 7 years ago

Maybe I don't understand the problem correctly, but what's the problem with this approach?

https://github.com/jroimartin/gocui/blob/master/_examples/mouse.go#L64-L68

and then:

https://github.com/jroimartin/gocui/blob/master/_examples/mouse.go#L83-L85

jroimartin commented 7 years ago

BTW you could also create a widget for your textareas and handle mouse events from them, which could possibly clean up your code. For instance,

https://github.com/jroimartin/gocui/blob/master/_examples/widgets.go#L86-L113

Benaiah commented 7 years ago

@jroimartin yeah, that could solve this specific problem, but it still doesn't allow for any determination of mouse position besides which view was clicked. In addition, wouldn't this disable the built-in gocui mouse feature of moving the cursor within the text of the view?

jroimartin commented 7 years ago

it still doesn't allow for any determination of mouse position besides which view was clicked.

You can use *View.Cursor() to know the cursor position within the clicked view.

https://github.com/jroimartin/gocui/blob/master/_examples/mouse.go#L87

wouldn't this disable the built-in gocui mouse feature of moving the cursor within the text of the view?

It shouldn't, mouse keybindings are executed after setting the cursor position (g.execKeybindings(v, ev)):

https://github.com/jroimartin/gocui/blob/master/gui.go#L588-L600

Benaiah commented 7 years ago

@jroimartin cool! Glad that this wasn't the issue I originally thought. Thanks for your help and patience.

jroimartin commented 7 years ago

No problem! :)

BTW don't get me wrong, I'm open to change the API and I know there is lot of room for improvement, so if we find something in the API that should be modified we will do it. But always trying to keep it as simple and sane as possible, because that's one of the objectives behind gocui.