emilk / egui

egui: an easy-to-use immediate mode GUI in Rust that runs on both web and native
https://www.egui.rs/
Apache License 2.0
22.38k stars 1.6k forks source link

Gampad and arrow-keys navigation support #1250

Closed kissmikijr closed 1 year ago

kissmikijr commented 2 years ago

Is your feature request related to a problem? Please describe.

I'd like to be able to navigate on the gui elments using a gamepad

kissmikijr commented 2 years ago

I am happy to work on this, however I'll definitely need some pointers where to start.

emilk commented 2 years ago

I am happy to work on this, however I'll definitely need some pointers where to start.

That would be wonderful!

The current focus system (TAB/shift-tab) is based on which order widgets are added, and is found in struct Focus in egui/src/memory.rs. In particular, Focus::interested_in_focus is called for every new widget that is added on screen.

To handle moving focus in the four cardinal directions we would need to also supply interested_in_focus with a Rect of the widget (that's the easy part). I think then the logic we would need be something like this:

Alternatively:

This will be slightly more expensive, but probably not by much, and the code will potentially be much cleaner.

akhilman commented 2 years ago

My idea is to store the bounding boxes of widgets during rendering along with the corresponding senses.

Further, we can easily implement the activation of the widget in an arbitrary direction, even using an analogue stick. To do this, it will be enough, using the saved data, to filter the widgets with the necessary senses, filter the widgets in the right direction from the active widget, and finally select the nearest widget.

This size list will also help implement mouse event filtering, as described in #724.

emilk commented 2 years ago

This is the same functionality required in order to be able to focus widgets with the arrow keys, so I'll add that to this issue.

TimonPost commented 1 year ago

We need gamepad support for egui and I'm looking to either try doing something similar like https://github.com/idanarye/bevy-egui-kbgp or to implement this into egui directly. I kinda want to do it in egui as it looks like a valuable addition.

Making egui full-gamepad compatible is probably a slightly bigger task (e.g dragging sliders, checkboxes, inputting text). For us its important we can just do the navigation for now.

I am going to try giving the alternative approach a try, storing rects in a list, and then detecting what rects are closest in a certain cardinal direction. And also directly try implementing the keyboard arrows.

Any tips that would help speeding up the implementation?