Managing Focus Across Different Platforms
With the upcoming release of FGF/Thrust comes the return of a more traditional GUI. One of the most problematic requirements of a large GUI system is the notion of focus. The question remains how do you efficiently determine who has focus and how do you pass focus between controls? On Windows this is incredibly easy because we have the mouse pointer. Focus is changed whenever your mouse acts on a control. What about on the Zune or the Xbox 360 though? On both of these systems their is no mouse (although Thrust supports a virtual mouse).
The answer is to look at what Thrust currently supports. What built in system supports all three systems seamlessly? (~ means some support, X means full support)
| Event | Zune | Windows | Xbox 360 |
| Mouse | X | ||
| Keyboard | X | X | |
| GamePad | ~ | X | X |
| UniversalButton | X | X | X |
The problem is we can’t rely on each individual hardware controller being present and useable. For example we can’t rely on a keyboard being a focusing mechanism on the Xbox 360 because it isn’t a guarantee it exists. Likewise, we cannot rely on the GamePad on the Zune because of the lack of buttons.
To get to the point, the UniversalButton system was meant as a virtualization of the various hardware supported for each platform. It turns GamePad, Mouse, and Keyboard events into simple events like Up, Left, Down, Right, Select and Cancel. Because of this we can rely on it and implement a few more events.
- TabPreviousLocal
- TabNextLocal
- TabPreviousGlobal
- TabNextGlobal
You can consider local tabbing to be much like you would on a Windows form: hitting the tab key (or shift-tab) will move you from one control to another based on some order and only in the context of the global focus point (you never tab to a control in another window). The global tabbing can be considered like an Alt-Tab (or shift-alt-tab) where you can switch between windows.
So how do we implement this? We need a managing class (sorry Bjoern) to produce a bottleneck for the input events. As events are channeled through this class, it massages the data and figures out what to do. For instance if a global tab next event is received it has to switch focus to the next window in the system on the same level as the current window. If it receives a local tab event it will pass a message to the current focal point to tab to the next control.
What does this do for us? For one, it unifies the approach to focusing across all the UI subsystems. This means that a Window/Form implementation will focus in much the same way a simple screen will. Unfortunately it also means a complexity requirement for implementation developers. The age of the simple StateManager class is coming to an end. Elements on the screen now need to have a basic state for animation as well as a state for focus (or lack thereof). While it may still be possible to simply unload an element through the StateManager, the reality is that UI elements will have to do a little more management under the hood. Whether this is exposed to the user / developer is still to be decided.


