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; }