From 9a37cd2c2bf8661b3bc93f6b65bdc94f68e82947 Mon Sep 17 00:00:00 2001 From: Flakebi Date: Fri, 6 Jun 2014 22:23:52 +0200 Subject: [PATCH 1/3] Change focus cycle so invisible and deactivated widgets are skiped --- src/guiengine/event_handler.cpp | 205 +++++++------------------------- src/guiengine/event_handler.hpp | 3 +- 2 files changed, 46 insertions(+), 162 deletions(-) diff --git a/src/guiengine/event_handler.cpp b/src/guiengine/event_handler.cpp index cfcc0332c..5f493127f 100644 --- a/src/guiengine/event_handler.cpp +++ b/src/guiengine/event_handler.cpp @@ -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: @@ -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; @@ -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 @@ -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; } } @@ -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; + + if (NAVIGATION_DEBUG) + { + std::cout << "Navigating " << (reverse ? "up" : "down") << " to " << closest->getID() << std::endl; } - // when focusing a list by going up, select the last item of the list - assert (closestWidget != NULL); + assert(closestWidget != NULL); + + if (!closestWidget->isVisible() || !closestWidget->isActivated()) + continue; closestWidget->setFocusForPlayer(playerID); + // 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( list->getItemCount()-1 ); - return; + list->setSelectionID(reverse ? list->getItemCount() - 1 : 0); } found = true; - } } // end for - } if (!found) { if (NAVIGATION_DEBUG) - { - std::cout << "EventHandler::navigateUp : wrap around, selecting the last widget\n"; - } + std::cout << "EventHandler::navigat : wrap around\n"; - // select the last widget - Widget* lastWidget = NULL; + // select the last/first widget + Widget* wrapWidget = NULL; if (ModalDialog::isADialogActive()) { - lastWidget = ModalDialog::getCurrent()->getLastWidget(); + wrapWidget = reverse ? ModalDialog::getCurrent()->getLastWidget() : + ModalDialog::getCurrent()->getFirstWidget(); } else { Screen* screen = GUIEngine::getCurrentScreen(); if (screen == NULL) return; - lastWidget = screen->getLastWidget(); + wrapWidget = reverse ? screen->getLastWidget() : + screen->getFirstWidget(); } - 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); + if (wrapWidget != NULL) wrapWidget->setFocusForPlayer(playerID); } } diff --git a/src/guiengine/event_handler.hpp b/src/guiengine/event_handler.hpp index f4207f4e8..be31df84f 100644 --- a/src/guiengine/event_handler.hpp +++ b/src/guiengine/event_handler.hpp @@ -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 From bc2209284bc9bef1906e315aeff20cb266d3969a Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Thu, 12 Jun 2014 18:25:54 -0400 Subject: [PATCH 2/3] Some fixes with menu-cutscenes --- src/guiengine/abstract_state_manager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/guiengine/abstract_state_manager.cpp b/src/guiengine/abstract_state_manager.cpp index 69c4b3cb3..90ca4068f 100644 --- a/src/guiengine/abstract_state_manager.cpp +++ b/src/guiengine/abstract_state_manager.cpp @@ -160,6 +160,7 @@ void AbstractStateManager::replaceTopMostScreen(Screen* screen) getCurrentScreen()->tearDown(); m_menu_stack[m_menu_stack.size()-1] = name; + setGameState(MENU); switchToScreen(name.c_str()); // Send init event to new menu From e3a2246e25d33b21ccd327960073b248167b8630 Mon Sep 17 00:00:00 2001 From: Marianne Gagnon Date: Thu, 12 Jun 2014 18:43:20 -0400 Subject: [PATCH 3/3] More work on cutscene screens --- src/config/player_profile.hpp | 5 +- src/guiengine/abstract_state_manager.cpp | 4 +- src/guiengine/abstract_state_manager.hpp | 2 +- src/modes/cutscene_world.cpp | 62 ++++++++++++++++++++---- src/states_screens/feature_unlocked.cpp | 2 + src/states_screens/grand_prix_lose.cpp | 42 ---------------- 6 files changed, 62 insertions(+), 55 deletions(-) diff --git a/src/config/player_profile.hpp b/src/config/player_profile.hpp index a294d0a70..6625e211f 100644 --- a/src/config/player_profile.hpp +++ b/src/config/player_profile.hpp @@ -215,7 +215,10 @@ public: // ------------------------------------------------------------------------ bool isFirstTime() const { return m_story_mode_status->isFirstTime(); } // ------------------------------------------------------------------------ - void clearUnlocked() { m_story_mode_status->clearUnlocked(); } + void clearUnlocked() + { + m_story_mode_status->clearUnlocked(); + } // ------------------------------------------------------------------------ /** Returns the current challenge for this player. */ const ChallengeStatus* getCurrentChallengeStatus() const diff --git a/src/guiengine/abstract_state_manager.cpp b/src/guiengine/abstract_state_manager.cpp index 90ca4068f..3b7989370 100644 --- a/src/guiengine/abstract_state_manager.cpp +++ b/src/guiengine/abstract_state_manager.cpp @@ -138,7 +138,7 @@ void AbstractStateManager::pushScreen(Screen* screen) // ---------------------------------------------------------------------------- -void AbstractStateManager::replaceTopMostScreen(Screen* screen) +void AbstractStateManager::replaceTopMostScreen(Screen* screen, GUIEngine::GameState gameState) { //assert(m_game_mode != GAME); // you need to close any dialog before calling this @@ -160,7 +160,7 @@ void AbstractStateManager::replaceTopMostScreen(Screen* screen) getCurrentScreen()->tearDown(); m_menu_stack[m_menu_stack.size()-1] = name; - setGameState(MENU); + setGameState(gameState); switchToScreen(name.c_str()); // Send init event to new menu diff --git a/src/guiengine/abstract_state_manager.hpp b/src/guiengine/abstract_state_manager.hpp index e280103ac..b8ace0901 100644 --- a/src/guiengine/abstract_state_manager.hpp +++ b/src/guiengine/abstract_state_manager.hpp @@ -82,7 +82,7 @@ namespace GUIEngine * without displaying the second-topmost menu of the stack * in-between) */ - void replaceTopMostScreen(Screen* screen); + void replaceTopMostScreen(Screen* screen, GUIEngine::GameState gameState = GUIEngine::MENU); /** * \brief removes the menu at the top of the screens stack diff --git a/src/modes/cutscene_world.cpp b/src/modes/cutscene_world.cpp index ce878bf10..a998896e8 100644 --- a/src/modes/cutscene_world.cpp +++ b/src/modes/cutscene_world.cpp @@ -419,12 +419,11 @@ void CutsceneWorld::enterRaceOverState() // un-set the GP mode so that after unlocking, it doesn't try to continue the GP race_manager->setMajorMode(RaceManager::MAJOR_MODE_SINGLE); - if (PlayerManager::getCurrentPlayer() - ->getRecentlyCompletedChallenges().size() > 0) + std::vector unlocked = + PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges(); + if (unlocked.size() > 0) { - std::vector unlocked = - PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges(); - PlayerManager::getCurrentPlayer()->clearUnlocked(); + //PlayerManager::getCurrentPlayer()->clearUnlocked(); StateManager::get()->enterGameState(); race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE); @@ -443,12 +442,13 @@ void CutsceneWorld::enterRaceOverState() scene->addTrophy(race_manager->getDifficulty()); scene->findWhatWasUnlocked(race_manager->getDifficulty()); - StateManager::get()->replaceTopMostScreen(scene); + StateManager::get()->replaceTopMostScreen(scene, GUIEngine::INGAME_MENU); } else { if (race_manager->raceWasStartedFromOverworld()) { + //StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance()); OverWorld::enterOverWorld(); } else @@ -462,10 +462,54 @@ void CutsceneWorld::enterRaceOverState() // TODO: remove hardcoded knowledge of cutscenes, replace with scripting probably else if (m_parts.size() == 1 && m_parts[0] == "gplose") { + //race_manager->exitRace(); + //StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance()); + //if (race_manager->raceWasStartedFromOverworld()) + // OverWorld::enterOverWorld(); + race_manager->exitRace(); - StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance()); - if (race_manager->raceWasStartedFromOverworld()) - OverWorld::enterOverWorld(); + + // un-set the GP mode so that after unlocking, it doesn't try to continue the GP + race_manager->setMajorMode(RaceManager::MAJOR_MODE_SINGLE); + + std::vector unlocked = + PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges(); + if (unlocked.size() > 0) + { + //PlayerManager::getCurrentPlayer()->clearUnlocked(); + + StateManager::get()->enterGameState(); + race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE); + race_manager->setNumKarts(0); + race_manager->setNumPlayers(0); + race_manager->setNumLocalPlayers(0); + race_manager->startSingleRace("featunlocked", 999, false); + + FeatureUnlockedCutScene* scene = + FeatureUnlockedCutScene::getInstance(); + std::vector parts; + parts.push_back("featunlocked"); + ((CutsceneWorld*)World::getWorld())->setParts(parts); + + scene->addTrophy(race_manager->getDifficulty()); + scene->findWhatWasUnlocked(race_manager->getDifficulty()); + + StateManager::get()->replaceTopMostScreen(scene, GUIEngine::INGAME_MENU); + } + else + { + if (race_manager->raceWasStartedFromOverworld()) + { + //StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance()); + OverWorld::enterOverWorld(); + } + else + { + StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance()); + // we assume the main menu was pushed before showing this menu + //StateManager::get()->popMenu(); + } + } } // TODO: remove hardcoded knowledge of cutscenes, replace with scripting probably else if (race_manager->getTrackName() == "introcutscene" || diff --git a/src/states_screens/feature_unlocked.cpp b/src/states_screens/feature_unlocked.cpp index 624e99e0c..ab7c2df9f 100644 --- a/src/states_screens/feature_unlocked.cpp +++ b/src/states_screens/feature_unlocked.cpp @@ -346,6 +346,8 @@ void FeatureUnlockedCutScene::init() std::cerr << "Malformed unlocked goody!!!\n"; } } + + PlayerManager::getCurrentPlayer()->clearUnlocked(); } // init // ---------------------------------------------------------------------------- diff --git a/src/states_screens/grand_prix_lose.cpp b/src/states_screens/grand_prix_lose.cpp index 80ba7bfe9..f9bc459fd 100644 --- a/src/states_screens/grand_prix_lose.cpp +++ b/src/states_screens/grand_prix_lose.cpp @@ -109,48 +109,6 @@ void GrandPrixLose::onCutsceneEnd() m_kart_node[1] = NULL; m_kart_node[2] = NULL; m_kart_node[3] = NULL; - - // un-set the GP mode so that after unlocking, it doesn't try to continue the GP - race_manager->setMajorMode(RaceManager::MAJOR_MODE_SINGLE); - - std::vector unlocked = - PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges(); - if (unlocked.size() > 0) - { - race_manager->exitRace(); - - StateManager::get()->enterGameState(); - race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE); - race_manager->setNumKarts(0); - race_manager->setNumPlayers(0); - race_manager->setNumLocalPlayers(0); - race_manager->startSingleRace("featunlocked", 999, false); - - FeatureUnlockedCutScene* scene = - FeatureUnlockedCutScene::getInstance(); - std::vector parts; - parts.push_back("featunlocked"); - ((CutsceneWorld*)World::getWorld())->setParts(parts); - - scene->addTrophy(race_manager->getDifficulty()); - scene->findWhatWasUnlocked(race_manager->getDifficulty()); - - StateManager::get()->replaceTopMostScreen(scene); - PlayerManager::getCurrentPlayer()->clearUnlocked(); - } - else - { - if (race_manager->raceWasStartedFromOverworld()) - { - StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance()); - OverWorld::enterOverWorld(); - } - else - { - // we assume the main menu was pushed before showing this menu - StateManager::get()->popMenu(); - } - } } // -------------------------------------------------------------------------------------