From db3db6f8b57cea02559ef725fe1f469ab57e51ad Mon Sep 17 00:00:00 2001 From: hiker <henrichsjoerg@gmail.com> Date: Wed, 27 Aug 2014 22:08:50 +1000 Subject: [PATCH] First version of the GP info screen (instead of dialog). --- data/gui/gp_info.stkgui | 59 +++++++ sources.cmake | 2 +- src/states_screens/gp_info_screen.cpp | 214 ++++++++++++++++++++++++++ src/states_screens/gp_info_screen.hpp | 75 +++++++++ src/states_screens/tracks_screen.cpp | 8 +- 5 files changed, 355 insertions(+), 3 deletions(-) create mode 100644 data/gui/gp_info.stkgui create mode 100644 src/states_screens/gp_info_screen.cpp create mode 100644 src/states_screens/gp_info_screen.hpp diff --git a/data/gui/gp_info.stkgui b/data/gui/gp_info.stkgui new file mode 100644 index 000000000..c72841d35 --- /dev/null +++ b/data/gui/gp_info.stkgui @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="UTF-8"?> +<stkgui> + <icon-button id="back" x="0" y="0" height="8%" icon="gui/back.png"/> + + <div x="1%" y="1%" width="98%" height="98%" layout="vertical-row"> + + <header id="name" width="100%" text_align="center"/> + + <spacer width="1" height="5%"/> + + <box width="95%" height="50%" padding="10" layout="horizontal-row"> + <spacer width="10" height="100%"/> + <!-- Left pane --> + <div width="45%" height="95%" align="center" layout="vertical-row"> + <placeholder proportion="1" width="100%" height="100%" id="screenshot_div"> + </placeholder> + </div> + + <spacer width="5%" height="100%"/> + + <!-- Right pane --> + <div width="45%" height="95%" align="center" layout="vertical-row"> + <list id="tracks" width="100%" height="100%"/> + </div> + + </box> + <spacer width="1" height="3%"/> + <box width="95%" height="17%" padding="10" layout="vertical-row"> + <spacer width="1" height="5%"/> + + <div width="75%" height="fit" layout="horizontal-row" > + <spacer width="40" height="2" /> + <label id="ai-text" height="100%" width="40%" I18N="Number of AI karts" text="Number of AI karts"/> + <spacer with="40" height="2" /> + <spinner id="ai-spinner" width="20%" min_value="1" max_value="20" align="center" + wrap_around="true" /> + <spacer proportion="1" height="2" /> + </div> + <div width="75%" height="fit" layout="horizontal-row" > + <spacer width="40" height="2" /> + <label id="reverse-text" height="100%" width="40%" I18N="Drive the track reverse" text="Drive in reverse"/> + <spacer width="40" height="2" /> + <checkbox id="reverse"/> + <spacer proportion="1" height="2" /> + </div> + <spacer width="1" height="2%"/> + </box> + <spacer width="1" height="2%"/> + <buttonbar id="buttons" height="15%" width="100%" align="center"> + + <icon-button id="start" width="64" height="64" icon="gui/green_check.png" + I18N="Start race" text="Start Race"/> + + <icon-button id="continue" width="64" height="64" icon="gui/green_check.png" + I18N="Continue race" text="Continue Race"/> + </buttonbar> + + </div> +</stkgui> diff --git a/sources.cmake b/sources.cmake index f484b15d5..ddc029d4f 100644 --- a/sources.cmake +++ b/sources.cmake @@ -1,5 +1,5 @@ # Modify this file to change the last-modified date when you add/remove a file. -# This will then trigger a new cmake run automatically. +# This will then trigger a new cmake run automatically. file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp") file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp") file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*") diff --git a/src/states_screens/gp_info_screen.cpp b/src/states_screens/gp_info_screen.cpp new file mode 100644 index 000000000..16f18d499 --- /dev/null +++ b/src/states_screens/gp_info_screen.cpp @@ -0,0 +1,214 @@ +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2009-2013 Marianne Gagnon +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "states_screens/gp_info_screen.hpp" + +#include "audio/sfx_manager.hpp" +#include "challenges/unlock_manager.hpp" +#include "config/player_manager.hpp" +#include "config/saved_grand_prix.hpp" +#include "graphics/irr_driver.hpp" +#include "guiengine/engine.hpp" +#include "guiengine/screen.hpp" +#include "guiengine/widgets/check_box_widget.hpp" +#include "guiengine/widgets/icon_button_widget.hpp" +#include "guiengine/widgets/label_widget.hpp" +#include "guiengine/widgets/list_widget.hpp" +#include "guiengine/widgets/ribbon_widget.hpp" +#include "io/file_manager.hpp" +#include "race/grand_prix_manager.hpp" +#include "race/grand_prix_data.hpp" +#include "race/race_manager.hpp" +#include "states_screens/state_manager.hpp" +#include "states_screens/tracks_screen.hpp" +#include "tracks/track.hpp" +#include "tracks/track_manager.hpp" +#include "utils/translation.hpp" + +#include <IGUIEnvironment.h> +#include <IGUIStaticText.h> + +using irr::gui::IGUIStaticText; +using GUIEngine::PROP_ID; + +using namespace GUIEngine; + +DEFINE_SCREEN_SINGLETON( GPInfoScreen ); + +GPInfoScreen::GPInfoScreen() : Screen("gp_info.stkgui") +{ + m_gp = NULL; + m_curr_time = 0.0f; +} // GPInfoScreen + +// ---------------------------------------------------------------------------- + +GPInfoScreen::~GPInfoScreen() +{ +} // ~GPInfoScreen + +// ---------------------------------------------------------------------------- +/** Sets the GP to be displayed. + */ +void GPInfoScreen::setGP(const std::string &gp_ident) +{ + m_gp = grand_prix_manager->getGrandPrix(gp_ident); +} // setGP + +// ---------------------------------------------------------------------------- +void GPInfoScreen::init() +{ + Screen::init(); + m_curr_time = 0.0f; + + getWidget<LabelWidget>("name")->setText(m_gp->getName(), false); + + m_gp->checkConsistency(); + + m_over_body = UserConfigParams::m_height/7; + m_lower_bound = UserConfigParams::m_height*6/7; + + addTracks(); + addScreenshot(); + + CheckBoxWidget *reverse = getWidget<CheckBoxWidget>("reverse"); + reverse->setState(false); + + // Check if there is a saved GP: + SavedGrandPrix* saved_gp = + SavedGrandPrix::getSavedGP(StateManager::get() + ->getActivePlayerProfile(0)->getUniqueID(), + m_gp->getId(), + race_manager->getDifficulty(), + race_manager->getNumberOfKarts(), + race_manager->getNumLocalPlayers()); + + getWidget<IconButtonWidget>("continue")->setVisible(saved_gp!=NULL); +} // init + +// ---------------------------------------------------------------------------- +void GPInfoScreen::loadedFromFile() +{ +} // loadedFromFile + +// ---------------------------------------------------------------------------- + +void GPInfoScreen::addTracks() +{ + const std::vector<std::string> tracks = m_gp->getTrackNames(); + + ListWidget *list = getWidget<ListWidget>("tracks"); + list->clear(); + for(unsigned int i=0; i<tracks.size(); i++) + { + const Track *track = track_manager->getTrack(tracks[i]); + std::string s = StringUtils::toString(i); + list->addItem(s, translations->fribidize(track->getName()) ); + } +} // addTracks + +// ---------------------------------------------------------------------------- + +void GPInfoScreen::addScreenshot() +{ + Widget* screenshot_div = getWidget("screenshot_div"); + + m_screenshot_widget = new GUIEngine::IconButtonWidget( + GUIEngine::IconButtonWidget::SCALE_MODE_KEEP_CUSTOM_ASPECT_RATIO, + false, false, GUIEngine::IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE); + // images are saved squared, but must be stretched to 4:3 + m_screenshot_widget->setCustomAspectRatio(4.0f / 3.0f); + m_screenshot_widget->m_x = screenshot_div->m_x; + m_screenshot_widget->m_y = screenshot_div->m_y; + m_screenshot_widget->m_w = screenshot_div->m_w; + m_screenshot_widget->m_h = screenshot_div->m_h; + + + // Temporary icon, will replace it just after + // (but it will be shown if the given icon is not found) + m_screenshot_widget->m_properties[PROP_ICON] = "gui/main_help.png"; + m_screenshot_widget->add(); + + const Track *track = track_manager->getTrack(m_gp->getTrackId(0)); + video::ITexture* screenshot = irr_driver->getTexture(track->getScreenshotFile(), + "While loading screenshot for track '%s':", + track->getFilename() ); + if (screenshot != NULL) + m_screenshot_widget->setImage(screenshot); + m_widgets.push_back(m_screenshot_widget); +} // addScreenShot + +// ---------------------------------------------------------------------------- + +void GPInfoScreen::onEnterPressedInternal() +{ + // Save the GP id because dismiss() will destroy this instance + std::string gp_id = m_gp->getId(); +//FIXME ModalDialog::dismiss(); + // Disable accidentally unlocking of a challenge + PlayerManager::getCurrentPlayer()->setCurrentChallenge(""); + race_manager->startGP(grand_prix_manager->getGrandPrix(gp_id), false, false); +} + +// ---------------------------------------------------------------------------- + +void GPInfoScreen::eventCallback(GUIEngine::Widget *, const std::string &name, + const int player_id) +{ + if(name=="buttons") + { + const std::string &button = getWidget<GUIEngine::RibbonWidget>("buttons") + ->getSelectionIDString(PLAYER_ID_GAME_MASTER); + + if (button == "start") + { + // Save GP identifier, since dismiss will delete this object. + std::string gp_id = m_gp->getId(); + // Also create a copy of the string: it is a reference to data + // in a widget in the dialog - so if we call dismiss, this reference + // becomes invalid! + std::string save_source = name; + // FIXME ModalDialog::dismiss(); + race_manager->startGP(grand_prix_manager->getGrandPrix(gp_id), false, + (save_source == "continue")); + } + } // name=="buttons" + +} // eventCallback + +// ---------------------------------------------------------------------------- + +void GPInfoScreen::onUpdate(float dt) +{ + if (dt == 0) + return; // if nothing changed, return right now + + m_curr_time += dt; + int frameAfter = (int)(m_curr_time / 1.5f); + + const std::vector<std::string> tracks = m_gp->getTrackNames(); + if (frameAfter >= (int)tracks.size()) + { + frameAfter = 0; + m_curr_time = 0; + } + + Track* track = track_manager->getTrack(tracks[frameAfter]); + std::string file = track->getScreenshotFile(); + m_screenshot_widget->setImage(file, IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE); + m_screenshot_widget->m_properties[GUIEngine::PROP_ICON] = file; +} // onUpdate \ No newline at end of file diff --git a/src/states_screens/gp_info_screen.hpp b/src/states_screens/gp_info_screen.hpp new file mode 100644 index 000000000..976d2c2b4 --- /dev/null +++ b/src/states_screens/gp_info_screen.hpp @@ -0,0 +1,75 @@ +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2009-2014 Marianne Gagnon +// 2014 Joerg Henrichs +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 3 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifndef HEADER_GP_INFO_SCREEN_HPP +#define HEADER_GP_INFO_SCREEN_HPP + +#include "guiengine/screen.hpp" + +class GrandPrixData; + +namespace GUIEngine +{ + class IconButtonWidget; +} + +/** + * \brief Dialog that shows information about a specific grand prix + * \ingroup states_screens + */ +class GPInfoScreen : public GUIEngine::Screen, + public GUIEngine::ScreenSingleton<GPInfoScreen> +{ +protected: // Necessary for RandomGPInfoScreen + GUIEngine::IconButtonWidget* m_screenshot_widget; + float m_curr_time; + + /** The grand prix data. */ + GrandPrixData *m_gp; + + /** height of the separator over the body */ + int m_over_body; + /** height of the seperator over the buttons */ + int m_lower_bound; + + /** \brief display all the tracks according to the current gp + * For a normal gp info dialog, it just creates a label for every track. + * But with a random gp info dialog, it tries to reuse as many + * labels as possible by just changing their text. */ + void addTracks(); + void addScreenshot(); + +public: + GPInfoScreen(); + /** Places the focus back on the selected GP, in the case that the dialog + * was cancelled and we're returning to the track selection screen */ + virtual ~GPInfoScreen(); + + void onEnterPressedInternal(); + virtual void eventCallback(GUIEngine::Widget *, const std::string &name, + const int player_id); + virtual void loadedFromFile(); + virtual void init(); + + virtual void onUpdate(float dt); + + void setGP(const std::string &gp_ident); +}; + +#endif diff --git a/src/states_screens/tracks_screen.cpp b/src/states_screens/tracks_screen.cpp index 8832a6902..ba4865c07 100644 --- a/src/states_screens/tracks_screen.cpp +++ b/src/states_screens/tracks_screen.cpp @@ -29,7 +29,7 @@ #include "race/grand_prix_manager.hpp" #include "states_screens/state_manager.hpp" #include "states_screens/track_info_screen.hpp" -#include "states_screens/dialogs/gp_info_dialog.hpp" +#include "states_screens/gp_info_screen.hpp" #include "states_screens/dialogs/random_gp_dialog.hpp" #include "tracks/track.hpp" #include "tracks/track_manager.hpp" @@ -118,7 +118,11 @@ void TracksScreen::eventCallback(Widget* widget, const std::string& name, if (selection == "Random Grand Prix") new RandomGPInfoDialog(); else - new GPInfoDialog(selection); + { + GPInfoScreen *gpis = GPInfoScreen::getInstance(); + gpis->setGP(selection); + StateManager::get()->pushScreen(gpis); + } } } else if (name == "trackgroups")