clintbellanger/flare-engine — pull request #430 by josephbleau (2013-03-11 11:46:19+00:00)
Title: Proposal for simple & easy to use keyboard-based menu navigation

This PR is an example and potential beginning implementation of a keyboard (or joy, since its unified and uses same bindings) only menu navigation system. This will be useful if users wish to play with a controller with quick and logical navigation not using mouse emulation.

I sincerely recommend you check this branch out and compile and just play with it for one minute. It differs greatly from previous implementations of keyboard menu support.

HOW YOU USE TABLIST:

Include a TabList in your class where you're going to have keyboard-navigable widgets. The order in which the items are accessed by the keyboard is implicit in the order you add them.

Add widgets using tablist.add(mywidget).

Once you have added the navigable widgets to tablist, you simply need to call tablist.logic() as early as possible inside your classes update method. Tablist will lock the keys so handle accordingly.

AS A WIDGET IMPLEMENTER:

There are three methods and one member that I've added to the base Widget class. The methods are all optional and have a default implementation. They are:

getNext() / getPrev: is called when a user is iterating through widgets and reaches yours. these methods returns true when you are ready to release the up/down keys back to them. This allows you to implement internal navigation. You can find example usage of this in WidgetTextList. In TextList I don't actually release up/down (user must use left/right to escape) although I'm uncertain if this is the best practice or usage.

activate(): Simple and straight-forward. This method is called when the user has focus on your widget and presses the activate key. I have altered WidgetButton to support this functionality.

in_focus: This is set to true when a widget is currently in_focus. This will allow the widget implementation to test for this and act appropriately.

Other members which may eventually exist and be used: focusable (set to true or false depending on whether or not the widget is allowed to be "in focus") and captures_keys (set to true or false depending on whether or not the widget captures the entire keyboard, this will be useful in something like WidgetInput, and TabList would respect these flags, but this is currently not implemented.)

NOTE:

This is not by any means a final solution or final implementation. There are a lot of loose-ends, but I submit this as-is so that I might get feedback, criticism, or an otherwise go-ahead or "stop now!" before I spend the effort in implementing and supporting every widget we have so far.

Also, currently how GameStateLoad is working is with a manual implementation not using TabList. This is because the game slots are not implemented in terms of widgets. This is something that can be changed of course.

Best regards,
Joe (Ninwa on IRC)