Fixed renaming of local player, removed old rename dialog.

This commit is contained in:
hiker
2014-05-26 08:25:33 +10:00
parent 64492fb6cb
commit 4cc59a56ce
6 changed files with 63 additions and 277 deletions

View File

@@ -1,174 +0,0 @@
// 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/dialogs/enter_player_name_dialog.hpp"
#include "audio/sfx_manager.hpp"
#include "challenges/unlock_manager.hpp"
#include "config/player_manager.hpp"
#include "config/player_profile.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/widgets/button_widget.hpp"
#include "guiengine/widgets/label_widget.hpp"
#include "guiengine/widgets/text_box_widget.hpp"
#include "states_screens/state_manager.hpp"
#include "utils/translation.hpp"
#include "utils/string_utils.hpp"
#include <IGUIEnvironment.h>
using namespace GUIEngine;
using namespace irr;
using namespace irr::core;
using namespace irr::gui;
// -----------------------------------------------------------------------------
EnterPlayerNameDialog::EnterPlayerNameDialog(INewPlayerListener* listener,
const float w, const float h,
const core::stringw &name):
ModalDialog(w, h)
{
m_listener = listener;
m_self_destroy = false;
loadFromFile("enter_player_name_dialog.stkgui");
TextBoxWidget* text_field = getWidget<TextBoxWidget>("textfield");
assert(text_field != NULL);
text_field->setText(name);
text_field->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
if(name!=L"")
m_original_player = PlayerManager::get()->getPlayer(name);
else
m_original_player = NULL;
core::stringw username = name;
// If there is no player (i.e. first start of STK), try to pick
// a good default name
if (PlayerManager::get()->getNumPlayers() == 0)
{
if (getenv("USERNAME") != NULL) // for windows
username = getenv("USERNAME");
else if (getenv("USER") != NULL) // Linux, Macs
username = getenv("USER");
else if (getenv("LOGNAME") != NULL) // Linux, Macs
username = getenv("LOGNAME");
}
text_field->setText(username.c_str());
} // EnterPlayerNameDialog
// -----------------------------------------------------------------------------
EnterPlayerNameDialog::~EnterPlayerNameDialog()
{
} // ~EnterPlayerNameDialog
// -----------------------------------------------------------------------------
GUIEngine::EventPropagation
EnterPlayerNameDialog::processEvent(const std::string& eventSource)
{
if (eventSource == "cancel")
{
dismiss();
return GUIEngine::EVENT_BLOCK;
}
else if (eventSource == "ok")
{
onEnterPressedInternal();
return GUIEngine::EVENT_BLOCK;
}
return GUIEngine::EVENT_LET;
} // processEvent
// -----------------------------------------------------------------------------
void EnterPlayerNameDialog::onEnterPressedInternal()
{
// ---- Cancel button pressed
const int playerID = PLAYER_ID_GAME_MASTER;
ButtonWidget* cancelButton = getWidget<ButtonWidget>("cancel");
if (GUIEngine::isFocusedForPlayer(cancelButton, playerID))
{
std::string fakeEvent = "cancel";
processEvent(fakeEvent);
return;
}
// ---- Otherwise, see if we can accept the new name
TextBoxWidget* text_field = getWidget<TextBoxWidget>("textfield");
stringw player_name = text_field->getText().trim();
if (StringUtils::notEmpty(player_name))
{
// check for duplicates
const int amount = PlayerManager::get()->getNumPlayers();
for (int n=0; n<amount; n++)
{
if (PlayerManager::get()->getPlayer(n)->getName() == player_name)
{
LabelWidget* label = getWidget<LabelWidget>("title");
label->setText(_("Cannot add a player with this name."), false);
sfx_manager->quickSound( "anvil" );
return;
}
}
if(m_original_player)
{
m_original_player->setName(player_name);
}
else
{
// Finally, add the new player.
PlayerManager::get()->addNewPlayer(player_name);
PlayerManager::get()->save();
}
// It's unsafe to delete from inside the event handler so we do it
// in onUpdate (which checks for m_self_destroy)
m_self_destroy = true;
} // if valid name
else
{
LabelWidget* label = getWidget<LabelWidget>("title");
label->setText(_("Cannot add a player with this name."), false);
sfx_manager->quickSound( "anvil" );
}
} // onEnterPressedInternal
// -----------------------------------------------------------------------------
void EnterPlayerNameDialog::onUpdate(float dt)
{
// It's unsafe to delete from inside the event handler so we do it here
if (m_self_destroy)
{
TextBoxWidget* text_field = getWidget<TextBoxWidget>("textfield");
stringw player_name = text_field->getText().trim();
// irrLicht is too stupid to remove focus from deleted widgets
// so do it by hand
GUIEngine::getGUIEnv()->removeFocus( text_field->getIrrlichtElement() );
GUIEngine::getGUIEnv()->removeFocus( m_irrlicht_window );
// we will destroy the dialog before notifying the listener to be safer.
// but in order not to crash we must make a local copy of the listern
// otherwise we will crash
INewPlayerListener* listener = m_listener;
ModalDialog::dismiss();
if (listener != NULL) listener->onNewPlayerWithName( player_name );
}
} // onUpdate

View File

@@ -1,77 +0,0 @@
// 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.
#ifndef HEADER_ENTERPLAYERNAME_DIALOG_HPP
#define HEADER_ENTERPLAYERNAME_DIALOG_HPP
#include <irrString.h>
#include "guiengine/modaldialog.hpp"
#include "guiengine/widgets/text_box_widget.hpp"
namespace GUIEngine
{
class TextBoxWidget;
class ButtonWidget;
class LabelWidget;
}
class PlayerProfile;
/** Dialog that allows the player to enter the name for a new player or
* rename an existing player.
* \ingroup states_screens
*/
class EnterPlayerNameDialog : public GUIEngine::ModalDialog
{
public:
class INewPlayerListener
{
public:
virtual void onNewPlayerWithName(const irr::core::stringw& newName) = 0;
virtual ~INewPlayerListener(){}
};
private:
INewPlayerListener* m_listener;
bool m_self_destroy;
/** Pointer to the original PlayerProfile if it's a rename, or NULL if it
* is a new player. */
PlayerProfile *m_original_player;
public:
/**
* Creates a modal dialog with given percentage of screen width and height
*/
EnterPlayerNameDialog(INewPlayerListener* listener, const float percentWidth,
const float percentHeight, const core::stringw &name="");
~EnterPlayerNameDialog();
void onEnterPressedInternal();
GUIEngine::EventPropagation processEvent(const std::string& eventSource);
virtual void onUpdate(float dt);
//virtual void onTextUpdated();
};
#endif

View File

@@ -44,6 +44,7 @@ DEFINE_SCREEN_SINGLETON( RegisterScreen );
RegisterScreen::RegisterScreen() : Screen("online/register.stkgui")
{
m_existing_player = NULL;
} // RegisterScreen
// -----------------------------------------------------------------------------
@@ -54,7 +55,11 @@ void RegisterScreen::init()
// If there is no player (i.e. first start of STK), try to pick
// a good default name
stringw username = "";
if (PlayerManager::get()->getNumPlayers() == 0)
if(m_existing_player)
{
username = m_existing_player->getName();
}
else if (PlayerManager::get()->getNumPlayers() == 0)
{
if (getenv("USERNAME") != NULL) // for windows
username = getenv("USERNAME");
@@ -63,8 +68,8 @@ void RegisterScreen::init()
else if (getenv("LOGNAME") != NULL) // Linux, Macs
username = getenv("LOGNAME");
}
getWidget<TextBoxWidget>("local_username")->setText(username);
getWidget<TextBoxWidget>("local_username")->setText(username);
TextBoxWidget *password_widget = getWidget<TextBoxWidget>("password");
password_widget->setPasswordBox(true,L'*');
@@ -78,8 +83,15 @@ void RegisterScreen::init()
m_signup_request = NULL;
m_info_message_shown = false;
makeEntryFieldsVisible(true);
} // init
// -----------------------------------------------------------------------------
void RegisterScreen::setRename(PlayerProfile *player)
{
m_existing_player = player;
} // setRename
// -----------------------------------------------------------------------------
/** Shows or hides the entry fields for online registration, depending on
* online mode.
@@ -87,6 +99,13 @@ void RegisterScreen::init()
*/
void RegisterScreen::makeEntryFieldsVisible(bool online)
{
// In case of a rename, hide all other fields.
if(m_existing_player)
{
m_info_widget->setVisible(false);
getWidget<CheckBoxWidget>("online")->setVisible(false);
online = false;
}
getWidget<TextBoxWidget>("username")->setVisible(online);
getWidget<LabelWidget >("label_username")->setVisible(online);
getWidget<TextBoxWidget>("password")->setVisible(online);
@@ -103,7 +122,7 @@ void RegisterScreen::makeEntryFieldsVisible(bool online)
/** If necessary creates the local user.
* \param local_name Name of the local user.
*/
void RegisterScreen::registerLocal(const stringw &local_name)
void RegisterScreen::handleLocalName(const stringw &local_name)
{
if (local_name.size()==0)
return;
@@ -111,10 +130,22 @@ void RegisterScreen::registerLocal(const stringw &local_name)
// If a local player with that name does not exist, create one
if(!PlayerManager::get()->getPlayer(local_name))
{
PlayerProfile *player = PlayerManager::get()->addNewPlayer(local_name);
PlayerProfile *player;
// If it's a rename, change the name of the player
if(m_existing_player && local_name.size()>0)
{
m_existing_player->setName(local_name);
player = m_existing_player;
}
else
{
player = PlayerManager::get()->addNewPlayer(local_name);
}
PlayerManager::get()->save();
if(player)
if (player)
{
PlayerManager::get()->setCurrentPlayer(player);
}
else
{
m_info_widget->setErrorColor();
@@ -122,8 +153,13 @@ void RegisterScreen::registerLocal(const stringw &local_name)
false);
}
}
} // registerLocal
else
{
m_info_widget->setErrorColor();
m_info_widget->setText(_("Could not create player '%s'.", local_name),
false);
}
} // handleLocalName
// -----------------------------------------------------------------------------
/** Handles the actual registration process. It does some tests on id, password
@@ -134,14 +170,13 @@ void RegisterScreen::doRegister()
stringw local_name = getWidget<TextBoxWidget>("local_username")
->getText().trim();
registerLocal(local_name);
handleLocalName(local_name);
// If no online account is requested, don't register
if(!getWidget<CheckBoxWidget>("online")->getState())
if(!getWidget<CheckBoxWidget>("online")->getState() || m_existing_player)
{
if(local_name.size()>0)
UserScreen::getInstance()->newUserAdded(local_name, L"");
StateManager::get()->popMenu();
m_existing_player = NULL;
return;
}
@@ -190,7 +225,11 @@ void RegisterScreen::doRegister()
sfx_manager->quickSound( "anvil" );
if(local_name.size()>0)
UserScreen::getInstance()->newUserAdded(local_name, username);
{
PlayerProfile *player = PlayerManager::get()->getPlayer(local_name);
if (player)
player->setLastOnlineName(username);
}
} // doRegister
// -----------------------------------------------------------------------------
@@ -283,6 +322,7 @@ void RegisterScreen::eventCallback(Widget* widget, const std::string& name,
}
else if (name == "back")
{
m_existing_player = NULL;
StateManager::get()->escapePressed();
}
@@ -291,6 +331,7 @@ void RegisterScreen::eventCallback(Widget* widget, const std::string& name,
// -----------------------------------------------------------------------------
bool RegisterScreen::onEscapePressed()
{
m_existing_player = NULL;
if (PlayerManager::get()->getNumPlayers() == 0)
{
// Must be first time start, and player cancelled player creation

View File

@@ -23,6 +23,9 @@
namespace GUIEngine { class Widget; class LabelWidget;
class RibbonWidget; }
namespace Online { class XMLRequest; }
class PlayerProfile;
/**
* \brief Screen to register an online account.
* \ingroup states_screens
@@ -34,7 +37,7 @@ private:
friend class GUIEngine::ScreenSingleton<RegisterScreen>;
void makeEntryFieldsVisible(bool online);
void registerLocal(const irr::core::stringw &local_name);
void handleLocalName(const irr::core::stringw &local_name);
void doRegister();
void init();
RegisterScreen();
@@ -48,6 +51,10 @@ private:
/** The XML request to the server. */
Online::XMLRequest *m_signup_request;
/** Pointer to an existing player if the screen is doing a rename,
* NULL otherwise. */
PlayerProfile *m_existing_player;
/** True if the info message (email was sent...) is shown. */
bool m_info_message_shown;
@@ -57,6 +64,7 @@ public:
virtual void loadedFromFile() OVERRIDE {};
virtual void onUpdate(float dt) OVERRIDE;
virtual bool onEscapePressed() OVERRIDE;
void setRename(PlayerProfile *player);
void acceptTerms();
/** \brief implement callback from parent class GUIEngine::Screen */

View File

@@ -265,6 +265,7 @@ void BaseUserScreen::eventCallback(Widget* widget,
else if (button == "rename")
{
PlayerProfile *cp = getSelectedPlayer();
RegisterScreen::getInstance()->setRename(cp);
StateManager::get()->pushScreen(RegisterScreen::getInstance());
// Init will automatically be called, which
// refreshes the player list
@@ -467,17 +468,6 @@ void BaseUserScreen::logoutError(const irr::core::stringw & error_message)
m_options_widget->setActivated();
} // logoutError
// ----------------------------------------------------------------------------
void BaseUserScreen::newUserAdded(const irr::core::stringw &local_name,
const irr::core::stringw &online_name)
{
PlayerProfile *player = PlayerManager::get()->getPlayer(local_name);
// Set the online name, only if the user clicks on 'ok' will this
// new player become the current player (since we potentially have to
// log out the old current player).
player->setLastOnlineName(online_name);
} // newUserAdded
// ----------------------------------------------------------------------------
/** Called when a player will be deleted.
*/

View File

@@ -113,8 +113,6 @@ public:
void loginError(const irr::core::stringw &error_message);
void logoutSuccessful();
void logoutError(const irr::core::stringw &error_message);
void newUserAdded(const irr::core::stringw &local_name,
const irr::core::stringw &online_name);
}; // class BaseUserScreen
// ============================================================================