Guiliani  Version 2.5 revision 6773 (build 33)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Focusing

Guiliani supports two main approaches for changing the focused object with key presses: focus previous/focus next and four-way navigation.

In both modes, the framework searches through the tree in the desired direction by calling CGUIObject::RequestFocus until it finds a focusable object. If an object accepts the focus (because it is focusable), CGUIObject::GetFocus is called. This method may be re-implemented. After a control accepted and received the focus, the previously focused object is notified by a call to CGUIObject::LoseFocus.

Focus previous and focus next

In this mode, the focused object can be changed by two keys. One focuses the 'previous' object, the other the 'next' object.

What the 'previous' and 'next' objects are is defined by the structure of the GUI tree (composite objects and their children).

For detailed information, see CGUICompositeObject::FocusPrevious and CGUICompositeObject::FocusNext.

Four-way navigation

In this mode, four directional keys or buttons can be used to change the focused object. The algorithm works geometrically by examining the relative positions of the currently focused object's center point and the center points of the surrounding objects. Consider the following example GUI:

4wn_example.png

Each of the rectangles represents a focusable object. The orange-framed object is the currently focused one. The diagonal lines show the four sectors or directions in which the next focusable object is searched for.

Example: when pressing a key that results in a 'focus right', the framework will find the objects 1 and 2 because their center points lie in that sector. The object whose center is geometrically closer to the center of the currently focused object is focused next.

When focusing 'down', only object 3 will be found because there are no other object's center points in the lower sector.

Focusing 'up' finds objects 5 and 6; the closer one (5) will be focused.

Focusing 'left' does nothing because there are no other objects to the left.

The results delivered by this algorithm may not always be intuitive. In the For instance, it might be desirable to have an object to be focused when pressing 'down'. In these cases, neighborhood may be manually defined. The following methods may be called to define four-way navigation neighbors:

Custom focus logic

If neither the standard focusing algorithm, nor the possibility to manually set neighbors via Object handles, delivers the desired result, you are free to implement custom focus logic by overriding the CGUIObject::FourWayNext() method. This method will be called by the framework with a parameter telling in which direction the focus should be moved. By reimplementing this method you can control where the focus shall be moved. The following example code demonstrates how this can be done. Make sure to either call the base-class implementation if you did not handle the focus logic yourself, or explicitly return true, so that Guiliani knows that you have taken care of the focus already.

#include "GUI.h"
#include "GUIEventHandler.h"
eC_Bool CExampleObject::FourWayNext(FourWayFocus_t eFocusDirection)
{
switch(eFocusDirection)
{
case FourWayFocus_t::FOCUS_UP: // Use 2-Way navigation and simply focus the "previous" object of the currently focussed one
GETEVENTHDL.GetFocussedObject()->FocusPrevious();
break;
case FourWayFocus_t::FOCUS_DOWN: // Same as above, but this time focus the "next" object
GETEVENTHDL.GetFocussedObject()->FocusNext();
break;
case FourWayFocus_t::FOCUS_LEFT: // Search for a specific object in the GUI and try to focus it
GETGUI.GetObjectByID( OBJ_SOME_NAME )->RequestFocus();
break;
default: // Call base class for default handling
return CGUICompositeObject::FourWayNext(eFocusDirection);
}
return true; // We have handled focussing. Guiliani shall not apply the default algorithm.
}