Cleaned up event propagation code a lot to stop using different contradictory conventions, and to be easily read

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@4051 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria 2009-09-27 19:43:22 +00:00
parent e0d66bf543
commit 8b9d4bd2e7
15 changed files with 110 additions and 91 deletions

View File

@ -25,6 +25,7 @@
#include "input/input_manager.hpp"
using GUIEngine::EventHandler;
using GUIEngine::EventPropagation;
// -----------------------------------------------------------------------------
@ -47,13 +48,13 @@ bool EventHandler::OnEvent (const SEvent &event)
event.EventType != EET_JOYSTICK_INPUT_EVENT)
)
{
return onGUIEvent(event);
return onGUIEvent(event) == EVENT_BLOCK;
}
else
{
// FIXME : it's a bit unclean that all input events go trough the gui module
const bool blockPropagation = input_manager->input(event);
return blockPropagation;
const EventPropagation blockPropagation = input_manager->input(event);
return blockPropagation == EVENT_BLOCK;
}
// to shut up a warning. gcc is too stupid too see the code will never get here
@ -62,7 +63,7 @@ bool EventHandler::OnEvent (const SEvent &event)
// -----------------------------------------------------------------------------
bool EventHandler::onGUIEvent(const SEvent& event)
EventPropagation EventHandler::onGUIEvent(const SEvent& event)
{
if (event.EventType == EET_GUI_EVENT)
{
@ -90,10 +91,9 @@ bool EventHandler::onGUIEvent(const SEvent& event)
if (w->m_event_handler != NULL && w->m_event_handler->m_type == WTYPE_RIBBON)
{
RibbonWidget* ribbon = dynamic_cast<RibbonWidget*>(w->m_event_handler);
if(ribbon == NULL) break;
if(ribbon->mouseHovered(w))
transmitEvent(ribbon, ribbon->m_properties[PROP_ID]);
if(ribbon->m_event_handler != NULL) ribbon->m_event_handler->mouseHovered(w);
if (ribbon == NULL) break;
if (ribbon->mouseHovered(w) == EVENT_LET) transmitEvent(ribbon, ribbon->m_properties[PROP_ID]);
if (ribbon->m_event_handler != NULL) ribbon->m_event_handler->mouseHovered(w);
getGUIEnv()->setFocus(ribbon->m_element);
}
else
@ -146,17 +146,17 @@ bool EventHandler::onGUIEvent(const SEvent& event)
EGET_ELEMENT_FOCUS_LOST, EGET_ELEMENT_FOCUSED, EGET_ELEMENT_HOVERED, EGET_ELEMENT_LEFT,
EGET_ELEMENT_CLOSED,
*/
return false;
return EVENT_LET;
}
// -----------------------------------------------------------------------------
bool EventHandler::onWidgetActivated(GUIEngine::Widget* w, const int playerID)
EventPropagation EventHandler::onWidgetActivated(GUIEngine::Widget* w, const int playerID)
{
if (ModalDialog::isADialogActive())
{
if (ModalDialog::getCurrent()->processEvent(w->m_properties[PROP_ID])) return false;
if (w->m_event_handler == NULL) return false;
if (ModalDialog::getCurrent()->processEvent(w->m_properties[PROP_ID])) return EVENT_LET;
if (w->m_event_handler == NULL) return EVENT_LET;
}
std::cout << "**** widget activated : " << w->m_properties[PROP_ID].c_str() << " ****" << std::endl;
@ -176,12 +176,12 @@ bool EventHandler::onWidgetActivated(GUIEngine::Widget* w, const int playerID)
/* 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))
if (parent->transmitEvent(w, w->m_properties[PROP_ID], playerID) == EVENT_LET)
{
// notify modal dialog too
if (ModalDialog::isADialogActive())
{
if (ModalDialog::getCurrent()->processEvent(parent->m_properties[PROP_ID])) return false;
if (ModalDialog::getCurrent()->processEvent(parent->m_properties[PROP_ID])) return EVENT_LET;
}
transmitEvent(parent, parent->m_properties[PROP_ID]);
@ -189,7 +189,7 @@ bool EventHandler::onWidgetActivated(GUIEngine::Widget* w, const int playerID)
}
else transmitEvent(w, w->m_properties[PROP_ID]);
return true;
return EVENT_BLOCK;
}
// -----------------------------------------------------------------------------
@ -237,8 +237,7 @@ void EventHandler::processAction(const int action, const unsigned int value, Inp
}
if (widget_to_call->leftPressed(playerID))
transmitEvent(w, w->m_properties[PROP_ID]);
if (widget_to_call->leftPressed(playerID) == EVENT_LET) transmitEvent(w, w->m_properties[PROP_ID]);
}
break;
@ -271,8 +270,7 @@ void EventHandler::processAction(const int action, const unsigned int value, Inp
widget_to_call = widget_to_call->m_event_handler;
}
if (widget_to_call->rightPressed(playerID))
transmitEvent(widget_to_call, w->m_properties[PROP_ID]);
if (widget_to_call->rightPressed(playerID) == EVENT_LET) transmitEvent(widget_to_call, w->m_properties[PROP_ID]);
}
break;

View File

@ -31,6 +31,12 @@ using namespace gui;
namespace GUIEngine
{
enum EventPropagation
{
EVENT_BLOCK,
EVENT_LET
};
class Widget;
/**
@ -44,8 +50,8 @@ namespace GUIEngine
*/
class EventHandler : public IEventReceiver
{
bool onGUIEvent(const SEvent& event);
bool onWidgetActivated(Widget* w, const int playerID);
EventPropagation onGUIEvent(const 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);

View File

@ -22,6 +22,7 @@
#include <irrlicht.h>
#include <map>
#include "guiengine/event_handler.hpp"
#include "guiengine/skin.hpp"
#include "utils/constants.hpp"
#include "utils/ptr_vector.hpp"
@ -120,16 +121,16 @@ namespace GUIEngine
* Returns 'true' if main event handler should be notified of a change.
* Override in children to be notified of left/right events.
*/
virtual bool rightPressed(const int playerID) { return false; }
virtual bool leftPressed(const int playerID) { return false; }
virtual EventPropagation rightPressed(const int playerID) { return EVENT_BLOCK; }
virtual EventPropagation leftPressed(const int playerID) { return EVENT_BLOCK; }
/** used when you set eventSupervisors - see m_event_handler explainations below
called when one of a widget's children is hovered.
Returns 'true' if main event handler should be notified of a change. */
virtual bool mouseHovered(Widget* child) { return false; }
virtual EventPropagation mouseHovered(Widget* child) { return EVENT_BLOCK; }
/** override in children if you need to know when the widget is focused. return whether to block event */
virtual bool focused(const int playerID) { isWithinATextBox = false; return false; }
virtual EventPropagation focused(const int playerID) { isWithinATextBox = false; return EVENT_LET; }
/**
* The XML loader stored coords in their raw string form inside this widget.
@ -283,7 +284,7 @@ namespace GUIEngine
this call. Must return whether main (GUI engine user) event callback should be notified or not.
Note that in the case of a hierarchy of widgets (with m_event_handler), only the topmost widget
of the chain decides whether the main handler is notified; return value is not read for others. */
virtual bool transmitEvent(Widget* w, std::string& originator, const int playerID) { return true; }
virtual EventPropagation transmitEvent(Widget* w, std::string& originator, const int playerID) { return EVENT_LET; }
/**
* Create and add the irrLicht widget(s) associated with this object.

View File

@ -38,11 +38,11 @@ void CheckBoxWidget::add()
m_element->setTabGroup(false);
}
// -----------------------------------------------------------------------------
bool CheckBoxWidget::transmitEvent(Widget* w, std::string& originator, const int playerID)
EventPropagation CheckBoxWidget::transmitEvent(Widget* w, std::string& originator, const int playerID)
{
/* toggle */
m_state = !m_state;
/* notify main event handler */
return true;
return EVENT_LET;
}

View File

@ -34,7 +34,7 @@ namespace GUIEngine
class CheckBoxWidget : public Widget
{
bool m_state;
bool transmitEvent(Widget* w, std::string& originator, const int playerID);
EventPropagation transmitEvent(Widget* w, std::string& originator, const int playerID);
public:
CheckBoxWidget();

View File

@ -324,7 +324,7 @@ void DynamicRibbonWidget::registerHoverListener(DynamicRibbonHoverListener* list
m_hover_listeners.push_back(listener);
}
// -----------------------------------------------------------------------------
bool DynamicRibbonWidget::rightPressed(const int playerID)
EventPropagation DynamicRibbonWidget::rightPressed(const int playerID)
{
RibbonWidget* w = getSelectedRibbon(playerID);
if (w != NULL)
@ -341,12 +341,12 @@ bool DynamicRibbonWidget::rightPressed(const int playerID)
}
}
if (m_rows[0].m_ribbon_type == RIBBON_TOOLBAR) return false;
if (m_rows[0].m_ribbon_type == RIBBON_TOOLBAR) return EVENT_BLOCK;
return true;
return EVENT_LET;
}
// -----------------------------------------------------------------------------
bool DynamicRibbonWidget::leftPressed(const int playerID)
EventPropagation DynamicRibbonWidget::leftPressed(const int playerID)
{
RibbonWidget* w = getSelectedRibbon(playerID);
if (w != NULL)
@ -363,22 +363,22 @@ bool DynamicRibbonWidget::leftPressed(const int playerID)
}
if (m_rows[0].m_ribbon_type == RIBBON_TOOLBAR) return false;
if (m_rows[0].m_ribbon_type == RIBBON_TOOLBAR) return EVENT_BLOCK;
return true;
return EVENT_LET;
}
// -----------------------------------------------------------------------------
bool DynamicRibbonWidget::transmitEvent(Widget* w, std::string& originator, const int playerID)
EventPropagation DynamicRibbonWidget::transmitEvent(Widget* w, std::string& originator, const int playerID)
{
if (originator=="left")
{
scroll(-1);
return false;
return EVENT_BLOCK;
}
if (originator=="right")
{
scroll(1);
return false;
return EVENT_BLOCK;
}
// find selection in current ribbon
@ -392,10 +392,10 @@ bool DynamicRibbonWidget::transmitEvent(Widget* w, std::string& originator, cons
}
}
return true;
return EVENT_LET;
}
// -----------------------------------------------------------------------------
bool DynamicRibbonWidget::mouseHovered(Widget* child)
EventPropagation DynamicRibbonWidget::mouseHovered(Widget* child)
{
updateLabel();
propagateSelection();
@ -413,10 +413,10 @@ bool DynamicRibbonWidget::mouseHovered(Widget* child)
}
}
return false;
return EVENT_BLOCK;
}
// -----------------------------------------------------------------------------
bool DynamicRibbonWidget::focused(const int playerID)
EventPropagation DynamicRibbonWidget::focused(const int playerID)
{
Widget::focused(playerID);
updateLabel();
@ -428,7 +428,7 @@ bool DynamicRibbonWidget::focused(const int playerID)
getSelectedRibbon(playerID)->getSelectionText(playerID), playerID);
}
return false;
return EVENT_LET;
}
// -----------------------------------------------------------------------------
void DynamicRibbonWidget::onRowChange(RibbonWidget* row, const int playerID)

View File

@ -124,7 +124,7 @@ namespace GUIEngine
void propagateSelection();
/** Callback called widget is focused */
bool focused(const int playerID);
EventPropagation focused(const int playerID);
/** Removes all previously added contents icons, and re-adds them (calculating the new amount) */
void setSubElements();
@ -138,8 +138,8 @@ namespace GUIEngine
/** Callbacks */
void onRowChange(RibbonWidget* row, const int playerID);
void add();
bool mouseHovered(Widget* child);
bool transmitEvent(Widget* w, std::string& originator, const int playerID);
EventPropagation mouseHovered(Widget* child);
EventPropagation transmitEvent(Widget* w, std::string& originator, const int playerID);
public:
DynamicRibbonWidget(const bool combo=false, const int max_rows=4);
@ -160,10 +160,10 @@ namespace GUIEngine
void registerHoverListener(DynamicRibbonHoverListener* listener);
/** Called when right key is pressed */
bool rightPressed(const int playerID);
EventPropagation rightPressed(const int playerID);
/** Called when left key is pressed */
bool leftPressed(const int playerID);
EventPropagation leftPressed(const int playerID);
/** Updates icons/labels given current items and scrolling offset, taking care of resizing
the dynamic ribbon if the number of items changed */

View File

@ -217,7 +217,7 @@ void RibbonWidget::select(std::string item, const int playerID)
}
// -----------------------------------------------------------------------------
bool RibbonWidget::rightPressed(const int playerID)
EventPropagation RibbonWidget::rightPressed(const int playerID)
{
m_selection[playerID]++;
if (m_selection[playerID] >= m_children.size())
@ -232,10 +232,11 @@ bool RibbonWidget::rightPressed(const int playerID)
updateSelection();
if (playerID == 0) m_focus = m_children.get(m_selection[playerID]);
return m_ribbon_type != RIBBON_TOOLBAR;
if (m_ribbon_type != RIBBON_TOOLBAR) return EVENT_LET;
else return EVENT_BLOCK;
}
// -----------------------------------------------------------------------------
bool RibbonWidget::leftPressed(const int playerID)
EventPropagation RibbonWidget::leftPressed(const int playerID)
{
m_selection[playerID]--;
if (m_selection[playerID] < 0)
@ -251,14 +252,15 @@ bool RibbonWidget::leftPressed(const int playerID)
if (playerID == 0) m_focus = m_children.get(m_selection[playerID]);
return m_ribbon_type != RIBBON_TOOLBAR;
if (m_ribbon_type != RIBBON_TOOLBAR) return EVENT_LET;
else return EVENT_BLOCK;
}
// -----------------------------------------------------------------------------
bool RibbonWidget::focused(const int playerID)
EventPropagation RibbonWidget::focused(const int playerID)
{
Widget::focused(playerID);
if (m_children.size() < 1) return false; // empty ribbon
if (m_children.size() < 1) return EVENT_LET; // empty ribbon
if (m_focus == NULL && m_selection[playerID] != -1)
{
@ -273,10 +275,10 @@ bool RibbonWidget::focused(const int playerID)
((DynamicRibbonWidget*)m_event_handler)->onRowChange( this, playerID );
}
return false;
return EVENT_LET;
}
// -----------------------------------------------------------------------------
bool RibbonWidget::mouseHovered(Widget* child)
EventPropagation RibbonWidget::mouseHovered(Widget* child)
{
const int subbuttons_amount = m_children.size();
@ -287,13 +289,13 @@ bool RibbonWidget::mouseHovered(Widget* child)
if (m_children.get(i) == child)
{
// FIXME: don't hardcode player 0 there?
if (m_selection[0] == i) return false; // was already selected, don't send another event
if (m_selection[0] == i) return EVENT_BLOCK; // was already selected, don't send another event
if (m_ribbon_type == RIBBON_TOOLBAR) m_selection[0] = i; // don't change selection on hover for others
break;
}
}
updateSelection();
return false;
return EVENT_BLOCK;
}
// -----------------------------------------------------------------------------
@ -319,7 +321,7 @@ void RibbonWidget::updateSelection()
if (subbuttons_amount > 0 && m_ribbon_type == RIBBON_TOOLBAR) m_focus = m_children.get(m_selection[0]);
}
// -----------------------------------------------------------------------------
bool RibbonWidget::transmitEvent(Widget* w, std::string& originator, const int playerID)
EventPropagation RibbonWidget::transmitEvent(Widget* w, std::string& originator, const int playerID)
{
const int subbuttons_amount = m_children.size();
@ -337,7 +339,7 @@ bool RibbonWidget::transmitEvent(Widget* w, std::string& originator, const int p
// bring focus back to enclosing ribbon widget
GUIEngine::getGUIEnv()->setFocus(m_element);
return true;
return EVENT_LET;
}
// -----------------------------------------------------------------------------
void RibbonWidget::setLabel(const int id, irr::core::stringw new_name)

View File

@ -56,11 +56,11 @@ namespace GUIEngine
void updateSelection();
/** Callbacks */
bool rightPressed(const int playerID=0);
bool leftPressed(const int playerID=0);
bool mouseHovered(Widget* child);
bool transmitEvent(Widget* w, std::string& originator, const int playerID=0);
bool focused(const int playerID);
EventPropagation rightPressed(const int playerID=0);
EventPropagation leftPressed(const int playerID=0);
EventPropagation mouseHovered(Widget* child);
EventPropagation transmitEvent(Widget* w, std::string& originator, const int playerID=0);
EventPropagation focused(const int playerID);
ptr_vector<IGUIStaticText, REF> m_labels;

View File

@ -177,27 +177,27 @@ void SpinnerWidget::move(const int x, const int y, const int w, const int h)
}
// -----------------------------------------------------------------------------
bool SpinnerWidget::rightPressed(const int playerID)
EventPropagation SpinnerWidget::rightPressed(const int playerID)
{
std::cout << "Right pressed\n";
if (m_value+1 <= m_max) setValue(m_value+1);
return true;
return EVENT_LET;
}
// -----------------------------------------------------------------------------
bool SpinnerWidget::leftPressed(const int playerID)
EventPropagation SpinnerWidget::leftPressed(const int playerID)
{
std::cout << "Left pressed\n";
if (m_value-1 >= m_min) setValue(m_value-1);
return true;
return EVENT_LET;
}
// -----------------------------------------------------------------------------
bool SpinnerWidget::transmitEvent(Widget* w, std::string& originator, const int playerID)
EventPropagation SpinnerWidget::transmitEvent(Widget* w, std::string& originator, const int playerID)
{
if (originator == "left") leftPressed(playerID);
else if (originator == "right") rightPressed(playerID);
GUIEngine::getGUIEnv()->setFocus(m_element);
return true;
return EVENT_LET;
}
// -----------------------------------------------------------------------------
void SpinnerWidget::clearLabels()

View File

@ -38,9 +38,9 @@ namespace GUIEngine
bool m_graphical;
bool m_gauge;
bool transmitEvent(Widget* w, std::string& originator, const int playerID);
bool rightPressed(const int playerID);
bool leftPressed(const int playerID);
EventPropagation transmitEvent(Widget* w, std::string& originator, const int playerID);
EventPropagation rightPressed(const int playerID);
EventPropagation leftPressed(const int playerID);
public:
SpinnerWidget(const bool gauge=false);

View File

@ -43,7 +43,7 @@ namespace GUIEngine
void add();
void addItem(const char* item);
virtual bool focused(const int playerID) { isWithinATextBox = true; return false; }
virtual EventPropagation focused(const int playerID) { isWithinATextBox = true; return EVENT_LET; }
core::stringw getText() const;
};

View File

@ -45,6 +45,10 @@
#include "states_screens/state_manager.hpp"
InputManager *input_manager;
using GUIEngine::EventPropagation;
using GUIEngine::EVENT_LET;
using GUIEngine::EVENT_BLOCK;
//-----------------------------------------------------------------------------
/** Initialise input
*/
@ -381,7 +385,7 @@ void InputManager::input(Input::InputType type, int deviceID, int btnID, int axi
*
* Returns whether to halt the event's propagation here
*/
bool InputManager::input(const SEvent& event)
EventPropagation InputManager::input(const SEvent& event)
{
//const bool programaticallyGenerated = (event.UserEvent.UserData1 == 666 && event.UserEvent.UserData1 == 999);
@ -417,7 +421,7 @@ bool InputManager::input(const SEvent& event)
if (gp == NULL)
{
// Prevent null pointer crash
return true;
return EVENT_BLOCK;
}
for(int i=0; i<gp->m_button_count; i++)
@ -440,7 +444,7 @@ bool InputManager::input(const SEvent& event)
printf("Level %d: %s\n",
event.LogEvent.Level,event.LogEvent.Text);
}
return true;
return EVENT_BLOCK;
}
else if(event.EventType == EET_KEY_INPUT_EVENT)
{
@ -452,14 +456,14 @@ bool InputManager::input(const SEvent& event)
if (key == KEY_ESCAPE)
{
StateManager::get()->escapePressed();
return true;
return EVENT_BLOCK;
}
// 'backspace' in a text control must never be mapped, since user can be in a text
// area trying to erase text (and if it's mapped to rescue that would dismiss the
// dialog instead of erasing a single letter)
if (key == KEY_BACK && GUIEngine::isWithinATextBox)
{
return false;
return EVENT_LET;
}
input(Input::IT_KEYBOARD, 0, key,
@ -478,7 +482,7 @@ bool InputManager::input(const SEvent& event)
else
{
input(Input::IT_KEYBOARD, 0, key, 0, 0, programaticallyGenerated);
return true; // Don't propagate key up events
return EVENT_BLOCK; // Don't propagate key up events
}
}
#if 0 // in case we ever use mouse in-game...
@ -507,8 +511,15 @@ bool InputManager::input(const SEvent& event)
#endif
// block events in all modes but initial menus (except in text boxes to allow typing, and exceptm in modal dialogs in-game)
return getDeviceList()->playerAssignMode() != NO_ASSIGN && !GUIEngine::isWithinATextBox &&
(!GUIEngine::ModalDialog::isADialogActive() && StateManager::get()->getGameState() == GUIEngine::GAME);
if (getDeviceList()->playerAssignMode() != NO_ASSIGN && !GUIEngine::isWithinATextBox &&
(!GUIEngine::ModalDialog::isADialogActive() && StateManager::get()->getGameState() == GUIEngine::GAME))
{
return EVENT_BLOCK;
}
else
{
return EVENT_LET;
}
}
//-----------------------------------------------------------------------------

View File

@ -25,6 +25,7 @@
#include <irrlicht.h>
#include <map>
#include "guiengine/event_handler.hpp"
#include "input/input.hpp"
class DeviceManager;
@ -79,7 +80,7 @@ public:
// void initGamePadDevices();
//void input();
bool input(const irr::SEvent& event);
GUIEngine::EventPropagation input(const irr::SEvent& event);
DeviceManager* getDeviceList() { return m_device_manager; }

View File

@ -59,7 +59,7 @@ namespace KartSelectionScreen
{
int playerID;
virtual bool focused(const int playerID) ;
virtual EventPropagation focused(const int playerID) ;
public:
PlayerNameSpinner(const int playerID)
@ -502,9 +502,9 @@ bool playerJoin(InputDevice* device, bool firstPlayer)
// FIXME : player ID needs to be synced with active player list
PlayerKartWidget* newPlayer;
if (firstPlayer)
newPlayer = new PlayerKartWidget(aplayer, &rightarea, g_player_karts.size());//, rightarea.m_reserved_id);
newPlayer = new PlayerKartWidget(aplayer, &rightarea, g_player_karts.size(), rightarea.m_reserved_id);
else
newPlayer = new PlayerKartWidget(aplayer, &rightarea, g_player_karts.size());
newPlayer = new PlayerKartWidget(aplayer, &rightarea, g_player_karts.size(), rightarea.m_reserved_id);
getCurrentScreen()->manualAddWidget(newPlayer);
newPlayer->add();
@ -816,8 +816,8 @@ void renumberKarts()
#pragma mark -
#endif
// FIXME : clean this mess, this file should not contain so many classes
bool PlayerNameSpinner::focused(const int playerID)
// FIXME : clean this mess, this file should not contain so many classes
GUIEngine::EventPropagation PlayerNameSpinner::focused(const int playerID)
{
std::cout << "Player name spinner " << this->playerID << " focused by " << playerID << std::endl;
@ -841,7 +841,7 @@ bool PlayerNameSpinner::focused(const int playerID)
std::cout << "--> ID before : " << IDbefore << "; ID after : " << IDafter << std::endl;
return true; // block event
return GUIEngine::EVENT_BLOCK;
}
}
assert(false);
@ -849,7 +849,7 @@ bool PlayerNameSpinner::focused(const int playerID)
else
{
std::cout << "--> right spinner nothing to do\n";
return false;
return GUIEngine::EVENT_LET;
}
}