Some improvements to the GP editor:

- GP are now classified into groups, just like tracks: standard, user defined, and add-ons
    - allow empty GPs to be loaded by the GP manager, so that they can appear
      on the GP editor (but not on the track selection screen)
    - enable/disable buttons depending on the available options
    - provide some feedback after pushing the "save" button
    - some minor bug corrections and improvements
This commit is contained in:
Marc Coll Carrillo 2014-09-13 10:40:27 +02:00
parent d79a5aaf01
commit 5cf3ad220f
10 changed files with 276 additions and 115 deletions

View File

@ -15,7 +15,10 @@
child_height="120" keep_selection="true" /> child_height="120" keep_selection="true" />
</box> </box>
<spacer height="10" /> <!-- Populated dynamically at runtime -->
<tabs width="100%" height="30" id="gpgroups"> </tabs>
<spacer height="20" />
<box proportion="2" width="100%" layout="vertical-row"> <box proportion="2" width="100%" layout="vertical-row">
<label id="gpname" text_align="center" width="100%" <label id="gpname" text_align="center" width="100%"

View File

@ -20,6 +20,7 @@
#include "race/grand_prix_data.hpp" #include "race/grand_prix_data.hpp"
#include "config/player_profile.hpp" #include "config/player_profile.hpp"
#include "config/user_config.hpp"
#include "challenges/unlock_manager.hpp" #include "challenges/unlock_manager.hpp"
#include "config/player_manager.hpp" #include "config/player_manager.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
@ -39,12 +40,13 @@
/** Loads a grand prix definition from a file. /** Loads a grand prix definition from a file.
* \param filename Name of the file to load. * \param filename Name of the file to load.
*/ */
GrandPrixData::GrandPrixData(const std::string& filename) GrandPrixData::GrandPrixData(const std::string& filename, enum GPGroupType group)
{ {
m_filename = filename; setFilename(filename);
m_id = StringUtils::getBasename( m_id = StringUtils::getBasename(StringUtils::removeExtension(filename));
StringUtils::removeExtension(filename));
m_editable = (filename.find(file_manager->getGPDir(), 0) == 0); m_editable = (filename.find(file_manager->getGPDir(), 0) == 0);
m_group = group;
reload(); reload();
} // GrandPrixData } // GrandPrixData
@ -67,6 +69,7 @@ void GrandPrixData::createRandomGP(const unsigned int number_of_tracks,
m_id = "random"; m_id = "random";
m_name = "Random Grand Prix"; m_name = "Random Grand Prix";
m_editable = false; m_editable = false;
m_group = GP_NONE;
if(new_tracks) if(new_tracks)
{ {
@ -202,6 +205,15 @@ void GrandPrixData::setEditable(const bool editable)
m_editable = editable; m_editable = editable;
} // setEditable } // setEditable
// ----------------------------------------------------------------------------
/** Sets the group of this grand prix.
* \param editable New value.
*/
void GrandPrixData::setGroup(const enum GPGroupType group)
{
m_group = group;
} // setGroup
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Reloads grand prix from file. /** Reloads grand prix from file.
*/ */
@ -241,10 +253,9 @@ void GrandPrixData::reload()
const int amount = root->getNumNodes(); const int amount = root->getNumNodes();
if (amount == 0) if (amount == 0)
{ {
Log::error("GrandPrixData", Log::warn("GrandPrixData",
"Error while trying to read grandprix file '%s': " "Grandprix file '%s': There is no track defined",
"There is no track defined", m_filename.c_str()); m_filename.c_str());
throw std::runtime_error("No track defined");
} }
// Every iteration means parsing one track entry // Every iteration means parsing one track entry

View File

@ -36,6 +36,17 @@ class Track;
*/ */
class GrandPrixData class GrandPrixData
{ {
public:
/** Used to classify GPs into groups */
enum GPGroupType
{
GP_NONE = 0, ///< No group
GP_STANDARD, ///< Standard GP, included with the game
GP_USER_DEFINED, ///< Created by the user
GP_ADDONS, ///< Add-on GP
GP_GROUP_COUNT ///< Number of groups
}; // GPGroupType
private: private:
/** The name of the grand prix. */ /** The name of the grand prix. */
irr::core::stringw m_name; irr::core::stringw m_name;
@ -60,6 +71,9 @@ private:
/** Wether the user can edit this grand prix or not */ /** Wether the user can edit this grand prix or not */
bool m_editable; bool m_editable;
/** Group to which this GP belongs. */
enum GPGroupType m_group;
/** In the last GP Fort Magma can not be used untill the final challenge. /** In the last GP Fort Magma can not be used untill the final challenge.
* In order to provide still 5 tracks/GP, the last GP is only using 4 * In order to provide still 5 tracks/GP, the last GP is only using 4
* tracks in story mode, but once nolok is unlocked Fort Magma becomes * tracks in story mode, but once nolok is unlocked Fort Magma becomes
@ -84,7 +98,7 @@ public:
# pragma warning(disable:4290) # pragma warning(disable:4290)
#endif #endif
/** Load the GrandPrixData from the given filename */ /** Load the GrandPrixData from the given filename */
GrandPrixData(const std::string& filename); GrandPrixData(const std::string& filename, enum GPGroupType group);
/** Needed for simple creation of an instance of GrandPrixData */ /** Needed for simple creation of an instance of GrandPrixData */
GrandPrixData() {}; GrandPrixData() {};
@ -103,6 +117,7 @@ public:
void setName(const irr::core::stringw& name); void setName(const irr::core::stringw& name);
void setFilename(const std::string& filename); void setFilename(const std::string& filename);
void setEditable(const bool editable); void setEditable(const bool editable);
void setGroup(const enum GPGroupType group);
/** Load the grand prix from the file set by the constructor or the grand /** Load the grand prix from the file set by the constructor or the grand
* prix editor */ * prix editor */
void reload(); void reload();
@ -141,6 +156,10 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the filename of the grand prix xml file. */ /** Returns the filename of the grand prix xml file. */
const std::string& getFilename() const { return m_filename; } const std::string& getFilename() const { return m_filename; }
// ------------------------------------------------------------------------
/** Returns the group. */
enum GPGroupType getGroup() const { return m_group; }
}; // GrandPrixData }; // GrandPrixData
#endif #endif

View File

@ -20,11 +20,11 @@
#include "config/user_config.hpp" #include "config/user_config.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "race/grand_prix_data.hpp"
#include "utils/string_utils.hpp" #include "utils/string_utils.hpp"
#include <algorithm> #include <algorithm>
#include <set> #include <set>
#include <utility>
#include <sstream> #include <sstream>
GrandPrixManager *grand_prix_manager = NULL; GrandPrixManager *grand_prix_manager = NULL;
@ -47,44 +47,47 @@ GrandPrixManager::~GrandPrixManager()
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void GrandPrixManager::loadFiles() void GrandPrixManager::loadFiles()
{ {
// Add the directories to a set to avoid duplicates
std::set<std::string> dirs; std::set<std::string> dirs;
std::string dir;
// Add all the directories to a set to avoid duplicates //Standard GPs
dirs.insert(file_manager->getAsset(FileManager::GRANDPRIX, "")); loadDir(file_manager->getAsset(FileManager::GRANDPRIX, ""), GrandPrixData::GP_STANDARD);
dirs.insert(file_manager->getGPDir());
dirs.insert(UserConfigParams::m_additional_gp_directory);
for (std::set<std::string>::const_iterator it = dirs.begin(); //User defined GPs
it != dirs.end (); ++it) dir = file_manager->getGPDir();
{ if (!dir.empty() && dir[dir.size() - 1] == '/' && dirs.count(dir) == 0)
std::string dir = *it; loadDir(dir, GrandPrixData::GP_USER_DEFINED);
if (!dir.empty() && dir[dir.size() - 1] == '/')
loadDir(dir); //Add-on GPs
} dir = UserConfigParams::m_additional_gp_directory;
if (!dir.empty() && dir[dir.size() - 1] == '/' && dirs.count(dir) == 0)
loadDir(dir, GrandPrixData::GP_ADDONS);
} // loadFiles } // loadFiles
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void GrandPrixManager::loadDir(const std::string& dir) void GrandPrixManager::loadDir(const std::string& dir, enum GrandPrixData::GPGroupType group)
{ {
Log::info("GrandPrixManager", Log::info("GrandPrixManager",
"Loading Grand Prix files from %s", dir.c_str()); "Loading Grand Prix files from %s", dir.c_str());
assert(!dir.empty() && dir[dir.size() - 1] == '/'); assert(!dir.empty() && dir[dir.size() - 1] == '/');
// Findout which grand prix are available and load them // Find out which grand prix are available and load them
std::set<std::string> result; std::set<std::string> result;
file_manager->listFiles(result, dir); file_manager->listFiles(result, dir);
for(std::set<std::string>::iterator i = result.begin(); for(std::set<std::string>::iterator i = result.begin(); i != result.end(); i++)
i != result.end(); i++) {
if (StringUtils::hasSuffix(*i, SUFFIX)) if (StringUtils::hasSuffix(*i, SUFFIX))
load(dir + *i); load(dir + *i, group);
}
} // loadDir } // loadDir
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void GrandPrixManager::load(const std::string& filename) void GrandPrixManager::load(const std::string& filename, enum GrandPrixData::GPGroupType group)
{ {
try try
{ {
GrandPrixData* gp = new GrandPrixData(filename); GrandPrixData* gp = new GrandPrixData(filename, group);
m_gp_data.push_back(gp); m_gp_data.push_back(gp);
Log::debug("GrandPrixManager", Log::debug("GrandPrixManager",
"Grand Prix '%s' loaded from %s", "Grand Prix '%s' loaded from %s",
@ -188,6 +191,7 @@ GrandPrixData* GrandPrixManager::createNewGP(const irr::core::stringw& newName)
gp->setName(newName); gp->setName(newName);
gp->setFilename(file_manager->getGPDir() + newID + SUFFIX); gp->setFilename(file_manager->getGPDir() + newID + SUFFIX);
gp->setEditable(true); gp->setEditable(true);
gp->setGroup(GrandPrixData::GP_USER_DEFINED);
gp->writeToFile(); gp->writeToFile();
m_gp_data.push_back(gp); m_gp_data.push_back(gp);

View File

@ -19,6 +19,8 @@
#ifndef HEADER_GRAND_PRIX_MANAGER_HPP #ifndef HEADER_GRAND_PRIX_MANAGER_HPP
#define HEADER_GRAND_PRIX_MANAGER_HPP #define HEADER_GRAND_PRIX_MANAGER_HPP
#include "race/grand_prix_data.hpp"
#include <vector> #include <vector>
#include <string> #include <string>
@ -38,9 +40,9 @@ private:
/** Load all the grands prix from the 3 directories known */ /** Load all the grands prix from the 3 directories known */
void loadFiles(); void loadFiles();
/** Load all the grands prix in one directory */ /** Load all the grands prix in one directory */
void loadDir(const std::string& dir); void loadDir(const std::string& dir, enum GrandPrixData::GPGroupType group);
/** Load a grand prix and add it to m_gp_data*/ /** Load a grand prix and add it to m_gp_data*/
void load(const std::string &filename); void load(const std::string &filename, enum GrandPrixData::GPGroupType group);
/** Generates a new unique indentifier for a user defined grand prix */ /** Generates a new unique indentifier for a user defined grand prix */
std::string generateId(); std::string generateId();

View File

@ -187,6 +187,7 @@ void EditGPScreen::init()
loadList(m_selected); loadList(m_selected);
m_action.clear(); m_action.clear();
} }
enableButtons();
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -213,7 +214,10 @@ void EditGPScreen::onCancel()
{ {
ModalDialog::dismiss(); ModalDialog::dismiss();
if (m_action == "back") if (m_action == "back")
{
m_gp->reload(); // Discard changes
back(); back();
}
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -231,8 +235,14 @@ void EditGPScreen::loadList(const int selected)
Track* t = track_manager->getTrack(m_gp->getTrackId(i)); Track* t = track_manager->getTrack(m_gp->getTrackId(i));
assert(t != NULL); assert(t != NULL);
video::ITexture* screenShot = irr_driver->getTexture(t->getScreenshotFile()); video::ITexture* screenShot = irr_driver->getTexture(t->getScreenshotFile());
assert(screenShot != NULL); if (screenShot == NULL)
{
screenShot = irr_driver->getTexture(
file_manager->getAsset(FileManager::GUI, "main_help.png"));
}
assert (screenShot != NULL);
m_icons.push_back(m_icon_bank->addTextureAsSprite(screenShot)); m_icons.push_back(m_icon_bank->addTextureAsSprite(screenShot));
row.push_back(GUIEngine::ListWidget::ListCell( row.push_back(GUIEngine::ListWidget::ListCell(
@ -264,15 +274,19 @@ void EditGPScreen::setModified(const bool modified)
save_button->setActivated(); save_button->setActivated();
else else
save_button->setDeactivated(); save_button->setDeactivated();
LabelWidget* header = getWidget<LabelWidget>("title");
assert(header != NULL);
header->setText(m_gp->getName() + (modified ? L" (+)" : L""), true);
enableButtons();
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void EditGPScreen::setSelected(const int selected) void EditGPScreen::setSelected(const int selected)
{ {
assert(getWidget<IconButtonWidget>("up") != NULL);
assert(getWidget<IconButtonWidget>("down") != NULL);
m_selected = selected; m_selected = selected;
enableButtons();
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -327,3 +341,38 @@ bool EditGPScreen::canMoveDown() const
{ {
return (0 <= m_selected && m_selected < m_list->getItemCount() - 1); return (0 <= m_selected && m_selected < m_list->getItemCount() - 1);
} }
// -----------------------------------------------------------------------------
void EditGPScreen::enableButtons()
{
IconButtonWidget* up_button = getWidget<IconButtonWidget>("up");
IconButtonWidget* down_button = getWidget<IconButtonWidget>("down");
IconButtonWidget* edit_button = getWidget<IconButtonWidget>("edit");
IconButtonWidget* remove_button = getWidget<IconButtonWidget>("remove");
assert(up_button != NULL);
assert(down_button != NULL);
assert(edit_button != NULL);
assert(remove_button != NULL);
if (m_selected >= 0 && m_list->getItemCount() > 1)
{
up_button->setActivated();
down_button->setActivated();
}
else
{
up_button->setDeactivated();
down_button->setDeactivated();
}
if (m_selected >= 0)
{
edit_button->setActivated();
remove_button->setActivated();
}
else
{
edit_button->setDeactivated();
remove_button->setDeactivated();
}
}

View File

@ -56,6 +56,8 @@ class EditGPScreen :
bool canMoveUp() const; bool canMoveUp() const;
bool canMoveDown() const; bool canMoveDown() const;
void enableButtons();
GrandPrixData* m_gp; GrandPrixData* m_gp;
GUIEngine::ListWidget* m_list; GUIEngine::ListWidget* m_list;
irr::gui::STKModifiedSpriteBank* m_icon_bank; irr::gui::STKModifiedSpriteBank* m_icon_bank;

View File

@ -23,7 +23,6 @@
#include "guiengine/widgets/dynamic_ribbon_widget.hpp" #include "guiengine/widgets/dynamic_ribbon_widget.hpp"
#include "guiengine/widgets/icon_button_widget.hpp" #include "guiengine/widgets/icon_button_widget.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "race/grand_prix_data.hpp"
#include "race/grand_prix_manager.hpp" #include "race/grand_prix_manager.hpp"
#include "states_screens/state_manager.hpp" #include "states_screens/state_manager.hpp"
#include "states_screens/edit_gp_screen.hpp" #include "states_screens/edit_gp_screen.hpp"
@ -39,12 +38,27 @@ using namespace irr::core;
DEFINE_SCREEN_SINGLETON( GrandPrixEditorScreen ); DEFINE_SCREEN_SINGLETON( GrandPrixEditorScreen );
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
GrandPrixEditorScreen::GrandPrixEditorScreen() GrandPrixEditorScreen::GrandPrixEditorScreen()
: Screen("gpeditor.stkgui"), m_selection(NULL) : Screen("gpeditor.stkgui"), m_selection(NULL), m_gpgroup(GrandPrixData::GP_NONE)
{ {
} }
// -----------------------------------------------------------------------------
void GrandPrixEditorScreen::beforeAddingWidget()
{
RibbonWidget* tabs = getWidget<RibbonWidget>("gpgroups");
assert (tabs != NULL);
tabs->clearAllChildren();
for (int i = 0; i < GrandPrixData::GP_GROUP_COUNT; i++)
{
tabs->addTextChild(getGroupName((enum GrandPrixData::GPGroupType)i),
StringUtils::toString(i));
}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void GrandPrixEditorScreen::loadedFromFile() void GrandPrixEditorScreen::loadedFromFile()
{ {
@ -54,13 +68,20 @@ void GrandPrixEditorScreen::loadedFromFile()
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void GrandPrixEditorScreen::eventCallback(Widget* widget, const std::string& name, const int playerID) void GrandPrixEditorScreen::eventCallback(Widget* widget, const std::string& name, const int playerID)
{ {
if (name == "gplist")
{
DynamicRibbonWidget* gplist_widget = getWidget<DynamicRibbonWidget>("gplist"); DynamicRibbonWidget* gplist_widget = getWidget<DynamicRibbonWidget>("gplist");
assert (gplist_widget != NULL); assert (gplist_widget != NULL);
std::string selected = gplist_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER); std::string selected = gplist_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
if (!selected.empty()) if (!selected.empty())
{
if (m_selection != NULL && selected == m_selection->getId() && m_selection->isEditable())
showEditScreen(m_selection);
else
setSelection (grand_prix_manager->getGrandPrix(selected)); setSelection (grand_prix_manager->getGrandPrix(selected));
}
if (name == "menu") }
else if (name == "menu")
{ {
RibbonWidget* menu = getWidget<RibbonWidget>("menu"); RibbonWidget* menu = getWidget<RibbonWidget>("menu");
assert(menu != NULL); assert(menu != NULL);
@ -70,52 +91,40 @@ void GrandPrixEditorScreen::eventCallback(Widget* widget, const std::string& nam
{ {
new EnterGPNameDialog(this, 0.5f, 0.4f); new EnterGPNameDialog(this, 0.5f, 0.4f);
} }
else if (m_action == "edit") else if (m_action == "edit" && m_selection != NULL)
{
if (m_selection->isEditable())
{ {
showEditScreen(m_selection); showEditScreen(m_selection);
} }
else else if (m_action == "remove" && m_selection != NULL)
{
new MessageDialog(
_("You can't edit the '%s' grand prix.\nYou might want to copy it first",
m_selection->getName().c_str()),
MessageDialog::MESSAGE_DIALOG_OK, NULL, false);
}
}
else if (m_action == "remove")
{
if (m_selection->isEditable())
{ {
new MessageDialog( new MessageDialog(
_("Are you sure you want to remove '%s'?", m_selection->getName().c_str()), _("Are you sure you want to remove '%s'?", m_selection->getName().c_str()),
MessageDialog::MESSAGE_DIALOG_CONFIRM, MessageDialog::MESSAGE_DIALOG_CONFIRM,
this, false); this, false);
} }
else else if (m_action == "rename" && m_selection != NULL)
{
new MessageDialog(
_("You can't remove '%s'.", m_selection->getName().c_str()),
MessageDialog::MESSAGE_DIALOG_OK, NULL, false);
}
}
else if (m_action == "rename")
{
if (m_selection->isEditable())
{ {
new EnterGPNameDialog(this, 0.5f, 0.4f); new EnterGPNameDialog(this, 0.5f, 0.4f);
} }
else
{
new MessageDialog(
_("You can't rename '%s'.", m_selection->getName().c_str()),
MessageDialog::MESSAGE_DIALOG_OK, NULL, false);
} }
else if (name == "gpgroups")
{
RibbonWidget* tabs = getWidget<RibbonWidget>("gpgroups");
assert(tabs != NULL);
enum GrandPrixData::GPGroupType group = (enum GrandPrixData::GPGroupType)atoi(
tabs->getSelectionIDString(PLAYER_ID_GAME_MASTER).c_str());
if (m_gpgroup != group)
{
m_gpgroup = group;
loadGPList();
setSelection(NULL);
} }
} }
else if (name == "back") else if (name == "back")
{ {
m_gpgroup = GrandPrixData::GP_NONE;
setSelection(NULL);
StateManager::get()->escapePressed(); StateManager::get()->escapePressed();
} }
} }
@ -123,27 +132,12 @@ void GrandPrixEditorScreen::eventCallback(Widget* widget, const std::string& nam
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void GrandPrixEditorScreen::init() void GrandPrixEditorScreen::init()
{ {
if (grand_prix_manager->getNumberOfGrandPrix() > 0) RibbonWidget* tabs = getWidget<RibbonWidget>("gpgroups");
{ assert (tabs != NULL);
if (m_selection == NULL)
{ tabs->select (StringUtils::toString(m_gpgroup), PLAYER_ID_GAME_MASTER);
loadGPList(); loadGPList();
setSelection (grand_prix_manager->getGrandPrix(0)); setSelection(m_selection);
}
else
{
std::string id = m_selection->getId();
grand_prix_manager->reload();
loadGPList();
m_selection = grand_prix_manager->editGrandPrix(id);
m_selection->reload();
setSelection (m_selection);
}
}
else
{
loadGPList();
}
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -153,11 +147,25 @@ void GrandPrixEditorScreen::setSelection (const GrandPrixData* gpdata)
assert(gpname_widget != NULL); assert(gpname_widget != NULL);
DynamicRibbonWidget* gplist_widget = getWidget<DynamicRibbonWidget>("gplist"); DynamicRibbonWidget* gplist_widget = getWidget<DynamicRibbonWidget>("gplist");
assert (gplist_widget != NULL); assert (gplist_widget != NULL);
DynamicRibbonWidget* tracks_widget = getWidget<DynamicRibbonWidget>("tracks");
assert(tracks_widget != NULL);
if (gpdata == NULL)
{
m_selection = NULL;
gpname_widget->setText (L"Please select a Grand Prix", true);
tracks_widget->clearItems();
tracks_widget->updateItemDisplay();
}
else
{
m_selection = grand_prix_manager->editGrandPrix(gpdata->getId()); m_selection = grand_prix_manager->editGrandPrix(gpdata->getId());
gpname_widget->setText (gpdata->getName(), true); gpname_widget->setText (gpdata->getName(), true);
gplist_widget->setSelection(m_selection->getId(), PLAYER_ID_GAME_MASTER, true); gplist_widget->setSelection(m_selection->getId(), PLAYER_ID_GAME_MASTER, true);
loadTrackList (gpdata->getId()); loadTrackList (gpdata->getId());
}
enableButtons();
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -219,9 +227,16 @@ void GrandPrixEditorScreen::loadGPList()
Track* track = track_manager->getTrack(tracks[t]); Track* track = track_manager->getTrack(tracks[t]);
sshot_files.push_back(track->getScreenshotFile()); sshot_files.push_back(track->getScreenshotFile());
} }
if (sshot_files.empty())
sshot_files.push_back(file_manager->getAsset(FileManager::GUI,"main_help.png"));
gplist_widget->addAnimatedItem(translations->fribidize(gp->getName()), gp->getId(), if (m_gpgroup == GrandPrixData::GP_NONE || m_gpgroup == gp->getGroup())
sshot_files, 2.0f, 0, IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE ); {
gplist_widget->addAnimatedItem(
translations->fribidize(gp->getName()),
gp->getId(), sshot_files, 2.0f, 0,
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE );
}
} }
gplist_widget->updateItemDisplay(); gplist_widget->updateItemDisplay();
@ -236,14 +251,45 @@ void GrandPrixEditorScreen::showEditScreen(GrandPrixData* gp)
StateManager::get()->pushScreen(edit); StateManager::get()->pushScreen(edit);
} }
// -----------------------------------------------------------------------------
void GrandPrixEditorScreen::enableButtons()
{
IconButtonWidget* copy_button = getWidget<IconButtonWidget>("copy");
IconButtonWidget* edit_button = getWidget<IconButtonWidget>("edit");
IconButtonWidget* remove_button = getWidget<IconButtonWidget>("remove");
IconButtonWidget* rename_button = getWidget<IconButtonWidget>("rename");
assert(copy_button != NULL);
assert(edit_button != NULL);
assert(remove_button != NULL);
assert(rename_button != NULL);
if (m_selection != NULL && m_selection->getNumberOfTracks() > 0)
copy_button->setActivated();
else
copy_button->setDeactivated();
if (m_selection != NULL && m_selection->isEditable())
{
edit_button->setActivated();
remove_button->setActivated();
rename_button->setActivated();
}
else
{
edit_button->setDeactivated();
remove_button->setDeactivated();
rename_button->setDeactivated();
}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void GrandPrixEditorScreen::onNewGPWithName(const stringw& newName) void GrandPrixEditorScreen::onNewGPWithName(const stringw& newName)
{ {
if (m_action == "copy") if (m_action == "copy" && m_selection != NULL)
{ {
setSelection(grand_prix_manager->copy(m_selection->getId(), newName)); setSelection(grand_prix_manager->copy(m_selection->getId(), newName));
} }
else if (m_action == "rename") else if (m_action == "rename" && m_selection != NULL)
{ {
m_selection->setName(newName); m_selection->setName(newName);
m_selection->writeToFile(); m_selection->writeToFile();
@ -254,14 +300,14 @@ void GrandPrixEditorScreen::onNewGPWithName(const stringw& newName)
} }
loadGPList(); loadGPList();
if (m_action != "rename") if (m_action != "rename" && m_selection != NULL)
showEditScreen(m_selection); showEditScreen(m_selection);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void GrandPrixEditorScreen::onConfirm() void GrandPrixEditorScreen::onConfirm()
{ {
if (m_action == "remove") if (m_action == "remove" && m_selection != NULL)
{ {
grand_prix_manager->remove(m_selection->getId()); grand_prix_manager->remove(m_selection->getId());
loadGPList(); loadGPList();
@ -270,3 +316,16 @@ void GrandPrixEditorScreen::onConfirm()
} }
ModalDialog::dismiss(); ModalDialog::dismiss();
} }
// ----------------------------------------------------------------------------
const wchar_t* GrandPrixEditorScreen::getGroupName(enum GrandPrixData::GPGroupType group)
{
switch (group)
{
case GrandPrixData::GP_NONE: return _("All");
case GrandPrixData::GP_STANDARD: return _("Standard");
case GrandPrixData::GP_USER_DEFINED: return _("User defined");
case GrandPrixData::GP_ADDONS: return _("Add-Ons");
default: return L"???";
}
}

View File

@ -19,6 +19,7 @@
#define HEADER_GRAND_PRIX_EDITOR_SCREEN_HPP #define HEADER_GRAND_PRIX_EDITOR_SCREEN_HPP
#include "guiengine/screen.hpp" #include "guiengine/screen.hpp"
#include "race/grand_prix_data.hpp"
#include "states_screens/dialogs/enter_gp_name_dialog.hpp" #include "states_screens/dialogs/enter_gp_name_dialog.hpp"
#include "states_screens/dialogs/message_dialog.hpp" #include "states_screens/dialogs/message_dialog.hpp"
@ -45,15 +46,22 @@ class GrandPrixEditorScreen :
void loadGPList(); void loadGPList();
void loadTrackList(const std::string& gpname); void loadTrackList(const std::string& gpname);
void showEditScreen(GrandPrixData* gp); void showEditScreen(GrandPrixData* gp);
void enableButtons();
void onNewGPWithName(const irr::core::stringw& newName); void onNewGPWithName(const irr::core::stringw& newName);
void onConfirm(); void onConfirm();
static const wchar_t* getGroupName(enum GrandPrixData::GPGroupType group);
GrandPrixData* m_selection; GrandPrixData* m_selection;
std::string m_action; std::string m_action;
enum GrandPrixData::GPGroupType m_gpgroup;
public: public:
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void beforeAddingWidget() OVERRIDE;
/** \brief implement callback from parent class GUIEngine::Screen */ /** \brief implement callback from parent class GUIEngine::Screen */
virtual void loadedFromFile() OVERRIDE; virtual void loadedFromFile() OVERRIDE;

View File

@ -185,6 +185,10 @@ void TracksScreen::init()
const GrandPrixData* gp = grand_prix_manager->getGrandPrix(n); const GrandPrixData* gp = grand_prix_manager->getGrandPrix(n);
const std::vector<std::string> tracks = gp->getTrackNames(true); const std::vector<std::string> tracks = gp->getTrackNames(true);
//Skip epmpty GPs
if (gp->getNumberOfTracks()==0)
continue;
std::vector<std::string> screenshots; std::vector<std::string> screenshots;
for (unsigned int t=0; t<tracks.size(); t++) for (unsigned int t=0; t<tracks.size(); t++)
{ {