From 0d959a72aa56e96dab756317cebb022415850c29 Mon Sep 17 00:00:00 2001 From: konstin Date: Sun, 25 May 2014 21:16:42 +0200 Subject: [PATCH] implement dynamic track listing (thanks to unitraxx for the help with the updating) --- src/states_screens/dialogs/gp_info_dialog.cpp | 111 ++++++++++++------ src/states_screens/dialogs/gp_info_dialog.hpp | 7 ++ .../dialogs/random_gp_dialog.cpp | 37 +++--- 3 files changed, 105 insertions(+), 50 deletions(-) diff --git a/src/states_screens/dialogs/gp_info_dialog.cpp b/src/states_screens/dialogs/gp_info_dialog.cpp index e02adbeea..e5ec330aa 100644 --- a/src/states_screens/dialogs/gp_info_dialog.cpp +++ b/src/states_screens/dialogs/gp_info_dialog.cpp @@ -36,7 +36,6 @@ #include "tracks/track_manager.hpp" #include "utils/translation.hpp" -#include #include #include @@ -65,6 +64,7 @@ GPInfoDialog::GPInfoDialog(const std::string& gp_ident) : title->setTabStop(false); title->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER); + displayTracks(m_area.getHeight()/7, m_area.getHeight()*6/7); InitAfterDrawingTheHeader(m_area.getHeight()/7, m_area.getHeight()*6/7, gp_ident); } @@ -82,40 +82,85 @@ GPInfoDialog::~GPInfoDialog() } +// ---------------------------------------------------------------------------- +void GPInfoDialog::displayTracks(const int upper_bound, + const int lower_bound) +{ + const std::vector tracks = m_gp->getTrackNames(); + const unsigned int track_amount = tracks.size(); + + int height_of_one_line = std::min((lower_bound - upper_bound)/(track_amount+1), + (unsigned int)(GUIEngine::getFontHeight()*1.5f)); + + // Count the number of label already existing labels representing a track + unsigned int existing = 0; + for (unsigned int i = 0; i < m_widgets.size(); i++) + { + if (m_widgets.get(i)->m_properties[PROP_ID] == "Track label") + existing++; + } + + unsigned int reuse = std::min(existing, track_amount); + // m_widgets has the type PtrVector + unsigned int widgets_iter = 0; + for (unsigned int i = 0; i < reuse; i++) + { + Track* track = track_manager->getTrack(tracks[i]); + + // Find the next widget that is a track label + while (m_widgets.get(widgets_iter)->m_properties[PROP_ID] != "Track label") + widgets_iter++; + + LabelWidget* widget = dynamic_cast(m_widgets.get(widgets_iter)); + widget->setText(translations->fribidize(track->getName()), false); + widget->move(20, upper_bound + height_of_one_line*(i+1), + m_area.getWidth()/2 - 20, height_of_one_line); + + widgets_iter++; + } + + if (existing < track_amount) + { + // There are not enough labels for all the track names, so we have to + // add some more + for (unsigned int i = reuse; i < track_amount; i++) + { + Track* track = track_manager->getTrack(tracks[i]); + assert(track != NULL); + + LabelWidget* widget = new LabelWidget(); + widget->m_properties[PROP_ID] = "Track label"; + widget->setText(translations->fribidize(track->getName()), false); + widget->setParent(m_irrlicht_window); + m_widgets.push_back(widget); + widget->add(); + + widget->move(20, upper_bound + height_of_one_line*(i+1), + m_area.getWidth()/2 - 20, height_of_one_line); + } + } + else if (existing > track_amount) + { + // There are label which are not necessary anymore so they're deleted + for (unsigned int i = widgets_iter; i < m_widgets.size(); i++) + { + if (m_widgets.get(i)->m_properties[PROP_ID] == "Track label") + { + m_irrlicht_window->removeChild(m_widgets.get(i)->getIrrlichtElement()); + m_widgets.remove(i); + i--; + } + } + } +} + // ---------------------------------------------------------------------------- void GPInfoDialog::InitAfterDrawingTheHeader(const int upper_bound, const int lower_bound, const std::string& gp_ident) { - // ---- Track listings const std::vector tracks = m_gp->getTrackNames(); - const int trackAmount = tracks.size(); - - int height_of_one_line = (lower_bound - upper_bound)/(trackAmount+1); - const int textHeight = GUIEngine::getFontHeight(); - if (height_of_one_line > (int)(textHeight*1.5f)) - height_of_one_line = (int)(textHeight*1.5f); - - bool gp_ok = true; - - for (int t=0; tgetTrack(tracks[t]); - assert(track != NULL); - stringw lineText = track->getName(); - - LabelWidget* widget = new LabelWidget(); - widget->setText(translations->fribidize(lineText), false); - widget->m_x = 20; - widget->m_y = upper_bound + height_of_one_line*(t+1); - widget->m_w = m_area.getWidth()/2 - 20; - widget->m_h = height_of_one_line; - widget->setParent(m_irrlicht_window); - - m_widgets.push_back(widget); - widget->add(); - } // ---- Track screenshot m_screenshot_widget = new IconButtonWidget(IconButtonWidget::SCALE_MODE_KEEP_CUSTOM_ASPECT_RATIO, @@ -165,7 +210,7 @@ void GPInfoDialog::InitAfterDrawingTheHeader(const int upper_bound, okBtn->m_properties[PROP_ID] = "cannot_start"; okBtn->setText(_("Sorry, no tracks available")); } - else if (gp_ok) + else { okBtn->m_properties[PROP_ID] = "start"; okBtn->setText(_("Start Grand Prix")); @@ -173,14 +218,8 @@ void GPInfoDialog::InitAfterDrawingTheHeader(const int upper_bound, continueBtn->m_properties[PROP_ID] = "continue"; continueBtn->setText(_("Continue")); } - else - { - okBtn->m_properties[PROP_ID] = "cannot_start"; - okBtn->setText(_("This Grand Prix is broken!")); - okBtn->setBadge(BAD_BADGE); - } - if (saved_gp && gp_ok) + if (saved_gp) { continueBtn->m_x = m_area.getWidth()/2 + 110; continueBtn->m_y = lower_bound; diff --git a/src/states_screens/dialogs/gp_info_dialog.hpp b/src/states_screens/dialogs/gp_info_dialog.hpp index 37c63b7f8..d0baa771b 100644 --- a/src/states_screens/dialogs/gp_info_dialog.hpp +++ b/src/states_screens/dialogs/gp_info_dialog.hpp @@ -53,6 +53,13 @@ public: void InitAfterDrawingTheHeader(const int y1, const int y2, const std::string& gp_ident); + /** \brief display all the tracks according to the current gp + * For a normal gp info dialog, it just creates a label with the name for + * every track. But in a random gp info dialog, it tries to reuse as many + * labels as possible by just changing their labels. If there are less than + * need, some are added, if there are to many, some become deleted. */ + void displayTracks(const int y1, const int y2); + void onEnterPressedInternal(); GUIEngine::EventPropagation processEvent(const std::string& eventSource); diff --git a/src/states_screens/dialogs/random_gp_dialog.cpp b/src/states_screens/dialogs/random_gp_dialog.cpp index 7191fa46a..3a3016648 100644 --- a/src/states_screens/dialogs/random_gp_dialog.cpp +++ b/src/states_screens/dialogs/random_gp_dialog.cpp @@ -17,6 +17,7 @@ #include "guiengine/engine.hpp" #include "guiengine/widgets/spinner_widget.hpp" +#include "guiengine/widget.hpp" #include "race/grand_prix_manager.hpp" #include "states_screens/dialogs/random_gp_dialog.hpp" #include "tracks/track_manager.hpp" @@ -53,30 +54,31 @@ randomGPInfoDialog::randomGPInfoDialog() title->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER); // ---- Spinners - // Number of laps chooser - GUIEngine::SpinnerWidget* spinner = new GUIEngine::SpinnerWidget(false); - spinner->setValue(m_number_of_tracks); - spinner->setMin(1); - spinner->setMax(track_manager->getTracksInGroup(m_trackgroup).size()); - spinner->setParent(m_irrlicht_window); - spinner->m_properties[PROP_ID] = "Number of tracks"; - m_widgets.push_back(spinner); - spinner->add(); - spinner->move(10, m_area.getHeight()/7, 300, 40); - // Trackgroup chooser - spinner = new GUIEngine::SpinnerWidget(false); + GUIEngine::SpinnerWidget* spinner = new GUIEngine::SpinnerWidget(false); spinner->m_properties[PROP_ID] = "Trackgroup"; spinner->setParent(m_irrlicht_window); m_widgets.push_back(spinner); spinner->add(); - spinner->move(310, m_area.getHeight()/7, 300, 40); + spinner->move(10, m_area.getHeight()/7, 300, 40); // Fill it with with all the track group names spinner->addLabel("all"); const std::vector& groups = track_manager->getAllTrackGroups(); for (unsigned int i = 1; i < groups.size() + 1; i++) spinner->addLabel(stringw(groups[i].c_str())); + // Number of laps chooser + spinner = new GUIEngine::SpinnerWidget(false); + spinner->setValue(m_number_of_tracks); + spinner->setMin(1); + spinner->setMax(track_manager->getNumberOfTracks()); // default is "all" + spinner->setParent(m_irrlicht_window); + spinner->m_properties[PROP_ID] = "Number of tracks"; + m_widgets.push_back(spinner); + spinner->add(); + spinner->move(310, m_area.getHeight()/7, 200, 40); + + displayTracks(m_area.getHeight()/7 + 50, m_area.getHeight()*6/7); InitAfterDrawingTheHeader(m_area.getHeight()/7 + 50, m_area.getHeight()*6/7, "random"); @@ -85,7 +87,7 @@ randomGPInfoDialog::randomGPInfoDialog() GUIEngine::EventPropagation randomGPInfoDialog::processEvent( const std::string& eventSource) { - if (eventSource == "Number of laps") + if (eventSource == "Number of tracks") { m_number_of_tracks = getWidget("Number of tracks")->getValue(); updateGP(); @@ -94,7 +96,13 @@ GUIEngine::EventPropagation randomGPInfoDialog::processEvent( { GUIEngine::SpinnerWidget* t = getWidget("Trackgroup"); GUIEngine::SpinnerWidget* s = getWidget("Number of tracks"); + m_trackgroup = stringc(t->getStringValue()).c_str(); + + // Update the maximum for the number of tracks since it's depending on + // the current track. The current value in the Number-of-tracks-spinner + // has to be updated, since otherwise the displayed (and used) value + // can be bigger than the maximum. (Might be a TODO to fix this) unsigned int max = (m_trackgroup == "all") ? track_manager->getNumberOfTracks() : track_manager->getTracksInGroup(m_trackgroup).size(); @@ -115,5 +123,6 @@ void randomGPInfoDialog::updateGP() delete m_gp; m_gp = new GrandPrixData(m_number_of_tracks, m_trackgroup, m_use_reverse); + displayTracks(m_area.getHeight()/7, m_area.getHeight()*6/7); }