Added a tabbed version of the user screen, and integrated it into

the option menu of STK.
This commit is contained in:
hiker
2014-05-15 22:59:21 +10:00
parent 137b5033dd
commit 0459c33f66
8 changed files with 205 additions and 59 deletions

View File

@@ -0,0 +1,69 @@
<stkgui>
<div x="1%" y="1%" width="98%" height="98%" layout="vertical-row" >
<header text_align="center" width="80%" align="center" text="SuperTuxKart Options"/>
<spacer height="15" width="10"/>
<tabs id="options_choice" height="10%" max_height="110" x="2%" width="98%" align="center">
<icon-button id="tab_video" width="128" height="128" icon="gui/options_video.png"/>
<icon-button id="tab_audio" width="128" height="128" icon="gui/options_audio.png"/>
<icon-button id="tab_ui" width="128" height="128" icon="gui/options_ui.png"/>
<icon-button id="tab_players" width="128" height="128" icon="gui/options_players.png"
I18N="Section in the settings menu" text="Players"/>
<icon-button id="tab_controls" width="128" height="128" icon="gui/options_input.png"/>
</tabs>
<box proportion="1" width="98%" layout="vertical-row">
<spacer height="15" width="10"/>
<scrollable_ribbon id="players" height="120" y="10" x="10" width="98%" align="center" label_location="each"
square_items="true" child_width="160" child_height="120" />
<spacer height="15" width="10"/>
<div width="80%" align="center" layout="vertical-row" height="fit">
<div width="100%" height="fit" layout="horizontal-row" >
<label proportion="1" height="100%" text_align="left" I18N="In the login screen" text="Online"/>
<checkbox id="online" I18N="In the login screen" text_align="left"/>
</div>
<!-- Disable guest accounts for now
<div width="100%" height="fit" layout="horizontal-row" >
<label id="label_guest" proportion="1" height="100%" text_align="left"
I18N="In the login screen" text="Guest login"/>
<checkbox id="guest" I18N="In the login screen" text_align="left"/>
</div>
-->
<div width="100%" height="fit" layout="horizontal-row" >
<label id="label_username" proportion="1" height="100%" text_align="left"
I18N="In the login screen" text="Username"/>
<textbox id="username" proportion="2" height="fit" I18N="In the registration dialog"/>
</div>
<spacer height="20" width="20"/>
<div width="100%" height="fit" layout="horizontal-row" >
<label id="label_password" proportion="1" height="100%" text_align="left"
I18N="In the registration dialog" text="Password"/>
<textbox id="password" proportion="2" height="fit" I18N="In the registration dialog"/>
</div>
</div>
<div width="80%" align="center" layout="vertical-row" height="fit">
<label id="message" width="80%" align="center" text_align="left"/>
</div>
<spacer width="20" height="25"/>
<buttonbar id="options" width="90%" height="13%" align="bottom">
<icon-button id="ok" width="64" height="64" icon="gui/green_check.png"
I18N="Login dialog" text="OK" label_location="bottom"/>
<icon-button id="new_user" width="64" height="64" icon="gui/main_help.png"
I18N="Login dialog" text="Create new user" label_location="bottom"/>
<icon-button id="rename" width="64" height="64" icon="gui/main_help.png"
I18N="Login dialog" text="Rename" label_location="bottom"/>
<icon-button id="delete" width="64" height="64" icon="gui/main_help.png"
I18N="Login dialog" text="Delete" label_location="bottom"/>
<icon-button id="cancel" width="64" height="64" icon="gui/main_help.png"
I18N="Login dialog" text="Cancel" label_location="bottom"/>
</buttonbar>
</box>
<spacer width="20" height="15"/>
</div>
</stkgui>

View File

@@ -425,8 +425,7 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name,
StateManager::get()->pushScreen(OnlineScreen::getInstance());
else
{
UserScreen *login = UserScreen::getInstance();
login->setIsPopup(true);
BaseUserScreen *login = UserScreen::getInstance();
StateManager::get()->pushScreen(login);
}
}

View File

@@ -28,10 +28,10 @@
#include "guiengine/widget.hpp"
#include "io/file_manager.hpp"
#include "states_screens/options_screen_input.hpp"
#include "states_screens/options_screen_players.hpp"
#include "states_screens/options_screen_ui.hpp"
#include "states_screens/options_screen_video.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/user_screen.hpp"
#include "utils/translation.hpp"
#include <iostream>
@@ -107,7 +107,7 @@ void OptionsScreenAudio::eventCallback(Widget* widget, const std::string& name,
if (selection == "tab_audio") StateManager::get()->replaceTopMostScreen(OptionsScreenAudio::getInstance());
else if (selection == "tab_video") StateManager::get()->replaceTopMostScreen(OptionsScreenVideo::getInstance());
else if (selection == "tab_players") StateManager::get()->replaceTopMostScreen(OptionsScreenPlayers::getInstance());
else if (selection == "tab_players") StateManager::get()->replaceTopMostScreen(TabbedUserScreen::getInstance());
else if (selection == "tab_controls") StateManager::get()->replaceTopMostScreen(OptionsScreenInput::getInstance());
else if (selection == "tab_ui") StateManager::get()->replaceTopMostScreen(OptionsScreenUI::getInstance());
}

View File

@@ -29,11 +29,11 @@
#include "io/file_manager.hpp"
#include "states_screens/options_screen_input2.hpp"
#include "states_screens/options_screen_audio.hpp"
#include "states_screens/options_screen_players.hpp"
#include "states_screens/options_screen_video.hpp"
#include "states_screens/options_screen_ui.hpp"
#include "states_screens/dialogs/add_device_dialog.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/user_screen.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
@@ -188,7 +188,7 @@ void OptionsScreenInput::eventCallback(Widget* widget, const std::string& name,
if (selection == "tab_audio") StateManager::get()->replaceTopMostScreen(OptionsScreenAudio::getInstance());
else if (selection == "tab_video") StateManager::get()->replaceTopMostScreen(OptionsScreenVideo::getInstance());
else if (selection == "tab_players") StateManager::get()->replaceTopMostScreen(OptionsScreenPlayers::getInstance());
else if (selection == "tab_players") StateManager::get()->replaceTopMostScreen(TabbedUserScreen::getInstance());
else if (selection == "tab_controls") StateManager::get()->replaceTopMostScreen(OptionsScreenInput::getInstance());
else if (selection == "tab_ui") StateManager::get()->replaceTopMostScreen(OptionsScreenUI::getInstance());
}

View File

@@ -35,9 +35,9 @@
#include "states_screens/main_menu_screen.hpp"
#include "states_screens/options_screen_audio.hpp"
#include "states_screens/options_screen_input.hpp"
#include "states_screens/options_screen_players.hpp"
#include "states_screens/options_screen_video.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/user_screen.hpp"
#include "utils/log.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
@@ -210,7 +210,7 @@ void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, con
if (selection == "tab_audio") StateManager::get()->replaceTopMostScreen(OptionsScreenAudio::getInstance());
else if (selection == "tab_video") StateManager::get()->replaceTopMostScreen(OptionsScreenVideo::getInstance());
else if (selection == "tab_players") StateManager::get()->replaceTopMostScreen(OptionsScreenPlayers::getInstance());
else if (selection == "tab_players") StateManager::get()->replaceTopMostScreen(TabbedUserScreen::getInstance());
else if (selection == "tab_controls") StateManager::get()->replaceTopMostScreen(OptionsScreenInput::getInstance());
}
else if(name == "back")

View File

@@ -32,9 +32,9 @@
#include "states_screens/dialogs/custom_video_settings.hpp"
#include "states_screens/options_screen_audio.hpp"
#include "states_screens/options_screen_input.hpp"
#include "states_screens/options_screen_players.hpp"
#include "states_screens/options_screen_ui.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/user_screen.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
@@ -465,7 +465,7 @@ void OptionsScreenVideo::eventCallback(Widget* widget, const std::string& name,
else if (selection == "tab_video")
screen = OptionsScreenVideo::getInstance();
else if (selection == "tab_players")
screen = OptionsScreenPlayers::getInstance();
screen = TabbedUserScreen::getInstance();
else if (selection == "tab_controls")
screen = OptionsScreenInput::getInstance();
else if (selection == "tab_ui")

View File

@@ -29,31 +29,35 @@
#include "online/messages.hpp"
#include "states_screens/dialogs/message_dialog.hpp"
#include "states_screens/main_menu_screen.hpp"
#include "states_screens/options_screen_audio.hpp"
#include "states_screens/options_screen_input.hpp"
#include "states_screens/options_screen_ui.hpp"
#include "states_screens/options_screen_video.hpp"
#include "states_screens/register_screen.hpp"
#include "states_screens/state_manager.hpp"
using namespace GUIEngine;
DEFINE_SCREEN_SINGLETON( UserScreen );
DEFINE_SCREEN_SINGLETON( UserScreen );
DEFINE_SCREEN_SINGLETON( TabbedUserScreen );
// ----------------------------------------------------------------------------
UserScreen::UserScreen() : Screen("user_screen.stkgui")
BaseUserScreen::BaseUserScreen(const std::string &name) : Screen(name.c_str())
{
m_is_popup_window = false;
} // UserScreen
} // BaseUserScreen
// ----------------------------------------------------------------------------
void UserScreen::loadedFromFile()
void BaseUserScreen::loadedFromFile()
{
} // loadedFromFile
// ----------------------------------------------------------------------------
void UserScreen::init()
void BaseUserScreen::init()
{
m_online_cb = getWidget<CheckBoxWidget>("online");
assert(m_online_cb);
@@ -76,12 +80,6 @@ void UserScreen::init()
m_info_widget->setErrorColor();
Screen::init();
PlayerProfile *player = PlayerManager::getCurrentPlayer();
if (player && !m_is_popup_window)
{
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
return;
}
m_players->clearItems();
std::string current_player_index="";
@@ -121,7 +119,7 @@ void UserScreen::init()
} // init
// ----------------------------------------------------------------------------
PlayerProfile* UserScreen::getSelectedPlayer()
PlayerProfile* BaseUserScreen::getSelectedPlayer()
{
const std::string &s_id = m_players
->getSelectionIDString(PLAYER_ID_GAME_MASTER);
@@ -132,7 +130,7 @@ PlayerProfile* UserScreen::getSelectedPlayer()
// ----------------------------------------------------------------------------
void UserScreen::tearDown()
void BaseUserScreen::tearDown()
{
Screen::tearDown();
} // tearDown
@@ -141,7 +139,7 @@ void UserScreen::tearDown()
/** Called when a user is selected. It updates the online checkbox and
* entrye fields.
*/
void UserScreen::selectUser(int index)
void BaseUserScreen::selectUser(int index)
{
PlayerProfile *profile = PlayerManager::get()->getPlayer(index);
assert(profile);
@@ -183,7 +181,7 @@ void UserScreen::selectUser(int index)
* \param online Online state, which dicates if the entry fields are
* visible (true) or not.
*/
void UserScreen::makeEntryFieldsVisible(bool online)
void BaseUserScreen::makeEntryFieldsVisible(bool online)
{
#ifdef GUEST_ACCOUNTS_ENABLED
getWidget<LabelWidget>("label_guest")->setVisible(online);
@@ -198,7 +196,7 @@ void UserScreen::makeEntryFieldsVisible(bool online)
// ----------------------------------------------------------------------------
/** Called when the user selects anything on the screen.
*/
void UserScreen::eventCallback(Widget* widget,
void BaseUserScreen::eventCallback(Widget* widget,
const std::string& name,
const int player_id)
{
@@ -270,10 +268,10 @@ void UserScreen::eventCallback(Widget* widget,
} // eventCallback
// ----------------------------------------------------------------------------
/** Closes the UserScreen, and makes sure that the right screen is displayed
/** Closes the BaseUserScreen, and makes sure that the right screen is displayed
* next.
*/
void UserScreen::closeScreen()
void BaseUserScreen::closeScreen()
{
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
} // closeScreen
@@ -284,7 +282,7 @@ void UserScreen::closeScreen()
* \param remember_me True if the login details should be remembered,
* so that next time this menu can be skipped.
*/
void UserScreen::login()
void BaseUserScreen::login()
{
// If an error occurs, the callback informing this screen about the
// problem will activate the widget again.
@@ -344,7 +342,7 @@ void UserScreen::login()
/** Called once every frame. It will replace this screen with the main menu
* screen if a successful login happened.
*/
void UserScreen::onUpdate(float dt)
void BaseUserScreen::onUpdate(float dt)
{
if (!m_options_widget->isActivated())
m_info_widget->setText(Online::Messages::loadingDots( _("Signing in")),
@@ -354,7 +352,7 @@ void UserScreen::onUpdate(float dt)
// ----------------------------------------------------------------------------
/** Callback from player profile if login was successful.
*/
void UserScreen::loginSuccessful()
void BaseUserScreen::loginSuccessful()
{
m_options_widget->setActivated();
// Clean any error message still shown
@@ -369,7 +367,7 @@ void UserScreen::loginSuccessful()
/** Callback from player profile if login was unsuccessful.
* \param error_message Contains the error message.
*/
void UserScreen::loginError(const irr::core::stringw & error_message)
void BaseUserScreen::loginError(const irr::core::stringw & error_message)
{
sfx_manager->quickSound("anvil");
m_info_widget->setErrorColor();
@@ -378,7 +376,7 @@ void UserScreen::loginError(const irr::core::stringw & error_message)
} // loginError
// ----------------------------------------------------------------------------
void UserScreen::newUserAdded(const irr::core::stringw &local_name,
void BaseUserScreen::newUserAdded(const irr::core::stringw &local_name,
const irr::core::stringw &online_name)
{
PlayerProfile *player = PlayerManager::get()->getPlayer(local_name);
@@ -389,7 +387,7 @@ void UserScreen::newUserAdded(const irr::core::stringw &local_name,
// ----------------------------------------------------------------------------
/** Called when a player will be deleted.
*/
void UserScreen::deletePlayer()
void BaseUserScreen::deletePlayer()
{
PlayerProfile *player = getSelectedPlayer();
irr::core::stringw message =
@@ -398,23 +396,29 @@ void UserScreen::deletePlayer()
class ConfirmServer : public MessageDialog::IConfirmDialogListener
{
BaseUserScreen *m_parent_screen;
public:
virtual void onConfirm()
{
UserScreen::getInstance()->doDeletePlayer();
m_parent_screen->doDeletePlayer();
} // onConfirm
// ------------------------------------------------------------
ConfirmServer(BaseUserScreen *parent)
{
m_parent_screen = parent;
}
}; // ConfirmServer
new MessageDialog(message, MessageDialog::MESSAGE_DIALOG_CONFIRM,
new ConfirmServer(), true);
new ConfirmServer(this), true);
} // deletePlayer
// ----------------------------------------------------------------------------
/** Callback when the user confirms to delete a player. This function actually
* deletes the player, discards the dialog, and re-initialised the UserScreen
* deletes the player, discards the dialog, and re-initialised the BaseUserScreen
* to display only the available players.
*/
void UserScreen::doDeletePlayer()
void BaseUserScreen::doDeletePlayer()
{
PlayerProfile *player = getSelectedPlayer();
PlayerManager::get()->deletePlayer(player);
@@ -423,7 +427,7 @@ void UserScreen::doDeletePlayer()
} // doDeletePlayer
// ----------------------------------------------------------------------------
void UserScreen::unloaded()
void BaseUserScreen::unloaded()
{
} // unloaded
@@ -434,7 +438,7 @@ void UserScreen::unloaded()
* to open the next dialog, which is the one to create a new player (which
* is conventient on a first start).
*/
void UserScreen::onDialogClose()
void BaseUserScreen::onDialogClose()
{
// To allow players to exit the game without creating a player, we count
// how often this function was called. The first time is after the
@@ -455,5 +459,55 @@ void UserScreen::onDialogClose()
} // getNumPlayers == 0
} // onDialogClose
// -----------------------------------------------------------------------------
// ============================================================================
/** If there already is a player (i.e. default player is saved), no need to
* show this dialog, go directly to the main menu screen.
*/
void UserScreen::init()
{
PlayerProfile *player = PlayerManager::getCurrentPlayer();
if (player)
{
StateManager::get()->resetAndGoToScreen(MainMenuScreen::getInstance());
return;
}
BaseUserScreen::init();
} // init
// ============================================================================
/** In the tab version, make sure the right tab is selected.
*/
void TabbedUserScreen::init()
{
RibbonWidget* tab_bar = this->getWidget<RibbonWidget>("options_choice");
if (tab_bar != NULL) tab_bar->select("tab_players", PLAYER_ID_GAME_MASTER);
tab_bar->getRibbonChildren()[0].setTooltip( _("Graphics") );
tab_bar->getRibbonChildren()[1].setTooltip( _("Audio") );
tab_bar->getRibbonChildren()[2].setTooltip(_("User Interface"));
tab_bar->getRibbonChildren()[4].setTooltip( _("Controls") );
BaseUserScreen::init();
} // init
// ----------------------------------------------------------------------------
/** Switch to the correct tab.
*/
void TabbedUserScreen::eventCallback(GUIEngine::Widget* widget,
const std::string& name,
const int playerID)
{
if (name == "options_choice")
{
const std::string &selection =
((RibbonWidget*)widget)->getSelectionIDString(PLAYER_ID_GAME_MASTER);
Screen *s;
if (selection=="tab_audio" ) s = OptionsScreenAudio::getInstance();
else if (selection=="tab_video" ) s = OptionsScreenVideo::getInstance();
else if (selection=="tab_players" ) s = TabbedUserScreen::getInstance();
else if (selection=="tab_controls") s = OptionsScreenInput::getInstance();
else if (selection=="tab_ui" ) s = OptionsScreenUI::getInstance();
assert(s);
StateManager::get()->replaceTopMostScreen(s);
}
} // eventCallback

View File

@@ -36,20 +36,21 @@ class PlayerProfile;
/**
* \brief Audio options screen
* \ingroup states_screens
* \brief The user management screen. The screen cames in two variations:
* either as a stand-alone screen before the main menu (on first time STK
* is started, or it the user is not remembered), but also as tab in the
* options menu. To implement this, we use one common base class that
* implements nearly all functionality, and derive to classes - one for
* the stand alone version, one for the version with tabs.
* \ingroup states_screens.
*/
class UserScreen : public GUIEngine::Screen,
public GUIEngine::ScreenSingleton<UserScreen>
class BaseUserScreen : public GUIEngine::Screen
{
UserScreen();
protected:
BaseUserScreen(const std::string &name);
private:
/** True if this window is a popup window, which means it will not
* immediately go to the main menu if a current player is defined. */
bool m_is_popup_window;
/** Online check box. */
GUIEngine::CheckBoxWidget *m_online_cb;
@@ -79,13 +80,12 @@ private:
virtual void onUpdate(float dt) OVERRIDE;
public:
friend class GUIEngine::ScreenSingleton<UserScreen>;
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void loadedFromFile();
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void eventCallback(GUIEngine::Widget* widget, const std::string& name, const int playerID);
virtual void eventCallback(GUIEngine::Widget* widget,
const std::string& name, const int playerID);
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void init();
@@ -100,10 +100,34 @@ public:
void loginError(const irr::core::stringw &error_message);
void newUserAdded(const irr::core::stringw &local_name,
const irr::core::stringw &online_name);
// ------------------------------------------------------------------------
/** True if this window is a popup window (i.e. it should not exit even if
* the current player exists. */
void setIsPopup(bool popup) { m_is_popup_window = popup; }
}; // class UserScreen
}; // class BaseUserScreen
// ============================================================================
class UserScreen : public BaseUserScreen,
public GUIEngine::ScreenSingleton<UserScreen>
{
private:
UserScreen() : BaseUserScreen("user_screen.stkgui")
{};
public:
friend class GUIEngine::ScreenSingleton<UserScreen>;
virtual void init();
}; // class UserScreenTabed
// ============================================================================
class TabbedUserScreen : public BaseUserScreen,
public GUIEngine::ScreenSingleton<TabbedUserScreen>
{
private:
TabbedUserScreen() : BaseUserScreen("user_screen_tab.stkgui")
{}
public:
friend class GUIEngine::ScreenSingleton<TabbedUserScreen>;
virtual void init();
virtual void eventCallback(GUIEngine::Widget* widget,
const std::string& name, const int playerID);
}; // class TabbedUserScreen
#endif