Icon button for race result (#4071)

* Icons for race result

* Fix bugs && improvements

* Tabs to spaces

* Fix bugs && improvements
This commit is contained in:
Du maosen 2019-09-30 15:33:07 +08:00 committed by Benau
parent 98d8aca91a
commit 71fec6780c
2 changed files with 242 additions and 218 deletions

View File

@ -1,25 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<stkgui>
<div x="2%" y="5%" width="100%" height="95%" layout="vertical-row" id="div">
<roundedbox width="90%" proportion="1" align="center">
<div id="result-table" width="96%" height="96%" x="2%" y="2%">
<!-- Contents is added programatically -->
<div x="3%" y="2%" width="94%" height="96%" layout="vertical-row" id="div">
<roundedbox width="100%" height="100%" align="center">
<div x="2%" y="2%" width="96%" height="96%" layout="vertical-row">
<div id="result-table" width="100%" height="80%">
<!-- Contents is added programatically -->
</div>
<spacer height="3%" width="100%"/>
<!-- The actual button texts will vary depending on what type of race
was being run, and if something was unlocked etc. So we don't
specify a text here, and label the buttons :
top : 'See unlocked feature(s)', 'Continue', 'Setup new race'
middle: 'Restart' (or invisible)
bottom: 'Abort GP', 'Back to the menu' (or invisible)
Setting text=" " is important, otherwise the height of the
widget is incorrect. -->
<buttonbar id="operations" width="65%" height="18%" align="center">
<icon-button id="left" width="128" height="128" text="Left"/>
<icon-button id="middle" width="128" height="128" text="Middle"/>
<icon-button id="right" width="128" height="128" text="Right"/>
</buttonbar>
</div>
</roundedbox>
<spacer height="1%" width="96%"/>
<!-- The actual button texts will vary depending on what type of race
was being run, and if something was unlocked etc. So we don't
specify a text here, and label the buttons :
top : 'See unlocked feature(s)', 'Continue', 'Setup new race'
middle: 'Restart' (or invisible)
bottom: 'Abort GP', 'Back to the menu' (or invisible)
Setting text=" " is important, otherwise the height of the
widget is incorrect. -->
<button id="top" align="center" width="60%"/>
<spacer height="1%" width="96%"/>
<button id="middle" align="center" width="60%"/>
<spacer height="1%" width="96%"/>
<button id="bottom" align="center" width="60%"/>
<spacer height="1%" width="96%"/>
<spacer height="3%" width="90%"/>
</div>
</stkgui>

View File

@ -34,6 +34,7 @@
#include "guiengine/widget.hpp"
#include "guiengine/widgets/icon_button_widget.hpp"
#include "guiengine/widgets/label_widget.hpp"
#include "guiengine/widgets/ribbon_widget.hpp"
#include "io/file_manager.hpp"
#include "karts/abstract_kart.hpp"
#include "karts/controller/controller.hpp"
@ -83,9 +84,9 @@ void RaceResultGUI::init()
m_timer = 0;
getWidget("top")->setVisible(false);
getWidget("left")->setVisible(false);
getWidget("middle")->setVisible(false);
getWidget("bottom")->setVisible(false);
getWidget("right")->setVisible(false);
music_manager->stopMusic();
@ -159,9 +160,9 @@ void RaceResultGUI::tearDown()
*/
void RaceResultGUI::enableAllButtons()
{
GUIEngine::Widget *top = getWidget("top");
GUIEngine::Widget *middle = getWidget("middle");
GUIEngine::Widget *bottom = getWidget("bottom");
GUIEngine::IconButtonWidget *left = getWidget<GUIEngine::IconButtonWidget>("left");
GUIEngine::IconButtonWidget *middle = getWidget<GUIEngine::IconButtonWidget>("middle");
GUIEngine::IconButtonWidget *right = getWidget<GUIEngine::IconButtonWidget>("right");
if (race_manager->getMajorMode() == RaceManager::MAJOR_MODE_GRAND_PRIX)
{
@ -171,12 +172,14 @@ void RaceResultGUI::enableAllButtons()
// If we're in a network world, change the buttons text
if (World::getWorld()->isNetworkWorld())
{
top->setVisible(false);
middle->setText(_("Continue"));
middle->setVisible(true);
middle->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
bottom->setText(_("Quit the server"));
bottom->setVisible(true);
left->setLabel(_("Continue"));
left->setImage("gui/icons/green_check.png");
left->setVisible(true);
left->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
middle->setVisible(false);
right->setLabel(_("Quit the server"));
right->setImage("gui/icons/main_quit.png");
right->setVisible(true);
return;
}
@ -187,30 +190,40 @@ void RaceResultGUI::enableAllButtons()
(race_manager->getMajorMode() != RaceManager::MAJOR_MODE_GRAND_PRIX ||
race_manager->getTrackNumber() + 1 == race_manager->getNumOfTracks() ) )
{
top->setText(n == 1 ? _("You completed a challenge!")
middle->setLabel(n == 1 ? _("You completed a challenge!")
: _("You completed challenges!"));
top->setVisible(true);
top->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
middle->setImage("gui/icons/cup_gold.png");
middle->setVisible(true);
middle->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
}
else if (race_manager->getMajorMode() == RaceManager::MAJOR_MODE_GRAND_PRIX)
{
// In case of a GP:
// ----------------
top->setVisible(false);
top->setFocusable(false);
middle->setLabel(_("Continue"));
middle->setImage("gui/icons/green_check.png");
middle->setVisible(false);
middle->setFocusable(false);
right->setVisible(false);
right->setFocusable(false);
middle->setText(_("Continue"));
middle->setVisible(true);
// Two continue buttons to make sure the buttons in the bar is balanced
left->setLabel(_("Continue"));
left->setImage("gui/icons/green_check.png");
left->setVisible(true);
if (race_manager->getTrackNumber() + 1 < race_manager->getNumOfTracks())
{
bottom->setText(_("Abort Grand Prix"));
bottom->setVisible(true);
bottom->setFocusable(true);
right->setLabel(_("Abort Grand Prix"));
right->setImage("gui/icons/race_giveup.png");
right->setVisible(true);
right->setFocusable(true);
}
else
{
bottom->setFocusable(false);
left->setVisible(false);
left->setFocusable(false);
middle->setVisible(true);
}
middle->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
@ -220,24 +233,28 @@ void RaceResultGUI::enableAllButtons()
// Normal race
// -----------
middle->setText(_("Restart"));
middle->setVisible(true);
middle->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
left->setLabel(_("Restart"));
left->setImage("gui/icons/restart.png");
left->setVisible(true);
left->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
if (race_manager->raceWasStartedFromOverworld())
{
top->setVisible(false);
bottom->setText(_("Back to challenge selection"));
middle->setVisible(false);
right->setLabel(_("Back to challenge selection"));
right->setImage("gui/icons/back.png");
}
else
{
middle->setImage("gui/icons/main_race.png");
if (race_manager->isRecordingRace())
top->setText(_("Race against the new ghost replay"));
middle->setLabel(_("Race against the new ghost replay"));
else
top->setText(_("Setup New Race"));
top->setVisible(true);
bottom->setText(_("Back to the menu"));
middle->setLabel(_("Setup New Race"));
middle->setVisible(true);
right->setLabel(_("Back to the menu"));
right->setImage("gui/icons/back.png");
}
bottom->setVisible(true);
right->setVisible(true);
}
} // enableAllButtons
@ -259,198 +276,203 @@ void RaceResultGUI::eventCallback(GUIEngine::Widget* widget,
m_end_track++;
displayScreenShots();
}
// If we're playing online :
if (World::getWorld()->isNetworkWorld())
if(name == "operations")
{
if (name == "middle") // Continue button (return to server lobby)
const std::string& action =
getWidget<GUIEngine::RibbonWidget>("operations")->getSelectionIDString(PLAYER_ID_GAME_MASTER);
// If we're playing online :
if (World::getWorld()->isNetworkWorld())
{
// Signal to the server that this client is back in the lobby now.
auto cl = LobbyProtocol::get<ClientLobby>();
if (cl)
cl->doneWithResults();
getWidget("middle")->setText(_("Waiting for others"));
}
if (name == "bottom") // Quit server (return to online lan / wan menu)
{
race_manager->clearNetworkGrandPrixResult();
if (STKHost::existHost())
if (action == "left") // Continue button (return to server lobby)
{
STKHost::get()->shutdown();
// Signal to the server that this client is back in the lobby now.
auto cl = LobbyProtocol::get<ClientLobby>();
if (cl)
cl->doneWithResults();
getWidget<GUIEngine::IconButtonWidget>("left")->setLabel(_("Waiting for others"));
}
race_manager->exitRace();
race_manager->setAIKartOverride("");
StateManager::get()->resetAndSetStack(
NetworkConfig::get()->getResetScreens().data());
NetworkConfig::get()->unsetNetworking();
if (action == "right") // Quit server (return to online lan / wan menu)
{
race_manager->clearNetworkGrandPrixResult();
if (STKHost::existHost())
{
STKHost::get()->shutdown();
}
race_manager->exitRace();
race_manager->setAIKartOverride("");
StateManager::get()->resetAndSetStack(
NetworkConfig::get()->getResetScreens().data());
NetworkConfig::get()->unsetNetworking();
}
return;
}
return;
}
// If something was unlocked, the 'continue' button was
// actually used to display "Show unlocked feature(s)" text.
// ---------------------------------------------------------
int n = (int)PlayerManager::getCurrentPlayer()
->getRecentlyCompletedChallenges().size();
if (n > 0 &&
(race_manager->getMajorMode() != RaceManager::MAJOR_MODE_GRAND_PRIX ||
race_manager->getTrackNumber() + 1 == race_manager->getNumOfTracks() ) )
// If something was unlocked, the 'continue' button was
// actually used to display "Show unlocked feature(s)" text.
// ---------------------------------------------------------
int n = (int)PlayerManager::getCurrentPlayer()
->getRecentlyCompletedChallenges().size();
if (n > 0 &&
(race_manager->getMajorMode() != RaceManager::MAJOR_MODE_GRAND_PRIX ||
race_manager->getTrackNumber() + 1 == race_manager->getNumOfTracks() ) )
{
if (name == "top")
{
if (race_manager->getMajorMode() == RaceManager::MAJOR_MODE_GRAND_PRIX)
if (action == "middle")
{
if (race_manager->getMajorMode() == RaceManager::MAJOR_MODE_GRAND_PRIX)
{
cleanupGPProgress();
}
std::vector<const ChallengeData*> unlocked =
PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges();
bool gameCompleted = false;
for (unsigned int n = 0; n < unlocked.size(); n++)
{
if (unlocked[n]->getChallengeId() == "fortmagma")
{
gameCompleted = true;
break;
}
}
if (gameCompleted)
{
// clear the race
// kart will no longer be available during cutscene, drop reference
StateManager::get()->getActivePlayer(playerID)->setKart(NULL);
PropertyAnimator::get()->clear();
World::deleteWorld();
CutsceneWorld::setUseDuration(true);
StateManager::get()->enterGameState();
race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE);
race_manager->setNumKarts(0);
race_manager->setNumPlayers(0);
race_manager->startSingleRace("endcutscene", 999, false);
std::vector<std::string> parts;
parts.push_back("endcutscene");
((CutsceneWorld*)World::getWorld())->setParts(parts);
}
else
{
StateManager::get()->popMenu();
PropertyAnimator::get()->clear();
World::deleteWorld();
CutsceneWorld::setUseDuration(false);
StateManager::get()->enterGameState();
race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE);
race_manager->setNumKarts(0);
race_manager->setNumPlayers(0);
race_manager->startSingleRace("featunlocked", 999, race_manager->raceWasStartedFromOverworld());
FeatureUnlockedCutScene* scene =
FeatureUnlockedCutScene::getInstance();
scene->addTrophy(race_manager->getDifficulty(),false);
scene->findWhatWasUnlocked(race_manager->getDifficulty(),unlocked);
scene->push();
race_manager->setAIKartOverride("");
std::vector<std::string> parts;
parts.push_back("featunlocked");
((CutsceneWorld*)World::getWorld())->setParts(parts);
}
PlayerManager::getCurrentPlayer()->clearUnlocked();
return;
}
Log::warn("RaceResultGUI", "Incorrect event '%s' when things are unlocked.",
action.c_str());
}
// Next check for GP
// -----------------
if (race_manager->getMajorMode() == RaceManager::MAJOR_MODE_GRAND_PRIX)
{
if (action == "left" || action == "middle") // Next GP
{
cleanupGPProgress();
StateManager::get()->popMenu();
race_manager->next();
}
std::vector<const ChallengeData*> unlocked =
PlayerManager::getCurrentPlayer()->getRecentlyCompletedChallenges();
bool gameCompleted = false;
for (unsigned int n = 0; n < unlocked.size(); n++)
else if (action == "right") // Abort
{
if (unlocked[n]->getChallengeId() == "fortmagma")
{
gameCompleted = true;
break;
}
new MessageDialog(_("Do you really want to abort the Grand Prix?"),
MessageDialog::MESSAGE_DIALOG_CONFIRM, this, false);
}
if (gameCompleted)
else if (!getWidget(action.c_str())->isVisible())
{
// clear the race
Log::warn("RaceResultGUI", "Incorrect event '%s' when things are unlocked.",
action.c_str());
}
return;
}
// kart will no longer be available during cutscene, drop reference
StateManager::get()->getActivePlayer(playerID)->setKart(NULL);
PropertyAnimator::get()->clear();
World::deleteWorld();
StateManager::get()->popMenu();
if (action == "left") // Restart
{
race_manager->rerunRace();
}
else if (action == "middle") // Setup new race
{
// Save current race data for race against new ghost
std::string track_name = race_manager->getTrackName();
int laps = race_manager->getNumLaps();
bool reverse = race_manager->getReverseTrack();
bool new_ghost_race = race_manager->isRecordingRace();
CutsceneWorld::setUseDuration(true);
StateManager::get()->enterGameState();
race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE);
race_manager->setNumKarts(0);
race_manager->setNumPlayers(0);
race_manager->startSingleRace("endcutscene", 999, false);
race_manager->exitRace();
race_manager->setAIKartOverride("");
std::vector<std::string> parts;
parts.push_back("endcutscene");
((CutsceneWorld*)World::getWorld())->setParts(parts);
//If pressing continue quickly in a losing challenge
if (race_manager->raceWasStartedFromOverworld())
{
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
OverWorld::enterOverWorld();
}
// Special case : race against a newly saved ghost
else if (new_ghost_race)
{
ReplayPlay::get()->loadAllReplayFile();
unsigned long long int last_uid = ReplayRecorder::get()->getLastUID();
ReplayPlay::get()->setReplayFileByUID(last_uid);
race_manager->setRecordRace(true);
race_manager->setRaceGhostKarts(true);
race_manager->setNumKarts(race_manager->getNumLocalPlayers());
// Disable accidentally unlocking of a challenge
PlayerManager::getCurrentPlayer()->setCurrentChallenge("");
race_manager->setReverseTrack(reverse);
race_manager->startSingleRace(track_name, laps, false);
}
else
{
StateManager::get()->popMenu();
PropertyAnimator::get()->clear();
World::deleteWorld();
CutsceneWorld::setUseDuration(false);
StateManager::get()->enterGameState();
race_manager->setMinorMode(RaceManager::MINOR_MODE_CUTSCENE);
race_manager->setNumKarts(0);
race_manager->setNumPlayers(0);
race_manager->startSingleRace("featunlocked", 999, race_manager->raceWasStartedFromOverworld());
FeatureUnlockedCutScene* scene =
FeatureUnlockedCutScene::getInstance();
scene->addTrophy(race_manager->getDifficulty(),false);
scene->findWhatWasUnlocked(race_manager->getDifficulty(),unlocked);
scene->push();
race_manager->setAIKartOverride("");
std::vector<std::string> parts;
parts.push_back("featunlocked");
((CutsceneWorld*)World::getWorld())->setParts(parts);
Screen* newStack[] = { MainMenuScreen::getInstance(),
RaceSetupScreen::getInstance(),
NULL };
StateManager::get()->resetAndSetStack(newStack);
}
PlayerManager::getCurrentPlayer()->clearUnlocked();
return;
}
Log::warn("RaceResultGUI", "Incorrect event '%s' when things are unlocked.",
name.c_str());
}
// Next check for GP
// -----------------
if (race_manager->getMajorMode() == RaceManager::MAJOR_MODE_GRAND_PRIX)
{
if (name == "middle") // Next GP
{
cleanupGPProgress();
StateManager::get()->popMenu();
race_manager->next();
}
else if (name == "bottom") // Abort
{
new MessageDialog(_("Do you really want to abort the Grand Prix?"),
MessageDialog::MESSAGE_DIALOG_CONFIRM, this, false);
}
else if (!getWidget(name.c_str())->isVisible())
{
Log::warn("RaceResultGUI", "Incorrect event '%s' when things are unlocked.",
name.c_str());
}
return;
}
StateManager::get()->popMenu();
if (name == "top") // Setup new race
{
// Save current race data for race against new ghost
std::string track_name = race_manager->getTrackName();
int laps = race_manager->getNumLaps();
bool reverse = race_manager->getReverseTrack();
bool new_ghost_race = race_manager->isRecordingRace();
race_manager->exitRace();
race_manager->setAIKartOverride("");
//If pressing continue quickly in a losing challenge
if (race_manager->raceWasStartedFromOverworld())
else if (action == "right") // Back to main
{
race_manager->exitRace();
race_manager->setAIKartOverride("");
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
OverWorld::enterOverWorld();
}
// Special case : race against a newly saved ghost
else if (new_ghost_race)
{
ReplayPlay::get()->loadAllReplayFile();
unsigned long long int last_uid = ReplayRecorder::get()->getLastUID();
ReplayPlay::get()->setReplayFileByUID(last_uid);
race_manager->setRecordRace(true);
race_manager->setRaceGhostKarts(true);
race_manager->setNumKarts(race_manager->getNumLocalPlayers());
// Disable accidentally unlocking of a challenge
PlayerManager::getCurrentPlayer()->setCurrentChallenge("");
race_manager->setReverseTrack(reverse);
race_manager->startSingleRace(track_name, laps, false);
}
else
{
Screen* newStack[] = { MainMenuScreen::getInstance(),
RaceSetupScreen::getInstance(),
NULL };
StateManager::get()->resetAndSetStack(newStack);
}
}
else if (name == "middle") // Restart
{
race_manager->rerunRace();
}
else if (name == "bottom") // Back to main
{
race_manager->exitRace();
race_manager->setAIKartOverride("");
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
if (race_manager->raceWasStartedFromOverworld())
{
OverWorld::enterOverWorld();
if (race_manager->raceWasStartedFromOverworld())
{
OverWorld::enterOverWorld();
}
}
}
else