implement dynamic track listing (thanks to unitraxx for the help with the updating)

This commit is contained in:
konstin 2014-05-25 21:16:42 +02:00
parent aab6a1fcb6
commit 0d959a72aa
3 changed files with 105 additions and 50 deletions

View File

@ -36,7 +36,6 @@
#include "tracks/track_manager.hpp"
#include "utils/translation.hpp"
#include <iostream>
#include <IGUIEnvironment.h>
#include <IGUIStaticText.h>
@ -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<std::string> 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<Widget, HOLD>
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<LabelWidget*>(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<std::string> 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; t<trackAmount; t++)
{
Track* track = track_manager->getTrack(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;

View File

@ -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);

View File

@ -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<std::string>& 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<GUIEngine::SpinnerWidget>("Number of tracks")->getValue();
updateGP();
@ -94,7 +96,13 @@ GUIEngine::EventPropagation randomGPInfoDialog::processEvent(
{
GUIEngine::SpinnerWidget* t = getWidget<GUIEngine::SpinnerWidget>("Trackgroup");
GUIEngine::SpinnerWidget* s = getWidget<GUIEngine::SpinnerWidget>("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);
}