Skip to content

Commit

Permalink
Merge branch 'focus'
Browse files Browse the repository at this point in the history
  • Loading branch information
auriamg committed Jun 12, 2014
2 parents ed978cc + 9a37cd2 commit 4ea1b7c
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 159 deletions.
199 changes: 42 additions & 157 deletions src/guiengine/event_handler.cpp
Expand Up @@ -305,12 +305,12 @@ void EventHandler::processGUIAction(const PlayerAction action,

case PA_ACCEL:
case PA_MENU_UP:
navigateUp(playerID, type, pressedDown);
navigate(playerID, type, pressedDown, true);
break;

case PA_BRAKE:
case PA_MENU_DOWN:
navigateDown(playerID, type, pressedDown);
navigate(playerID, type, pressedDown, false);
break;

case PA_RESCUE:
Expand Down Expand Up @@ -364,10 +364,14 @@ const bool NAVIGATION_DEBUG = false;
#pragma mark Private methods
#endif

void EventHandler::navigateUp(const int playerID, Input::InputType type, const bool pressedDown)
/**
* Focus the next widget either downwards or upwards.
*
* \param reverse True means navigating up, false means down.
*/
void EventHandler::navigate(const int playerID, Input::InputType type, const bool pressedDown, const bool reverse)
{
//std::cout << "Naviagte up!\n";
IGUIElement *el = NULL/*, *first=NULL*/, *closest=NULL;
IGUIElement *el = NULL, *closest = NULL;

if (type == Input::IT_STICKBUTTON && !pressedDown)
return;
Expand All @@ -378,19 +382,22 @@ void EventHandler::navigateUp(const int playerID, Input::InputType type, const b
el = w->getIrrlichtElement();
}


// list widgets are a bit special, because up/down keys are also used
// to navigate between various list items, not only to navigate between
// components
if (w != NULL && w->m_type == WTYPE_LIST)
{
ListWidget* list = (ListWidget*)w;
ListWidget* list = (ListWidget*) w;

const bool stay_within_list = list->getSelectionID() > 0;
const bool stay_within_list = reverse ? list->getSelectionID() > 0 :
list->getSelectionID() < list->getItemCount() - 1;

if (stay_within_list)
{
list->setSelectionID(list->getSelectionID()-1);
if (reverse)
list->setSelectionID(list->getSelectionID() - 1);
else
list->setSelectionID(list->getSelectionID() + 1);
return;
}
else
Expand All @@ -399,16 +406,15 @@ void EventHandler::navigateUp(const int playerID, Input::InputType type, const b
}
}

if (w != NULL && w->m_tab_up_root != -1)
if (w != NULL && ((reverse && w->m_tab_up_root != -1) || (!reverse && w->m_tab_down_root != -1)))
{
Widget* up = GUIEngine::getWidget( w->m_tab_up_root );
assert( up != NULL );

el = up->getIrrlichtElement();
Widget* next = GUIEngine::getWidget(reverse ? w->m_tab_up_root : w->m_tab_down_root);
assert(next != NULL);
el = next->getIrrlichtElement();

if (el == NULL)
{
std::cerr << "WARNING : m_tab_down_root is set to an ID for which I can't find the widget\n";
std::cerr << "WARNING : m_tab_down/up_root is set to an ID for which I can't find the widget\n";
return;
}
}
Expand All @@ -424,190 +430,69 @@ void EventHandler::navigateUp(const int playerID, Input::InputType type, const b
// find closest widget
if (el != NULL && el->getTabGroup() != NULL)
{
// if the current widget is e.g. 15, search for widget 14, 13, 12, ... (up to 10 IDs may be missing)
for (int n=1; n<10 && !found; n++)
// Up: if the current widget is e.g. 15, search for widget 14, 13, 12, ... (up to 10 IDs may be missing)
// Down: if the current widget is e.g. 5, search for widget 6, 7, 8, 9, ..., 15 (up to 10 IDs may be missing)
for (int n = 1; n < 10 && !found; n++)
{
closest = GUIEngine::getGUIEnv()->getRootGUIElement()->getElementFromId(el->getTabOrder() - n, true);
closest = GUIEngine::getGUIEnv()->getRootGUIElement()->getElementFromId(el->getTabOrder() + (reverse ? -n : n), true);

if (closest != NULL && Widget::isFocusableId(closest->getID()))
{
if (NAVIGATION_DEBUG) std::cout << "Navigating up to " << closest->getID() << std::endl;
Widget* closestWidget = GUIEngine::getWidget( closest->getID() );

if (playerID != PLAYER_ID_GAME_MASTER && !closestWidget->m_supports_multiplayer) return;

// if a dialog is shown, restrict to items in the dialog
if (ModalDialog::isADialogActive() && !ModalDialog::getCurrent()->isMyChild(closestWidget))
{
continue;
}

// when focusing a list by going up, select the last item of the list
assert (closestWidget != NULL);

closestWidget->setFocusForPlayer(playerID);

if (closestWidget->m_type == WTYPE_LIST)
if (NAVIGATION_DEBUG)
{
IGUIListBox* list = (IGUIListBox*)(closestWidget->m_element);
assert(list != NULL);

list->setSelected( list->getItemCount()-1 );
return;
std::cout << "Navigating " << (reverse ? "up" : "down") << " to " << closest->getID() << std::endl;
}
found = true;

}
} // end for

}

if (!found)
{
if (NAVIGATION_DEBUG)
{
std::cout << "EventHandler::navigateUp : wrap around, selecting the last widget\n";
}

// select the last widget
Widget* lastWidget = NULL;

if (ModalDialog::isADialogActive())
{
lastWidget = ModalDialog::getCurrent()->getLastWidget();
}
else
{
Screen* screen = GUIEngine::getCurrentScreen();
if (screen == NULL) return;
lastWidget = screen->getLastWidget();
}

if (lastWidget != NULL) lastWidget->setFocusForPlayer(playerID);
}
}

// -----------------------------------------------------------------------------

void EventHandler::navigateDown(const int playerID, Input::InputType type, const bool pressedDown)
{
//std::cout << "Naviagte down!\n";

IGUIElement *el = NULL, *closest = NULL;

if (type == Input::IT_STICKBUTTON && !pressedDown)
return;

Widget* w = GUIEngine::getFocusForPlayer(playerID);
if (w != NULL)
{
el = w->getIrrlichtElement();
}
//std::cout << "!!! Player " << playerID << " navigating down of " << w->m_element->getID() << std::endl;

// list widgets are a bit special, because up/down keys are also used
// to navigate between various list items, not only to navigate between
// components
if (w != NULL && w->m_type == WTYPE_LIST)
{
ListWidget* list = (ListWidget*)w;

const bool stay_within_list = list->getSelectionID() < list->getItemCount()-1;

if (stay_within_list)
{
list->setSelectionID(list->getSelectionID()+1);
return;
}
else
{
list->setSelectionID(-1);
}
}

if (w != NULL && w->m_tab_down_root != -1)
{
Widget* down = GUIEngine::getWidget( w->m_tab_down_root );
assert(down != NULL);
el = down->getIrrlichtElement();

if (el == NULL)
{
std::cerr << "WARNING : m_tab_down_root is set to an ID for which I can't find the widget\n";
return;
}
}

// don't allow navigating to any widget when a dialog is shown; only navigate to widgets in the dialog
if (ModalDialog::isADialogActive() && !ModalDialog::getCurrent()->isMyIrrChild(el))
{
el = NULL;
}

bool found = false;

if (el != NULL && el->getTabGroup() != NULL)
{
// if the current widget is e.g. 5, search for widget 6, 7, 8, 9, ..., 15 (up to 10 IDs may be missing)
for (int n=1; n<10 && !found; n++)
{
closest = GUIEngine::getGUIEnv()->getRootGUIElement()->getElementFromId(el->getTabOrder() + n, true);

if (closest != NULL && Widget::isFocusableId(closest->getID()))
{

Widget* closestWidget = GUIEngine::getWidget( closest->getID() );
if (playerID != PLAYER_ID_GAME_MASTER && !closestWidget->m_supports_multiplayer) return;
assert(closestWidget != NULL);

// if a dialog is shown, restrict to items in the dialog
if (ModalDialog::isADialogActive() && !ModalDialog::getCurrent()->isMyChild(closestWidget))
{
if (!closestWidget->isVisible() || !closestWidget->isActivated())
continue;
}

if (NAVIGATION_DEBUG)
{
std::cout << "Navigating down to " << closestWidget->getID() << "\n";
}

assert( closestWidget != NULL );
closestWidget->setFocusForPlayer(playerID);

// another list exception : when entering a list, select the first item
// another list exception : when entering a list by going down, select the first item
// when focusing a list by going up, select the last item of the list
if (closestWidget->m_type == WTYPE_LIST)
{
IGUIListBox* list = (IGUIListBox*)(closestWidget->m_element);
ListWidget* list = (ListWidget*) closestWidget;
assert(list != NULL);

list->setSelected(0);
list->setSelectionID(reverse ? list->getItemCount() - 1 : 0);
}

found = true;
}
} // end for
}

if (!found)
{
if (NAVIGATION_DEBUG)
std::cout << "EventHandler::navigat : wrap around\n";

if (NAVIGATION_DEBUG) std::cout << "Navigating down : wrap around\n";

// select the first widget
Widget* firstWidget = NULL;
// select the last/first widget
Widget* wrapWidget = NULL;

if (ModalDialog::isADialogActive())
{
//std::cout << "w = ModalDialog::getCurrent()->getFirstWidget();\n";
firstWidget = ModalDialog::getCurrent()->getFirstWidget();
wrapWidget = reverse ? ModalDialog::getCurrent()->getLastWidget() :
ModalDialog::getCurrent()->getFirstWidget();
}
else
{
Screen* screen = GUIEngine::getCurrentScreen();
if (screen == NULL) return;
firstWidget = screen->getFirstWidget();
wrapWidget = reverse ? screen->getLastWidget() :
screen->getFirstWidget();
}

if (firstWidget != NULL) firstWidget->setFocusForPlayer(playerID);
if (wrapWidget != NULL) wrapWidget->setFocusForPlayer(playerID);
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/guiengine/event_handler.hpp
Expand Up @@ -62,8 +62,7 @@ namespace GUIEngine

EventPropagation onGUIEvent(const irr::SEvent& event);
EventPropagation onWidgetActivated(Widget* w, const int playerID);
void navigateUp(const int playerID, Input::InputType type, const bool pressedDown);
void navigateDown(const int playerID, Input::InputType type, const bool pressedDown);
void navigate(const int playerID, Input::InputType type, const bool pressedDown, const bool reverse);

/** \brief send an event to the GUI module user's event callback
* \param widget the widget that triggerred this event
Expand Down

0 comments on commit 4ea1b7c

Please sign in to comment.