diff --git a/crogine/include/crogine/ecs/systems/UISystem.hpp b/crogine/include/crogine/ecs/systems/UISystem.hpp index e3af87f88..fa6e0fdd8 100644 --- a/crogine/include/crogine/ecs/systems/UISystem.hpp +++ b/crogine/include/crogine/ecs/systems/UISystem.hpp @@ -211,9 +211,17 @@ namespace cro \param index The index of the input to select Note that this may not give expected results if multiple inputs have been manually assigned the same selection index with setSelectionIndex() + or the index is not in range of the group size - in which case prefer + selectByIndex() */ void selectAt(std::size_t index); + /*! + \brief Selects at a specific index if a UIInput component has been provided + with one via setSelectionIndex() - otherwise prefer selectAt() + */ + void selectByIndex(std::size_t index); + private: std::vector m_buttonCallbacks; diff --git a/crogine/src/ecs/systems/UISystem.cpp b/crogine/src/ecs/systems/UISystem.cpp index 883cfa36f..d7624fa05 100644 --- a/crogine/src/ecs/systems/UISystem.cpp +++ b/crogine/src/ecs/systems/UISystem.cpp @@ -548,6 +548,25 @@ void UISystem::selectAt(std::size_t index) } } +void UISystem::selectByIndex(std::size_t index) +{ + const auto& entities = m_groups[m_activeGroup]; + auto old = m_selectedIndex; + + do + { + m_selectedIndex = (m_selectedIndex + 1) % entities.size(); + } while (entities[m_selectedIndex].getComponent().getSelectionIndex() != index && m_selectedIndex != old); + + //and do selected callback + if (m_selectedIndex != old + && entities[m_selectedIndex].getComponent().enabled) + { + unselect(old); + select(m_selectedIndex); + } +} + //private glm::vec2 UISystem::toWorldCoords(std::int32_t x, std::int32_t y) { diff --git a/samples/golf/buildnumber.h b/samples/golf/buildnumber.h index 8a3307242..ad666a5ee 100644 --- a/samples/golf/buildnumber.h +++ b/samples/golf/buildnumber.h @@ -3,7 +3,7 @@ #ifndef BUILD_NUMBER_H_ #define BUILD_NUMBER_H_ -#define BUILDNUMBER 960 -#define BUILDNUMBER_STR "960" +#define BUILDNUMBER 970 +#define BUILDNUMBER_STR "970" #endif /* BUILD_NUMBER_H_ */ diff --git a/samples/golf/src/golf/LeaderboardState.cpp b/samples/golf/src/golf/LeaderboardState.cpp index d49cceaf6..8d7f12b49 100644 --- a/samples/golf/src/golf/LeaderboardState.cpp +++ b/samples/golf/src/golf/LeaderboardState.cpp @@ -535,7 +535,6 @@ void LeaderboardState::buildScene() e.getComponent().setColour(cro::Colour::Transparent); }); - //tab buttons entity = m_scene.createEntity(); entity.addComponent().setPosition({ 50.f, 45.f, 0.2f }); @@ -1266,6 +1265,19 @@ void LeaderboardState::refreshDisplay() void LeaderboardState::updateButtonIndices() { + const auto selectNext = [&](std::int32_t idx) + { + auto e = m_scene.createEntity(); + e.addComponent().active = true; + e.getComponent().function = + [&, idx](cro::Entity f, float) + { + m_scene.getSystem()->selectByIndex(idx); + f.getComponent().active = false; + m_scene.destroyEntity(f); + }; + }; + switch (m_displayContext.boardIndex) { default: break; @@ -1287,6 +1299,8 @@ void LeaderboardState::updateButtonIndices() m_buttons[DynamicButton::Close].getComponent().setNextIndex(ButtonID::HIO, ButtonID::Nearest); m_buttons[DynamicButton::Close].getComponent().setPrevIndex(ButtonID::Streak, ButtonID::DateRange); + + selectNext(ButtonID::HIO); break; case BoardIndex::Hio: m_buttons[DynamicButton::Course].getComponent().setNextIndex(ButtonID::Rank, ButtonID::Rank); @@ -1306,6 +1320,8 @@ void LeaderboardState::updateButtonIndices() m_buttons[DynamicButton::Close].getComponent().setNextIndex(ButtonID::Course, ButtonID::Nearest); m_buttons[DynamicButton::Close].getComponent().setPrevIndex(ButtonID::Streak, ButtonID::DateRange); + + selectNext(ButtonID::Rank); break; case BoardIndex::Rank: m_buttons[DynamicButton::Course].getComponent().setNextIndex(ButtonID::HIO, ButtonID::HIO); @@ -1325,6 +1341,8 @@ void LeaderboardState::updateButtonIndices() m_buttons[DynamicButton::Close].getComponent().setNextIndex(ButtonID::Course, ButtonID::Nearest); m_buttons[DynamicButton::Close].getComponent().setPrevIndex(ButtonID::Streak, ButtonID::DateRange); + + selectNext(ButtonID::Streak); break; case BoardIndex::Streak: m_buttons[DynamicButton::Course].getComponent().setNextIndex(ButtonID::HIO, ButtonID::HIO); @@ -1344,6 +1362,8 @@ void LeaderboardState::updateButtonIndices() m_buttons[DynamicButton::Close].getComponent().setNextIndex(ButtonID::Course, ButtonID::Nearest); m_buttons[DynamicButton::Close].getComponent().setPrevIndex(ButtonID::Rank, ButtonID::DateRange); + + selectNext(ButtonID::Course); break; } } diff --git a/samples/golf/src/golf/MenuCreation.cpp b/samples/golf/src/golf/MenuCreation.cpp index 45fe99d94..075713932 100644 --- a/samples/golf/src/golf/MenuCreation.cpp +++ b/samples/golf/src/golf/MenuCreation.cpp @@ -1629,10 +1629,10 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st entity.addComponent().area = bounds; entity.getComponent().setGroup(MenuID::Lobby); entity.getComponent().setSelectionIndex(RulesClubset); - //TODO update this if hosting + entity.getComponent().setNextIndex(LobbyInfoA, LobbyInfoA); entity.getComponent().setPrevIndex(LobbyCourseA, LobbyCourseA); - + m_lobbyButtonContext.rulesClubset = entity; entity.getComponent().callbacks[cro::UIInput::Selected] = m_courseSelectCallbacks.selectHighlight; entity.getComponent().callbacks[cro::UIInput::Unselected] = m_courseSelectCallbacks.unselectHighlight; @@ -1654,7 +1654,20 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st //updates start/quit buttons with correct navigation indices static std::function navigationUpdate; + navigationUpdate = nullptr; //we're using nasty static hack so make sure to reset this + const auto selectNext = [&](std::int32_t idx) + { + auto e = m_uiScene.createEntity(); + e.addComponent().active = true; + e.getComponent().function = + [&, idx](cro::Entity f, float) + { + m_uiScene.getSystem()->selectByIndex(idx); + f.getComponent().active = false; + m_uiScene.destroyEntity(f); + }; + }; //button for course selection entity = m_uiScene.createEntity(); @@ -1673,7 +1686,7 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st entity.getComponent().callbacks[cro::UIInput::Selected] = m_courseSelectCallbacks.selectHighlight; entity.getComponent().callbacks[cro::UIInput::Unselected] = m_courseSelectCallbacks.unselectHighlight; entity.getComponent().callbacks[cro::UIInput::ButtonUp] = m_uiScene.getSystem()->addCallback( - [&](cro::Entity, const cro::ButtonEvent& evt) + [&, selectNext](cro::Entity, const cro::ButtonEvent& evt) { if (activated(evt)) { @@ -1684,6 +1697,8 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st m_uiScene.getActiveCamera().getComponent().active = true; //forces a visibility refresh navigationUpdate(LobbyCourseA); + + selectNext(LobbyRulesA); } } ); @@ -1691,6 +1706,7 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st entity.addComponent().active = true; entity.getComponent().function = ruleButtonEnable; bgEnt.getComponent().addChild(entity.getComponent()); + m_lobbyButtonContext.lobbyCourseA = entity; //button for lobby info entity = m_uiScene.createEntity(); @@ -1709,7 +1725,7 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st entity.getComponent().callbacks[cro::UIInput::Selected] = m_courseSelectCallbacks.selectHighlight; entity.getComponent().callbacks[cro::UIInput::Unselected] = m_courseSelectCallbacks.unselectHighlight; entity.getComponent().callbacks[cro::UIInput::ButtonUp] = m_uiScene.getSystem()->addCallback( - [&](cro::Entity, const cro::ButtonEvent& evt) + [&, selectNext](cro::Entity, const cro::ButtonEvent& evt) { if (activated(evt)) { @@ -1720,6 +1736,8 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st m_uiScene.getActiveCamera().getComponent().active = true; //forces a visibility refresh navigationUpdate(LobbyInfoA); + + selectNext(LobbyCourseB); } } ); @@ -1727,7 +1745,7 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st entity.addComponent().active = true; entity.getComponent().function = ruleButtonEnable; bgEnt.getComponent().addChild(entity.getComponent()); - + m_lobbyButtonContext.lobbyInfoA = entity; //display lobby members - updateLobbyAvatars() adds the text ents to this. @@ -1841,7 +1859,7 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st entity.getComponent().callbacks[cro::UIInput::Selected] = m_courseSelectCallbacks.selectHighlight; entity.getComponent().callbacks[cro::UIInput::Unselected] = m_courseSelectCallbacks.unselectHighlight; entity.getComponent().callbacks[cro::UIInput::ButtonUp] = m_uiScene.getSystem()->addCallback( - [&](cro::Entity, const cro::ButtonEvent& evt) + [&, selectNext](cro::Entity, const cro::ButtonEvent& evt) { if (activated(evt)) { @@ -1852,6 +1870,8 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st m_uiScene.getActiveCamera().getComponent().active = true; //forces a visibility refresh navigationUpdate(LobbyRulesA); + + selectNext(LobbyCourseA); } } ); @@ -1859,6 +1879,7 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st entity.addComponent().active = true; entity.getComponent().function = courseButtonEnable; thumbBgEnt.getComponent().addChild(entity.getComponent()); + m_lobbyButtonContext.lobbyRulesA = entity; //button for info page entity = m_uiScene.createEntity(); @@ -1877,7 +1898,7 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st entity.getComponent().callbacks[cro::UIInput::Selected] = m_courseSelectCallbacks.selectHighlight; entity.getComponent().callbacks[cro::UIInput::Unselected] = m_courseSelectCallbacks.unselectHighlight; entity.getComponent().callbacks[cro::UIInput::ButtonUp] = m_uiScene.getSystem()->addCallback( - [&](cro::Entity, const cro::ButtonEvent& evt) + [&, selectNext](cro::Entity, const cro::ButtonEvent& evt) { if (activated(evt)) { @@ -1888,6 +1909,8 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st m_uiScene.getActiveCamera().getComponent().active = true; //forces a visibility refresh navigationUpdate(LobbyInfoB); + + selectNext(LobbyCourseB); } } ); @@ -1895,7 +1918,7 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st entity.addComponent().active = true; entity.getComponent().function = courseButtonEnable; thumbBgEnt.getComponent().addChild(entity.getComponent()); - + m_lobbyButtonContext.lobbyInfoB = entity; //course title @@ -1965,7 +1988,7 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st entity.getComponent().callbacks[cro::UIInput::Selected] = m_courseSelectCallbacks.selectHighlight; entity.getComponent().callbacks[cro::UIInput::Unselected] = m_courseSelectCallbacks.unselectHighlight; entity.getComponent().callbacks[cro::UIInput::ButtonUp] = m_uiScene.getSystem()->addCallback( - [&](cro::Entity, const cro::ButtonEvent& evt) + [&, selectNext](cro::Entity, const cro::ButtonEvent& evt) { if (activated(evt)) { @@ -1976,6 +1999,8 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st m_uiScene.getActiveCamera().getComponent().active = true; //forces a visibility refresh navigationUpdate(LobbyRulesB); + + selectNext(LobbyCourseA); } } ); @@ -1983,6 +2008,7 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st entity.addComponent().active = true; entity.getComponent().function = infoButtonEnable; infoBgEnt.getComponent().addChild(entity.getComponent()); + m_lobbyButtonContext.lobbyRulesB = entity; //button for course selection entity = m_uiScene.createEntity(); @@ -2001,7 +2027,7 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st entity.getComponent().callbacks[cro::UIInput::Selected] = m_courseSelectCallbacks.selectHighlight; entity.getComponent().callbacks[cro::UIInput::Unselected] = m_courseSelectCallbacks.unselectHighlight; entity.getComponent().callbacks[cro::UIInput::ButtonUp] = m_uiScene.getSystem()->addCallback( - [&](cro::Entity, const cro::ButtonEvent& evt) + [&, selectNext](cro::Entity, const cro::ButtonEvent& evt) { if (activated(evt)) { @@ -2012,6 +2038,8 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st m_uiScene.getActiveCamera().getComponent().active = true; //forces a visibility refresh navigationUpdate(LobbyCourseB); + + selectNext(LobbyRulesA); } } ); @@ -2036,6 +2064,7 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st entity.getComponent().setPrevIndex(LobbyCourseB, LobbyCourseB); // and this entity.getComponent().callbacks[cro::UIInput::Selected] = m_courseSelectCallbacks.selectHighlight; entity.getComponent().callbacks[cro::UIInput::Unselected] = m_courseSelectCallbacks.unselectHighlight; +#ifdef USE_GNS entity.getComponent().callbacks[cro::UIInput::ButtonUp] = m_uiScene.getSystem()->addCallback( [&](cro::Entity, const cro::ButtonEvent& evt) { @@ -2046,10 +2075,12 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st } } ); +#endif entity.addComponent().ID = CommandID::Menu::UIElement; entity.addComponent().active = true; entity.getComponent().function = infoButtonEnable; infoBgEnt.getComponent().addChild(entity.getComponent()); + m_lobbyButtonContext.infoLeaderboard = entity; //banner entity = m_uiScene.createEntity(); @@ -2431,28 +2462,35 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st auto lobbyStart = entity; - navigationUpdate = [lobbyQuit, lobbyStart](std::int32_t callerID) mutable + navigationUpdate = [&, lobbyQuit, lobbyStart](std::int32_t callerID) mutable { switch (callerID) { default: break; + //we can pair these up because they're switching to the same menu case LobbyCourseA: - - break; - case LobbyRulesA: - - break; - case LobbyInfoA: - - break; case LobbyCourseB: + lobbyQuit.getComponent().setNextIndex(LobbyStart, LobbyStart); + lobbyQuit.getComponent().setPrevIndex(LobbyStart, LobbyRulesA); + lobbyStart.getComponent().setNextIndex(LobbyQuit, LobbyQuit); + lobbyStart.getComponent().setPrevIndex(LobbyQuit, LobbyInfoB); break; + case LobbyRulesA: case LobbyRulesB: + lobbyQuit.getComponent().setNextIndex(LobbyStart, m_sharedData.hosting ? RulesPrevious : LobbyStart); + lobbyQuit.getComponent().setPrevIndex(LobbyStart, LobbyCourseA); + lobbyStart.getComponent().setNextIndex(LobbyQuit, m_sharedData.hosting ? RulesNext : LobbyQuit); + lobbyStart.getComponent().setPrevIndex(LobbyQuit, LobbyInfoA); break; + case LobbyInfoA: case LobbyInfoB: + lobbyQuit.getComponent().setNextIndex(LobbyStart, LobbyStart); + lobbyQuit.getComponent().setPrevIndex(LobbyStart, LobbyCourseB); + lobbyStart.getComponent().setNextIndex(LobbyQuit, m_lobbyButtonContext.hasScoreCard ? InfoScorecard : LobbyQuit); + lobbyStart.getComponent().setPrevIndex(LobbyQuit, LobbyRulesB); break; } }; @@ -2603,6 +2641,8 @@ void MenuState::createLobbyMenu(cro::Entity parent, std::uint32_t mouseEnter, st }; bannerEnt.getComponent().addChild(entity.getComponent()); + + refreshLobbyButtons(); } void MenuState::updateLobbyData(const net::NetEvent& evt) @@ -3083,8 +3123,8 @@ void MenuState::addCourseSelectButtons() checkboxEnt.addComponent().area = bounds; checkboxEnt.getComponent().setGroup(MenuID::Lobby); checkboxEnt.getComponent().setSelectionIndex(CourseFriendsOnly); - checkboxEnt.getComponent().setNextIndex(CourseHolePrev, LobbyInfoB); - checkboxEnt.getComponent().setPrevIndex(CourseHoleNext, CourseCPUSkip); + checkboxEnt.getComponent().setNextIndex(CoursePrev, LobbyInfoB); + checkboxEnt.getComponent().setPrevIndex(CourseNext, CourseCPUSkip); checkboxEnt.getComponent().callbacks[cro::UIInput::Selected] = m_courseSelectCallbacks.selectHighlight; checkboxEnt.getComponent().callbacks[cro::UIInput::Unselected] = m_courseSelectCallbacks.unselectHighlight; checkboxEnt.getComponent().callbacks[cro::UIInput::ButtonUp] = m_courseSelectCallbacks.toggleFriendsOnly; @@ -3122,7 +3162,7 @@ void MenuState::addCourseSelectButtons() labelEnt.addComponent().area = bounds; labelEnt.getComponent().setGroup(MenuID::Lobby); labelEnt.getComponent().setSelectionIndex(CourseInviteFriend); - labelEnt.getComponent().setNextIndex(LobbyRulesA, LobbyQuit); + labelEnt.getComponent().setNextIndex(LobbyRulesA, LobbyRulesA); labelEnt.getComponent().setPrevIndex(LobbyInfoB, CourseHolePrev); labelEnt.getComponent().callbacks[cro::UIInput::Selected] = m_courseSelectCallbacks.selectText; labelEnt.getComponent().callbacks[cro::UIInput::Unselected] = m_courseSelectCallbacks.unselectText; @@ -3163,7 +3203,11 @@ void MenuState::addCourseSelectButtons() buttonEnt.getComponent().setGroup(MenuID::Lobby); buttonEnt.getComponent().setSelectionIndex(CoursePrev); buttonEnt.getComponent().setNextIndex(CourseNext, CourseHolePrev); +#ifdef USE_GNS + buttonEnt.getComponent().setPrevIndex(CourseFriendsOnly, LobbyQuit); +#else buttonEnt.getComponent().setPrevIndex(CourseCPUSkip, LobbyQuit); +#endif buttonEnt.getComponent().callbacks[cro::UIInput::Selected] = m_courseSelectCallbacks.selectHighlight; buttonEnt.getComponent().callbacks[cro::UIInput::Unselected] = m_courseSelectCallbacks.unselectHighlight; buttonEnt.getComponent().callbacks[cro::UIInput::ButtonUp] = m_courseSelectCallbacks.prevCourse; @@ -3188,7 +3232,11 @@ void MenuState::addCourseSelectButtons() buttonEnt.addComponent().area = bounds; buttonEnt.getComponent().setGroup(MenuID::Lobby); buttonEnt.getComponent().setSelectionIndex(CourseNext); +#ifdef USE_GNS + buttonEnt.getComponent().setNextIndex(CourseFriendsOnly, CourseHoleNext); +#else buttonEnt.getComponent().setNextIndex(CourseCPUSkip, CourseHoleNext); +#endif buttonEnt.getComponent().setPrevIndex(CoursePrev, LobbyRulesA); buttonEnt.getComponent().callbacks[cro::UIInput::Selected] = m_courseSelectCallbacks.selectHighlight; buttonEnt.getComponent().callbacks[cro::UIInput::Unselected] = m_courseSelectCallbacks.unselectHighlight; @@ -4142,6 +4190,8 @@ void MenuState::createPreviousScoreCard() m_lobbyWindowEntities[LobbyEntityID::Info].getComponent().getScale().y != 0.f; }; m_lobbyWindowEntities[LobbyEntityID::Info].getComponent().addChild(entity.getComponent()); + + m_lobbyButtonContext.hasScoreCard = true; } void MenuState::togglePreviousScoreCard() @@ -4174,4 +4224,69 @@ void MenuState::togglePreviousScoreCard() m_lobbyWindowEntities[LobbyEntityID::Scorecard].getComponent().active = true; } } +} + +void MenuState::refreshLobbyButtons() +{ + if (m_sharedData.hosting) + { + m_lobbyButtonContext.lobbyCourseA.getComponent().setNextIndex(LobbyInfoA, LobbyQuit); + m_lobbyButtonContext.lobbyCourseA.getComponent().setPrevIndex(LobbyInfoA, Social::getClubLevel() ? RulesClubset : RulesGimmePrev); + + m_lobbyButtonContext.lobbyInfoA.getComponent().setNextIndex(LobbyCourseA, LobbyStart); + m_lobbyButtonContext.lobbyInfoA.getComponent().setPrevIndex(LobbyCourseA, Social::getClubLevel() ? RulesClubset : RulesGimmeNext); + + m_lobbyButtonContext.lobbyInfoB.getComponent().setNextIndex(LobbyRulesA, LobbyStart); +#ifdef USE_GNS + m_lobbyButtonContext.lobbyInfoB.getComponent().setPrevIndex(LobbyRulesA, CourseFriendsOnly); +#else + m_lobbyButtonContext.lobbyInfoB.getComponent().setPrevIndex(LobbyRulesA, CourseCPUSkip); +#endif + + m_lobbyButtonContext.lobbyRulesA.getComponent().setNextIndex(LobbyInfoB, LobbyQuit); + m_lobbyButtonContext.lobbyRulesA.getComponent().setPrevIndex(LobbyInfoB, CourseNext); + + if (m_lobbyButtonContext.rulesClubset.isValid()) + { + m_lobbyButtonContext.rulesClubset.getComponent().setNextIndex(LobbyInfoA, LobbyInfoA); + m_lobbyButtonContext.rulesClubset.getComponent().setPrevIndex(LobbyCourseA, RulesGimmePrev); + } + } + else + { + m_lobbyButtonContext.lobbyCourseA.getComponent().setNextIndex(LobbyInfoA, LobbyQuit); + m_lobbyButtonContext.lobbyCourseA.getComponent().setPrevIndex(LobbyInfoA, LobbyQuit); + + m_lobbyButtonContext.lobbyInfoA.getComponent().setNextIndex(LobbyCourseA, LobbyStart); + m_lobbyButtonContext.lobbyInfoA.getComponent().setPrevIndex(LobbyCourseA, LobbyStart); + + m_lobbyButtonContext.lobbyInfoB.getComponent().setNextIndex(LobbyRulesA, LobbyStart); + m_lobbyButtonContext.lobbyInfoB.getComponent().setPrevIndex(LobbyRulesA, LobbyStart); + + m_lobbyButtonContext.lobbyRulesA.getComponent().setNextIndex(LobbyInfoB, LobbyQuit); + m_lobbyButtonContext.lobbyRulesA.getComponent().setPrevIndex(LobbyInfoB, LobbyQuit); + + if (m_lobbyButtonContext.rulesClubset.isValid()) + { + m_lobbyButtonContext.rulesClubset.getComponent().setNextIndex(LobbyInfoA, LobbyInfoA); + m_lobbyButtonContext.rulesClubset.getComponent().setPrevIndex(LobbyCourseA, LobbyCourseA); + } + } + + if (m_lobbyButtonContext.hasScoreCard) + { + m_lobbyButtonContext.lobbyRulesB.getComponent().setNextIndex(LobbyCourseB, LobbyStart); + m_lobbyButtonContext.lobbyRulesB.getComponent().setPrevIndex(LobbyCourseB, InfoScorecard); + + m_lobbyButtonContext.infoLeaderboard.getComponent().setNextIndex(InfoScorecard, LobbyCourseB); + m_lobbyButtonContext.infoLeaderboard.getComponent().setPrevIndex(InfoScorecard, LobbyQuit); + } + else + { + m_lobbyButtonContext.lobbyRulesB.getComponent().setNextIndex(LobbyCourseB, LobbyStart); + m_lobbyButtonContext.lobbyRulesB.getComponent().setPrevIndex(LobbyCourseB, LobbyStart); + + m_lobbyButtonContext.infoLeaderboard.getComponent().setNextIndex(LobbyRulesB, LobbyCourseB); + m_lobbyButtonContext.infoLeaderboard.getComponent().setPrevIndex(LobbyRulesB, LobbyQuit); + } } \ No newline at end of file diff --git a/samples/golf/src/golf/MenuState.cpp b/samples/golf/src/golf/MenuState.cpp index 98b97977c..a553914aa 100644 --- a/samples/golf/src/golf/MenuState.cpp +++ b/samples/golf/src/golf/MenuState.cpp @@ -298,7 +298,7 @@ MenuState::MenuState(cro::StateStack& stack, cro::State::Context context, Shared spriteID = SpriteID::ReadyUp; connectionString = "Connected to: " + m_sharedData.targetIP + ":" + std::to_string(ConstVal::GamePort); } - + refreshLobbyButtons(); //makes sure indices point to correct target cmd.targetFlags = CommandID::Menu::ReadyButton; cmd.action = [&, spriteID](cro::Entity e, float) @@ -2008,6 +2008,7 @@ void MenuState::finaliseGameCreate(const MatchMaking::Message& msgData) //enable the course selection in the lobby addCourseSelectButtons(); + refreshLobbyButtons(); //send a UI refresh to correctly place buttons glm::vec2 size(GolfGame::getActiveTarget()->getSize()); @@ -2075,6 +2076,8 @@ void MenuState::finaliseGameJoin(const MatchMaking::Message& data) m_uiScene.destroyEntity(e); }; m_uiScene.getSystem()->sendCommand(cmd); + + refreshLobbyButtons(); //makes sure buttons point to correct target when navigating } void MenuState::beginTextEdit(cro::Entity stringEnt, cro::String* dst, std::size_t maxChars) diff --git a/samples/golf/src/golf/MenuState.hpp b/samples/golf/src/golf/MenuState.hpp index 1081dfcb2..53567673d 100644 --- a/samples/golf/src/golf/MenuState.hpp +++ b/samples/golf/src/golf/MenuState.hpp @@ -320,6 +320,22 @@ class MenuState final : public cro::State, public cro::GuiClient, public cro::Co void setProfileIndex(std::size_t); void refreshProfileFlyout(); + //allows updating the target indices + //of lobby buttons based on whether the + //user is hosting or not + struct LobbyButtonContext final + { + cro::Entity infoLeaderboard; + cro::Entity lobbyCourseA; + cro::Entity lobbyInfoA; + cro::Entity lobbyInfoB; + cro::Entity lobbyRulesA; + cro::Entity lobbyRulesB; + cro::Entity rulesClubset; + bool hasScoreCard = false; + }m_lobbyButtonContext; + void refreshLobbyButtons(); + //message handlers for completing connection void finaliseGameCreate(const MatchMaking::Message&); void finaliseGameJoin(const MatchMaking::Message&); diff --git a/samples/golf/src/golf/StatsState.cpp b/samples/golf/src/golf/StatsState.cpp index 7e5bbb9f3..640a75970 100644 --- a/samples/golf/src/golf/StatsState.cpp +++ b/samples/golf/src/golf/StatsState.cpp @@ -1944,6 +1944,21 @@ void StatsState::activateTab(std::int32_t tabID) m_audioEnts[AudioID::Accept].getComponent().play(); } + //for reasons I've given up trying to understand, we need to + //delay the selection by one frame. + const auto selectNext = [&](std::int32_t idx) + { + auto e = m_scene.createEntity(); + e.addComponent().active = true; + e.getComponent().function = + [&, idx](cro::Entity f, float) + { + m_scene.getSystem()->selectByIndex(idx); + f.getComponent().active = false; + m_scene.destroyEntity(f); + }; + }; + //update the selection order depending on which page we're on switch (tabID) { @@ -1958,7 +1973,7 @@ void StatsState::activateTab(std::int32_t tabID) m_tabButtons[TabID::Awards].getComponent().setNextIndex(ButtonPerformance, ButtonPerformance); m_tabButtons[TabID::Awards].getComponent().setPrevIndex(ButtonHistory, ButtonHistory); - m_scene.getSystem()->selectAt(ButtonPerformance); + selectNext(ButtonPerformance); break; case TabID::Performance: m_tabButtons[TabID::ClubStats].getComponent().setNextIndex(ButtonHistory, Perf01); @@ -1970,7 +1985,7 @@ void StatsState::activateTab(std::int32_t tabID) m_tabButtons[TabID::Awards].getComponent().setNextIndex(ButtonClubset, PerfDate); m_tabButtons[TabID::Awards].getComponent().setPrevIndex(ButtonHistory, PerfDate); - m_scene.getSystem()->selectAt(ButtonHistory); + selectNext(ButtonHistory); break; case TabID::History: m_tabButtons[TabID::ClubStats].getComponent().setNextIndex(ButtonPerformance, ButtonPerformance); @@ -1982,7 +1997,7 @@ void StatsState::activateTab(std::int32_t tabID) m_tabButtons[TabID::Awards].getComponent().setNextIndex(ButtonClubset, ButtonClubset); m_tabButtons[TabID::Awards].getComponent().setPrevIndex(ButtonPerformance, ButtonPerformance); - m_scene.getSystem()->selectAt(ButtonAwards); + selectNext(ButtonAwards); break; case TabID::Awards: m_tabButtons[TabID::ClubStats].getComponent().setNextIndex(ButtonPerformance, ButtonPerformance); @@ -1994,7 +2009,7 @@ void StatsState::activateTab(std::int32_t tabID) m_tabButtons[TabID::History].getComponent().setNextIndex(ButtonClubset, AwardNext); m_tabButtons[TabID::History].getComponent().setPrevIndex(ButtonPerformance, AwardNext); - m_scene.getSystem()->selectAt(ButtonClubset); + selectNext(ButtonClubset); break; } }