stk-code_catmod/src/guiengine/event_handler.cpp
hiker 4d6b110e56 Removed unnecessary #include of user_config.hpp in other hpp files
(to reduce the amount of recompilation when user_config.hpp is changed).
2014-02-26 12:52:16 +11:00

850 lines
29 KiB
C++

// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010-2013 Marianne Gagnon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "guiengine/event_handler.hpp"
#include "config/user_config.hpp"
#include "graphics/irr_driver.hpp"
#include "guiengine/abstract_state_manager.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/modaldialog.hpp"
#include "guiengine/screen.hpp"
#include "guiengine/widget.hpp"
#include "guiengine/widgets/list_widget.hpp"
#include "guiengine/widgets/ribbon_widget.hpp"
#include "input/input_manager.hpp"
#include "modes/demo_world.hpp"
#include "modes/world.hpp"
#include "states_screens/state_manager.hpp"
#include "utils/debug.hpp"
#include "utils/profiler.hpp"
#include <IGUIEnvironment.h>
#include <IGUIListBox.h>
#include <iostream>
using GUIEngine::EventHandler;
using GUIEngine::EventPropagation;
using namespace irr::gui;
// -----------------------------------------------------------------------------
EventHandler::EventHandler()
{
m_accept_events = false;
}
// -----------------------------------------------------------------------------
EventHandler::~EventHandler()
{
}
// -----------------------------------------------------------------------------
bool EventHandler::OnEvent (const SEvent &event)
{
if (!m_accept_events && event.EventType != EET_LOG_TEXT_EVENT) return true;
if(!Debug::onEvent(event))
return false;
// TO DEBUG HATS (when you don't actually have a hat)
/*
if (event.EventType == EET_KEY_INPUT_EVENT)
{
if (event.KeyInput.Key == 'W')
{
printf("Sending hat up event %i\n", event.KeyInput.PressedDown);
SEvent evt2;
evt2.EventType = EET_JOYSTICK_INPUT_EVENT;
for (int n=0; n<SEvent::SJoystickEvent::NUMBER_OF_AXES; n++)
{
evt2.JoystickEvent.Axis[n] = 0.0f;
}
evt2.JoystickEvent.ButtonStates = 0;
evt2.JoystickEvent.Joystick = 0;
evt2.JoystickEvent.POV = (event.KeyInput.PressedDown ? 0 : 65535); // 0 degrees
OnEvent(evt2);
return false;
}
else if (event.KeyInput.Key == 'D')
{
printf("Sending hat right event %i\n", event.KeyInput.PressedDown);
SEvent evt2;
evt2.EventType = EET_JOYSTICK_INPUT_EVENT;
for (int n=0; n<SEvent::SJoystickEvent::NUMBER_OF_AXES; n++)
{
evt2.JoystickEvent.Axis[n] = 0.0f;
}
evt2.JoystickEvent.ButtonStates = 0;
evt2.JoystickEvent.Joystick = 0;
evt2.JoystickEvent.POV = (event.KeyInput.PressedDown ? 9000 : 65535); // 90 degrees
OnEvent(evt2);
return false;
}
else if (event.KeyInput.Key == 'S')
{
printf("Sending hat down event %i\n", event.KeyInput.PressedDown);
SEvent evt2;
evt2.EventType = EET_JOYSTICK_INPUT_EVENT;
for (int n=0; n<SEvent::SJoystickEvent::NUMBER_OF_AXES; n++)
{
evt2.JoystickEvent.Axis[n] = 0.0f;
}
evt2.JoystickEvent.ButtonStates = 0;
evt2.JoystickEvent.Joystick = 0;
evt2.JoystickEvent.POV = (event.KeyInput.PressedDown ? 18000 : 65535); // 180 degrees
OnEvent(evt2);
return false;
}
else if (event.KeyInput.Key == 'A')
{
printf("Sending hat left event %i\n", event.KeyInput.PressedDown);
SEvent evt2;
evt2.EventType = EET_JOYSTICK_INPUT_EVENT;
for (int n=0; n<SEvent::SJoystickEvent::NUMBER_OF_AXES; n++)
{
evt2.JoystickEvent.Axis[n] = 0.0f;
}
evt2.JoystickEvent.ButtonStates = 0;
evt2.JoystickEvent.Joystick = 0;
evt2.JoystickEvent.POV = (event.KeyInput.PressedDown ? 27000 : 65535); // 270 degrees
OnEvent(evt2);
return false;
}
}
*/
// We do this (seemingly) overzealously to make sure that:
// 1. It resets on any GUI events
// 2. It resets on any mouse/joystick movement
// 3. It resets on any keyboard presses
if ((StateManager::get()->getGameState() == MENU)
&& (event.EventType != EET_LOG_TEXT_EVENT )
&& (event.EventType != EET_USER_EVENT ))
{
DemoWorld::resetIdleTime();
}
if (event.EventType == EET_GUI_EVENT)
{
return onGUIEvent(event) == EVENT_BLOCK;
}
else if (GUIEngine::getStateManager()->getGameState() != GUIEngine::GAME &&
event.EventType != EET_KEY_INPUT_EVENT && event.EventType != EET_JOYSTICK_INPUT_EVENT &&
event.EventType != EET_LOG_TEXT_EVENT)
{
return false; // EVENT_LET
}
else if (event.EventType == EET_MOUSE_INPUT_EVENT ||
event.EventType == EET_KEY_INPUT_EVENT ||
event.EventType == EET_JOYSTICK_INPUT_EVENT)
{
// Remember the mouse position
m_mouse_pos.X = event.MouseInput.X;
m_mouse_pos.Y = event.MouseInput.Y;
// Notify the profiler of mouse events
if(UserConfigParams::m_profiler_enabled &&
event.EventType == EET_MOUSE_INPUT_EVENT &&
event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP)
{
profiler.onClick(m_mouse_pos);
}
if (event.EventType == EET_MOUSE_INPUT_EVENT &&
event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN &&
StateManager::get()->getGameState() == GAME)
{
World::getWorld()->onMouseClick(event.MouseInput.X, event.MouseInput.Y);
}
// FIXME? it may be a bit unclean that all input events go trough
// the gui module
const EventPropagation blockPropagation = input_manager->input(event);
return blockPropagation == EVENT_BLOCK;
}
else if (event.EventType == EET_LOG_TEXT_EVENT)
{
// Ignore 'normal' messages
if (event.LogEvent.Level > irr:: ELL_INFORMATION)
{
// Unfortunatly irrlicht produces some internal error/warnings
// messages that can't be avoided (see COpenGLTexture where
// the constructor of COpenGLFBOTexture is used without
// specifying a color format, so the detault format (ECF_UNKOWNO)
// is used, which produces this error message). In non-debug
// mode ignore this error message, but leave it in for debugging.
if(std::string(event.LogEvent.Text)=="Unsupported texture format")
#ifdef DEBUG
printf("The following message will not be printed in release mode:\n");
#else
return true; // EVENT_BLOCK
#endif
const std::string &error_info = irr_driver->getTextureErrorMessage();
if (event.LogEvent.Level == irr::ELL_WARNING)
{
if(error_info.size()>0)
Log::warn("EventHandler", error_info.c_str());
Log::warn("Irrlicht", event.LogEvent.Text);
}
else if (event.LogEvent.Level == irr::ELL_ERROR)
{
if(error_info.size()>0)
Log::error("EventHandler", error_info.c_str());
Log::error("Irrlicht", event.LogEvent.Text);
}
}
return true;
}
// nothing to do with other events
return false;
}
// -----------------------------------------------------------------------------
void EventHandler::processGUIAction(const PlayerAction action,
int deviceID,
const unsigned int value,
Input::InputType type,
const int playerID)
{
Screen* screen = GUIEngine::getCurrentScreen();
if (screen != NULL)
{
EventPropagation propg = screen->filterActions(action, deviceID, value,
type, playerID);
if (propg == EVENT_BLOCK) return;
}
const bool pressedDown = value > Input::MAX_VALUE*2/3;
if (!pressedDown && type == Input::IT_STICKMOTION) return;
switch (action)
{
case PA_STEER_LEFT:
case PA_MENU_LEFT:
{
Widget* w = GUIEngine::getFocusForPlayer(playerID);
if (w == NULL) break;
Widget* widget_to_call = w;
/* Find topmost parent. Stop looping if a widget event handler's is itself, to not fall
in an infinite loop (this can happen e.g. in checkboxes, where they need to be
notified of clicks onto themselves so they can toggle their state. )
On the way, also notify everyone in the chain of the left press. */
while (widget_to_call->m_event_handler != NULL && widget_to_call->m_event_handler != widget_to_call)
{
if (widget_to_call->leftPressed(playerID) == EVENT_LET)
{
sendEventToUser(w, w->m_properties[PROP_ID], playerID);
}
widget_to_call = widget_to_call->m_event_handler;
}
if (widget_to_call->leftPressed(playerID) == EVENT_LET)
{
sendEventToUser(widget_to_call, widget_to_call->m_properties[PROP_ID], playerID);
}
}
break;
case PA_STEER_RIGHT:
case PA_MENU_RIGHT:
{
Widget* w = GUIEngine::getFocusForPlayer(playerID);
if (w == NULL) break;
Widget* widget_to_call = w;
/* Find topmost parent. Stop looping if a widget event handler's is itself, to not fall
in an infinite loop (this can happen e.g. in checkboxes, where they need to be
notified of clicks onto themselves so they can toggle their state. )
On the way, also notify everyone in the chain of the right press */
while (widget_to_call->m_event_handler != NULL && widget_to_call->m_event_handler != widget_to_call)
{
if (widget_to_call->rightPressed(playerID) == EVENT_LET)
{
sendEventToUser(widget_to_call, w->m_properties[PROP_ID], playerID);
}
widget_to_call = widget_to_call->m_event_handler;
}
if (widget_to_call->rightPressed(playerID) == EVENT_LET)
{
sendEventToUser(widget_to_call, widget_to_call->m_properties[PROP_ID], playerID);
}
}
break;
case PA_ACCEL:
case PA_MENU_UP:
navigateUp(playerID, type, pressedDown);
break;
case PA_BRAKE:
case PA_MENU_DOWN:
navigateDown(playerID, type, pressedDown);
break;
case PA_RESCUE:
case PA_MENU_CANCEL:
if (pressedDown) GUIEngine::getStateManager()->escapePressed();
break;
case PA_FIRE:
case PA_MENU_SELECT:
if (pressedDown && !isWithinATextBox())
{
Widget* w = GUIEngine::getFocusForPlayer(playerID);
if (w == NULL) break;
// FIXME : consider returned value?
onWidgetActivated( w, playerID );
}
break;
default:
return;
}
}
// -----------------------------------------------------------------------------
static EventHandler* event_handler_singleton = NULL;
EventHandler* EventHandler::get()
{
if (event_handler_singleton == NULL)
{
event_handler_singleton = new EventHandler();
}
return event_handler_singleton;
}
void EventHandler::deallocate()
{
delete event_handler_singleton;
event_handler_singleton = NULL;
} // deallocate
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
const bool NAVIGATION_DEBUG = false;
#if 0
#pragma mark -
#pragma mark Private methods
#endif
void EventHandler::navigateUp(const int playerID, Input::InputType type, const bool pressedDown)
{
//std::cout << "Naviagte up!\n";
IGUIElement *el = NULL/*, *first=NULL*/, *closest=NULL;
if (type == Input::IT_STICKBUTTON && !pressedDown)
return;
Widget* w = GUIEngine::getFocusForPlayer(playerID);
if (w != NULL)
{
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;
const bool stay_within_list = list->getSelectionID() > 0;
if (stay_within_list)
{
list->setSelectionID(list->getSelectionID()-1);
return;
}
else
{
list->setSelectionID(-1);
}
}
if (w != NULL && w->m_tab_up_root != -1)
{
Widget* up = GUIEngine::getWidget( w->m_tab_up_root );
assert( up != NULL );
el = up->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;
// 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++)
{
closest = GUIEngine::getGUIEnv()->getRootGUIElement()->getElementFromId(el->getTabOrder() - 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)
{
IGUIListBox* list = (IGUIListBox*)(closestWidget->m_element);
assert(list != NULL);
list->setSelected( list->getItemCount()-1 );
return;
}
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;
// if a dialog is shown, restrict to items in the dialog
if (ModalDialog::isADialogActive() && !ModalDialog::getCurrent()->isMyChild(closestWidget))
{
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
if (closestWidget->m_type == WTYPE_LIST)
{
IGUIListBox* list = (IGUIListBox*)(closestWidget->m_element);
assert(list != NULL);
list->setSelected(0);
}
found = true;
}
} // end for
}
if (!found)
{
if (NAVIGATION_DEBUG) std::cout << "Navigating down : wrap around\n";
// select the first widget
Widget* firstWidget = NULL;
if (ModalDialog::isADialogActive())
{
//std::cout << "w = ModalDialog::getCurrent()->getFirstWidget();\n";
firstWidget = ModalDialog::getCurrent()->getFirstWidget();
}
else
{
Screen* screen = GUIEngine::getCurrentScreen();
if (screen == NULL) return;
firstWidget = screen->getFirstWidget();
}
if (firstWidget != NULL) firstWidget->setFocusForPlayer(playerID);
}
}
// -----------------------------------------------------------------------------
void EventHandler::sendEventToUser(GUIEngine::Widget* widget, std::string& name, const int playerID)
{
if (ModalDialog::isADialogActive())
{
if (ModalDialog::getCurrent()->processEvent(widget->m_properties[PROP_ID]) == EVENT_BLOCK)
{
return;
}
}
if (getCurrentScreen() != NULL)
getCurrentScreen()->eventCallback(widget, name, playerID);
}
// -----------------------------------------------------------------------------
EventPropagation EventHandler::onWidgetActivated(GUIEngine::Widget* w, const int playerID)
{
if (w->m_deactivated) return EVENT_BLOCK;
Widget* parent = w->m_event_handler;
if (ModalDialog::isADialogActive() && (parent == NULL || parent->m_type != GUIEngine::WTYPE_RIBBON))
{
if (ModalDialog::getCurrent()->processEvent(w->m_properties[PROP_ID]) == EVENT_BLOCK)
{
return EVENT_BLOCK;
}
if (w->m_event_handler == NULL) return EVENT_LET;
}
//std::cout << "**** widget activated : " << w->m_properties[PROP_ID].c_str() << " ****" << std::endl;
if (w->m_event_handler != NULL)
{
/* Find all parents. Stop looping if a widget event handler's is itself, to not fall
in an infinite loop (this can happen e.g. in checkboxes, where they need to be
notified of clicks onto themselves so they can toggle their state. ) */
while (parent->m_event_handler != NULL && parent->m_event_handler != parent)
{
parent->transmitEvent(w, w->m_properties[PROP_ID], playerID);
parent = parent->m_event_handler;
}
if (parent->m_deactivated) return EVENT_BLOCK;
/* notify the found event event handler, and also notify the main callback if the
parent event handler says so */
if (parent->transmitEvent(w, w->m_properties[PROP_ID], playerID) == EVENT_LET)
{
sendEventToUser(parent, parent->m_properties[PROP_ID], playerID);
}
}
else
{
std::string id = w->m_properties[PROP_ID];
assert(w->ok());
if (w->transmitEvent(w, id, playerID) == EVENT_LET)
{
assert(w->ok());
sendEventToUser(w, id, playerID);
}
}
return EVENT_BLOCK;
}
// -----------------------------------------------------------------------------
EventPropagation EventHandler::onGUIEvent(const SEvent& event)
{
if (event.EventType == EET_GUI_EVENT)
{
if (event.GUIEvent.Caller == NULL) return EVENT_LET;
const s32 id = event.GUIEvent.Caller->getID();
switch (event.GUIEvent.EventType)
{
case EGET_BUTTON_CLICKED:
case EGET_SCROLL_BAR_CHANGED:
case EGET_CHECKBOX_CHANGED:
case EGET_LISTBOX_SELECTED_AGAIN:
{
Widget* w = GUIEngine::getWidget(id);
if (w == NULL) break;
if (w->m_deactivated)
{
GUIEngine::getCurrentScreen()->onDisabledItemClicked(w->m_properties[PROP_ID].c_str());
return EVENT_BLOCK;
}
w->onClick();
// These events are only triggered by mouse (or so I hope)
// The player that owns the mouser receives "game master" priviledges
return onWidgetActivated(w, PLAYER_ID_GAME_MASTER);
// These events are only triggered by keyboard/mouse (or so I hope...)
//const int playerID = input_manager->getPlayerKeyboardID();
//if (input_manager->masterPlayerOnly() && playerID != PLAYER_ID_GAME_MASTER) break;
//else if (playerID != -1) return onWidgetActivated(w, playerID);
//else break;
}
case EGET_ELEMENT_HOVERED:
{
Widget* w = GUIEngine::getWidget(id);
if (w == NULL) break;
if (!w->m_focusable) return GUIEngine::EVENT_BLOCK;
// When a modal dialog is shown, don't select widgets out of the dialog
if (ModalDialog::isADialogActive() && !ModalDialog::getCurrent()->isMyChild(w))
{
// check for parents too before discarding event
if (w->m_event_handler != NULL)
{
if (!ModalDialog::getCurrent()->isMyChild(w->m_event_handler))
{
break;
}
}
}
// select ribbons on hover
if (w->m_event_handler != NULL && w->m_event_handler->m_type == WTYPE_RIBBON)
{
// FIXME: don't make a special case for ribbon here, there should be a generic callback
// that all widgets may hook onto
RibbonWidget* ribbon = (RibbonWidget*)(w->m_event_handler);
if (ribbon == NULL) break;
// give the mouse "game master" priviledges
const int playerID = PLAYER_ID_GAME_MASTER; //input_manager->getPlayerKeyboardID();
if (playerID == -1) break;
if (input_manager->masterPlayerOnly() && playerID != PLAYER_ID_GAME_MASTER) break;
ribbon->mouseHovered(w, playerID);
if (ribbon->m_event_handler != NULL) ribbon->m_event_handler->mouseHovered(w, playerID);
ribbon->setFocusForPlayer(playerID);
}
else
{
// focus on hover for other widgets
// give the mouse "game master" priviledges
const int playerID = PLAYER_ID_GAME_MASTER; //input_manager->getPlayerKeyboardID();
if (input_manager->masterPlayerOnly() && playerID != PLAYER_ID_GAME_MASTER) break;
if (playerID != -1)
{
// lists don't like that combined with scrollbars
// (FIXME: find why instead of working around)
if (w->getType() != WTYPE_LIST)
{
w->setFocusForPlayer(playerID);
}
}
}
break;
}
/*
case EGET_ELEMENT_LEFT:
{
Widget* el = getWidget(id);
if(el == NULL) break;
break;
}
*/
case EGET_ELEMENT_FOCUSED:
{
Widget* w = GUIEngine::getWidget(id);
if (w == NULL) break;
// forbid list for gaining "irrLicht focus", then they will process key events and
// we don't want that since we do our own custom processing for keys
if (w->m_type == WTYPE_LIST)
{
// FIXME: fix that better
// cheap way to remove the focus from the element (nope, IGUIEnv::removeFocus doesn't work)
// Obviously will not work if the list is the first item of the screen.
IGUIElement* elem = getCurrentScreen()->getFirstWidget()->getIrrlichtElement();
if (elem->getType() == EGUIET_LIST_BOX)
{
elem = getCurrentScreen()->getLastWidget()->getIrrlichtElement();
assert(elem->getType() != EGUIET_LIST_BOX);
}
GUIEngine::getGUIEnv()->setFocus( elem );
return EVENT_BLOCK; // confirms to irrLicht that we processed it
}
break;
}
case EGET_LISTBOX_CHANGED:
{
Widget* w = GUIEngine::getWidget(id);
if (w == NULL) break;
assert(w->getType() == WTYPE_LIST);
const int playerID = input_manager->getPlayerKeyboardID();
if (input_manager->masterPlayerOnly() && playerID != PLAYER_ID_GAME_MASTER) break;
if (!w->isFocusedForPlayer(playerID)) w->setFocusForPlayer(playerID);
break;
}
case EGET_EDITBOX_ENTER:
{
// currently, enter pressed in text ctrl events can only happen in dialogs.
// FIXME : find a cleaner way to route the event to its proper location
if (ModalDialog::isADialogActive()) ModalDialog::onEnterPressed();
break;
}
default:
break;
} // end switch
}
/*
EGET_BUTTON_CLICKED, EGET_SCROLL_BAR_CHANGED, EGET_CHECKBOX_CHANGED, EGET_TAB_CHANGED,
EGET_MENU_ITEM_SELECTED, EGET_COMBO_BOX_CHANGED, EGET_SPINBOX_CHANGED, EGET_EDITBOX_ENTER,
EGET_LISTBOX_CHANGED, EGET_LISTBOX_SELECTED_AGAIN,
EGET_FILE_SELECTED, EGET_FILE_CHOOSE_DIALOG_CANCELLED,
EGET_MESSAGEBOX_YES, EGET_MESSAGEBOX_NO, EGET_MESSAGEBOX_OK, EGET_MESSAGEBOX_CANCEL,
EGET_TABLE_CHANGED, EGET_TABLE_HEADER_CHANGED, EGET_TABLE_SELECTED_AGAIN
EGET_ELEMENT_FOCUS_LOST, EGET_ELEMENT_FOCUSED, EGET_ELEMENT_HOVERED, EGET_ELEMENT_LEFT,
EGET_ELEMENT_CLOSED,
*/
return EVENT_LET;
}
// -----------------------------------------------------------------------------