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")