Lots of changes. When you click a user name now (in friends-list or search result), you get a pop-up, where you can click to join and watch the profile.

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/uni@13490 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
unitraxx 2013-08-17 00:11:03 +00:00
parent 8e530bd505
commit 0f0caf5f35
15 changed files with 357 additions and 73 deletions

View File

@ -0,0 +1,33 @@
<stkgui>
<div x="2%" y="5%" width="96%" height="85%" layout="vertical-row" >
<header id="title" width="96%" height="fit" text_align="center" word_wrap="true"
I18N="In the server info dialog' dialog" text="Server Info"/>
<spacer height="20" width="50">
<div width="80%" align="center" layout="vertical-row" height="fit" >
<div width="100%" height="fit" layout="horizontal-row" >
<label proportion="1" text_align="left" I18N="In the server info dialog" text="Name"/>
<label id="name" proportion="2" text_align="left" text=""/>
</div>
</div>
<spacer height="20" width="50">
<label id="info" proportion="1" width="90%" align="center" text_align="center" word_wrap="true" text=""/>
<spacer height="20" width="50">
<buttonbar id="options" width="90%" height="20%" align="center">
<icon-button id="enter" width="64" height="64" icon="gui/green_check.png"
I18N="Login dialog" text="Enter" label_location="bottom"/>
<icon-button id="cancel" width="64" height="64" icon="gui/main_quit.png"
I18N="Login dialog" text="Cancel" label_location="bottom"/>
</buttonbar>
</div>
</stkgui>

View File

@ -217,6 +217,7 @@ src/states_screens/dialogs/select_challenge.cpp
src/states_screens/dialogs/server_info_dialog.cpp
src/states_screens/dialogs/track_info_dialog.cpp
src/states_screens/dialogs/tutorial_message_dialog.cpp
src/states_screens/dialogs/user_info_dialog.cpp
src/states_screens/dialogs/vote_dialog.cpp
src/states_screens/feature_unlocked.cpp
src/states_screens/grand_prix_lose.cpp
@ -518,6 +519,7 @@ src/states_screens/dialogs/select_challenge.hpp
src/states_screens/dialogs/server_info_dialog.hpp
src/states_screens/dialogs/track_info_dialog.hpp
src/states_screens/dialogs/tutorial_message_dialog.hpp
src/states_screens/dialogs/user_info_dialog.hpp
src/states_screens/dialogs/vote_dialog.hpp
src/states_screens/feature_unlocked.hpp
src/states_screens/grand_prix_lose.hpp

View File

@ -36,15 +36,14 @@ namespace Online{
// ============================================================================
Profile::Profile(User * user)
Profile::Profile( const uint32_t & userid,
const irr::core::stringw & username)
{
setState (S_READY);
m_is_current_user = false;
m_cache_bit = false;
m_id = user->getUserID();
m_username = user->getUserName();
m_cache_bit = true;
m_id = userid;
m_is_current_user = (m_id == CurrentUser::get()->getUserID());
m_username = username;
m_has_fetched_friends = false;
}
@ -63,14 +62,18 @@ namespace Online{
void Profile::friendsListCallback(const XMLNode * input)
{
const XMLNode * friends_xml = input->getNode("friends");
m_friends.clearAndDeleteAll();
uint32_t friendid(0);
irr::core::stringw username("");
m_friends.clear();
uint32_t friend_id(0);
irr::core::stringw friend_username("");
for (unsigned int i = 0; i < friends_xml->getNumNodes(); i++)
{
friends_xml->getNode(i)->get("friend_id", &friendid);
friends_xml->getNode(i)->get("friend_name", &username);
m_friends.push_back(new User(username, friendid));
friends_xml->getNode(i)->get("friend_id", &friend_id);
friends_xml->getNode(i)->get("friend_name", &friend_username);
ProfileManager::get()->addToCache(
new Profile(friend_id, friend_username)
);
m_friends.push_back(friend_id);
}
m_has_fetched_friends = true;
Profile::setState (Profile::S_READY);
@ -100,7 +103,7 @@ namespace Online{
// ============================================================================
const PtrVector<Online::User> & Profile::getFriends()
const std::vector<uint32_t> & Profile::getFriends()
{
assert (m_has_fetched_friends && getState() == S_READY);
return m_friends;

View File

@ -47,6 +47,8 @@ namespace Online{
public:
FriendsListRequest() : XMLRequest(0, true) {}
};
typedef std::vector<uint32_t> IDList;
private:
enum State
@ -61,7 +63,7 @@ namespace Online{
irr::core::stringw m_username;
bool m_has_fetched_friends;
PtrVector<Online::User> m_friends;
std::vector<uint32_t> m_friends;
bool m_cache_bit;
@ -72,18 +74,22 @@ namespace Online{
void friendsListCallback(const XMLNode * input);
public:
Profile(User * user);
void fetchFriends();
const PtrVector<Online::User> & getFriends();
Profile( const uint32_t & userid,
const irr::core::stringw & username);
void fetchFriends();
const std::vector<uint32_t> & getFriends();
bool isFetching() { return getState() == S_FETCHING; }
bool isReady() { return getState() == S_READY; }
bool isFetching() const { return getState() == S_FETCHING; }
bool isReady() const { return getState() == S_READY; }
void setCacheBit() { m_cache_bit = true; }
void unsetCacheBit() { m_cache_bit = false; }
bool getCacheBit() { return m_cache_bit; }
uint32_t getID() { return m_id; }
irr::core::stringw getUsername() { return m_username; }
bool isCurrentUser() const { return m_is_current_user; }
void setCacheBit() { m_cache_bit = true; }
void unsetCacheBit() { m_cache_bit = false; }
bool getCacheBit() const { return m_cache_bit; }
uint32_t getID() const { return m_id; }
irr::core::stringw getUserName() const { return m_username; }
}; // class CurrentUser

View File

@ -53,11 +53,11 @@ namespace Online{
// ============================================================================
void ProfileManager::iterateCache()
void ProfileManager::iterateCache(Profile * profile)
{
if(m_profiles_cache.size() == m_max_cache_size)
{
m_currently_visiting->setCacheBit();
profile->setCacheBit();
ProfilesMap::iterator iter;
for (iter = m_profiles_cache.begin(); iter != m_profiles_cache.end(); ++iter)
{
@ -69,14 +69,14 @@ namespace Online{
{
iter->second->unsetCacheBit();
}
m_currently_visiting->setCacheBit();
profile->setCacheBit();
}
}
// ============================================================================
void ProfileManager::addToCache(Profile * profile)
void ProfileManager::directToCache(Profile * profile)
{
assert(profile != NULL);
if(m_profiles_cache.size() == m_max_cache_size)
@ -98,34 +98,49 @@ namespace Online{
}
// ============================================================================
void ProfileManager::setVisiting(User * user)
void ProfileManager::addToCache(Profile * profile)
{
assert(user != NULL);
if( m_profiles_cache.find(user->getUserID()) == m_profiles_cache.end())
if(cacheHit(profile->getID()))
{
//cache miss
m_currently_visiting = new Profile(user);
addToCache(m_currently_visiting);
//FIXME should do updating of values
delete profile;
}
else
{
//cache hit
m_currently_visiting = m_profiles_cache[user->getUserID()];
directToCache(profile);
}
iterateCache();
}
bool ProfileManager::cacheHit(const uint32_t id)
{
if (m_profiles_cache.find(id) != m_profiles_cache.end())
{
iterateCache(m_profiles_cache[id]);
return true;
}
return false;
}
// ============================================================================
void ProfileManager::setVisiting(const uint32_t id)
{
if(cacheHit(id))
{
m_currently_visiting = m_profiles_cache[id];
}
else
m_currently_visiting = NULL;
}
// ============================================================================
Profile * ProfileManager::getProfileByID(uint32_t id)
Profile * ProfileManager::getProfileByID(const uint32_t id)
{
if( m_profiles_cache.find(id) == m_profiles_cache.end())
{
Log::info("getProfileByID","here");
return NULL;
}
return m_profiles_cache[id];
if(cacheHit(id))
return m_profiles_cache[id];
return NULL;
}

View File

@ -52,19 +52,21 @@ namespace Online{
ProfilesMap m_profiles_cache;
Profile * m_currently_visiting;
static const unsigned int m_max_cache_size = 5;
static const unsigned int m_max_cache_size = 20;
void iterateCache();
void addToCache(Profile * profile);
void iterateCache(Profile * profile);
void directToCache(Profile * profile);
public:
/**Singleton */
static ProfileManager * get();
static void deallocate();
void setVisiting(Online::User * user);
void addToCache(Profile * profile);
void setVisiting(const uint32_t id);
bool cacheHit(const uint32_t id);
Profile * getVisitingProfile() {return m_currently_visiting;}
Profile * getProfileByID(uint32_t id);
Profile * getProfileByID(const uint32_t id);
}; // class CurrentUser

View File

@ -0,0 +1,133 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 Glenn De Jonghe
//
// 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/user_info_dialog.hpp"
#include <IGUIEnvironment.h>
#include "audio/sfx_manager.hpp"
#include "config/player.hpp"
#include "guiengine/engine.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/online_profile_overview.hpp"
#include "utils/translation.hpp"
#include "utils/string_utils.hpp"
#include "network/protocol_manager.hpp"
#include "network/protocols/connect_to_server.hpp"
#include "online/messages.hpp"
#include "states_screens/dialogs/registration_dialog.hpp"
#include "states_screens/networking_lobby.hpp"
using namespace GUIEngine;
using namespace irr;
using namespace irr::gui;
using namespace Online;
// -----------------------------------------------------------------------------
UserInfoDialog::UserInfoDialog(uint32_t visiting_id)
: ModalDialog(0.8f,0.8f), m_visiting_id(visiting_id)
{
m_self_destroy = false;
m_enter_profile = false;
loadFromFile("online/user_info_dialog.stkgui");
m_profile = ProfileManager::get()->getProfileByID(visiting_id);
m_name_widget = getWidget<LabelWidget>("name");
assert(m_name_widget != NULL);
//const Server * server = ProfileManager::get()->getServerByID(m_visiting_id);
m_name_widget->setText(m_profile->getUserName(),false);
m_info_widget = getWidget<LabelWidget>("info");
assert(m_info_widget != NULL);
m_options_widget = getWidget<RibbonWidget>("options");
assert(m_options_widget != NULL);
m_enter_widget = getWidget<IconButtonWidget>("enter");
assert(m_enter_widget != NULL);
m_cancel_widget = getWidget<IconButtonWidget>("cancel");
assert(m_cancel_widget != NULL);
m_options_widget->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
}
// -----------------------------------------------------------------------------
UserInfoDialog::~UserInfoDialog()
{
}
// -----------------------------------------------------------------------------
GUIEngine::EventPropagation UserInfoDialog::processEvent(const std::string& eventSource)
{
if (eventSource == m_options_widget->m_properties[PROP_ID])
{
const std::string& selection = m_options_widget->getSelectionIDString(PLAYER_ID_GAME_MASTER);
if (selection == m_cancel_widget->m_properties[PROP_ID])
{
m_self_destroy = true;
return GUIEngine::EVENT_BLOCK;
}
else if(selection == m_enter_widget->m_properties[PROP_ID])
{
ProfileManager::get()->setVisiting(m_profile->getID());
m_enter_profile = true;
return GUIEngine::EVENT_BLOCK;
}
}
return GUIEngine::EVENT_LET;
}
// -----------------------------------------------------------------------------
void UserInfoDialog::onEnterPressedInternal()
{
//If enter was pressed while none of the buttons was focused interpret as join event
const int playerID = PLAYER_ID_GAME_MASTER;
if (GUIEngine::isFocusedForPlayer(m_options_widget, playerID))
return;
m_self_destroy = true;
}
// -----------------------------------------------------------------------------
bool UserInfoDialog::onEscapePressed()
{
if (m_cancel_widget->isActivated())
m_self_destroy = true;
return false;
}
// -----------------------------------------------------------------------------
void UserInfoDialog::onUpdate(float dt)
{
//If we want to open the registration dialog, we need to close this one first
m_enter_profile && (m_self_destroy = true);
// It's unsafe to delete from inside the event handler so we do it here
if (m_self_destroy)
{
ModalDialog::dismiss();
if (m_enter_profile)
StateManager::get()->replaceTopMostScreen(OnlineProfileOverview::getInstance());
return;
}
}

View File

@ -0,0 +1,67 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013 Glenn De Jonghe
//
// 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_USER_INFO_DIALOG_HPP
#define HEADER_USER_INFO_DIALOG_HPP
#include <irrString.h>
#include "guiengine/modaldialog.hpp"
#include "guiengine/widgets.hpp"
#include "online/profile_manager.hpp"
#include "online/current_user.hpp"
#include "utils/types.hpp"
/**
* \brief Dialog that allows a user to sign in
* \ingroup states_screens
*/
class UserInfoDialog : public GUIEngine::ModalDialog
{
private:
bool m_self_destroy;
bool m_enter_profile;
const uint32_t m_visiting_id;
Online::Profile * m_profile;
GUIEngine::LabelWidget * m_name_widget;
GUIEngine::LabelWidget * m_info_widget;
GUIEngine::RibbonWidget * m_options_widget;
GUIEngine::IconButtonWidget * m_add_widget;
GUIEngine::IconButtonWidget * m_enter_widget;
GUIEngine::IconButtonWidget * m_cancel_widget;
void requestJoin();
public:
UserInfoDialog(uint32_t visiting_id);
~UserInfoDialog();
void onEnterPressedInternal();
GUIEngine::EventPropagation processEvent(const std::string& eventSource);
virtual bool onEscapePressed();
virtual void onUpdate(float dt);
};
#endif

View File

@ -45,9 +45,8 @@ void OnlineProfileBase::loadedFromFile()
{
m_profile_tabs = this->getWidget<RibbonWidget>("profile_tabs");
assert(m_profile_tabs != NULL);
LabelWidget * header = this->getWidget<LabelWidget>("title");
assert(header != NULL);
header->setText(_("Your profile"), false);
m_header = this->getWidget<LabelWidget>("title");
assert(m_header != NULL);
m_overview_tab = (IconButtonWidget *) m_profile_tabs->findWidgetNamed("tab_overview");
assert(m_overview_tab != NULL);
@ -65,6 +64,12 @@ void OnlineProfileBase::init()
m_overview_tab->setTooltip( _("Overview") );
m_friends_tab->setTooltip( _("Friends") );
m_visiting_profile = ProfileManager::get()->getVisitingProfile();
if (m_visiting_profile->isCurrentUser())
m_header->setText(_("Your profile"), false);
else
m_header->setText( m_visiting_profile->getUserName() + _("'s profile"), false);
} // init
// -----------------------------------------------------------------------------

View File

@ -24,6 +24,7 @@
#include "guiengine/screen.hpp"
#include "guiengine/widgets.hpp"
#include "online/profile.hpp"
namespace GUIEngine { class Widget; }
@ -36,10 +37,13 @@ class OnlineProfileBase : public GUIEngine::Screen
{
protected:
OnlineProfileBase(const char* filename);
GUIEngine::LabelWidget * m_header;
GUIEngine::RibbonWidget* m_profile_tabs;
GUIEngine::IconButtonWidget * m_overview_tab;
GUIEngine::IconButtonWidget * m_friends_tab;
Online::Profile * m_visiting_profile;
public:
/** \brief implement callback from parent class GUIEngine::Screen */

View File

@ -23,6 +23,7 @@
#include "guiengine/widget.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/online_user_search.hpp"
#include "states_screens/dialogs/user_info_dialog.hpp"
#include "utils/translation.hpp"
#include "online/messages.hpp"
@ -42,6 +43,7 @@ DEFINE_SCREEN_SINGLETON( OnlineProfileFriends );
OnlineProfileFriends::OnlineProfileFriends() : OnlineProfileBase("online/profile_friends.stkgui")
{
m_selected_friend_index = -1;
} // OnlineProfileFriends
// -----------------------------------------------------------------------------
@ -72,7 +74,6 @@ void OnlineProfileFriends::init()
{
OnlineProfileBase::init();
m_profile_tabs->select( m_friends_tab->m_properties[PROP_ID], PLAYER_ID_GAME_MASTER );
m_visiting_profile = ProfileManager::get()->getVisitingProfile();
assert(m_visiting_profile != NULL);
m_visiting_profile->fetchFriends();
m_waiting_for_friends = true;
@ -91,6 +92,11 @@ void OnlineProfileFriends::eventCallback(Widget* widget, const std::string& name
instance->setSearchString(m_search_box_widget->getText().trim());
StateManager::get()->pushScreen(instance);
}
else if (name == m_friends_list_widget->m_properties[GUIEngine::PROP_ID])
{
m_selected_friend_index = m_friends_list_widget->getSelectionID();
new UserInfoDialog(m_visiting_profile->getFriends()[m_selected_friend_index]);
}
} // eventCallback
// ----------------------------------------------------------------------------
@ -101,17 +107,18 @@ void OnlineProfileFriends::onUpdate(float delta, irr::video::IVideoDriver* driv
if(m_visiting_profile->isReady())
{
m_friends_list_widget->clear();
for(int i = 0; i < m_visiting_profile->getFriends().size(); i++)
for(unsigned int i = 0; i < m_visiting_profile->getFriends().size(); i++)
{
PtrVector<GUIEngine::ListWidget::ListCell> * row = new PtrVector<GUIEngine::ListWidget::ListCell>;
row->push_back(new GUIEngine::ListWidget::ListCell(m_visiting_profile->getFriends()[i].getUserName(),-1,3));
m_friends_list_widget->addItem("server", row);
Profile * friend_profile = ProfileManager::get()->getProfileByID(m_visiting_profile->getFriends()[i]);
row->push_back(new GUIEngine::ListWidget::ListCell(friend_profile->getUserName(),-1,3));
m_friends_list_widget->addItem("friend", row);
}
m_waiting_for_friends = false;
}
else
{
m_friends_list_widget->renameItem("loading", Messages::fetchingFriends());
m_friends_list_widget->renameItem("loading", Messages::fetchingFriends());
}
}
}

View File

@ -44,7 +44,7 @@ private:
GUIEngine::ButtonWidget * m_search_button_widget;
GUIEngine::TextBoxWidget * m_search_box_widget;
Online::Profile * m_visiting_profile;
int m_selected_friend_index;
bool m_waiting_for_friends;
public:

View File

@ -217,7 +217,8 @@ void OnlineScreen::eventCallback(Widget* widget, const std::string& name, const
}
else if (selection == m_profile_widget->m_properties[PROP_ID])
{
ProfileManager::get()->setVisiting(CurrentUser::get());
ProfileManager::get()->addToCache(new Profile(CurrentUser::get()->getUserID(), CurrentUser::get()->getUserName()));
ProfileManager::get()->setVisiting(CurrentUser::get()->getUserID());
StateManager::get()->pushScreen(OnlineProfileOverview::getInstance());
}
else if (selection == "register")

View File

@ -21,7 +21,7 @@
#include <assert.h>
#include "guiengine/modaldialog.hpp"
//#include "states_screens/dialogs/user_info_dialog.hpp"
#include "states_screens/dialogs/user_info_dialog.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/dialogs/message_dialog.hpp"
#include "utils/translation.hpp"
@ -48,8 +48,6 @@ OnlineUserSearch::OnlineUserSearch() : Screen("online/user_search.stkgui")
OnlineUserSearch::~OnlineUserSearch()
{
delete m_search_request;
m_users.clearAndDeleteAll();
} // OnlineUserSearch
// ----------------------------------------------------------------------------
@ -65,21 +63,29 @@ void OnlineUserSearch::tearDown()
void OnlineUserSearch::parseResult(const XMLNode * input)
{
m_users.clearAndDeleteAll();
m_users.clear();
const XMLNode * users_xml = input->getNode("users");
uint32_t id(0);
irr::core::stringw username("");
for (unsigned int i = 0; i < users_xml->getNumNodes(); i++)
{
m_users.push_back(new User(users_xml->getNode(i)));
users_xml->getNode(i)->get("id", &id);
users_xml->getNode(i)->get("user_name", &username);
ProfileManager::get()->addToCache(
new Profile(id, username)
);
m_users.push_back(id);
}
}
void OnlineUserSearch::showList()
{
m_user_list_widget->clear();
for(int i=0; i < m_users.size(); i++)
for(unsigned int i=0; i < m_users.size(); i++)
{
PtrVector<GUIEngine::ListWidget::ListCell> * row = new PtrVector<GUIEngine::ListWidget::ListCell>;
row->push_back(new GUIEngine::ListWidget::ListCell(m_users[i].getUserName(),-1,3));
Profile * profile = ProfileManager::get()->getProfileByID(m_users[i]);
row->push_back(new GUIEngine::ListWidget::ListCell(profile->getUserName(),-1,3));
m_user_list_widget->addItem("user", row);
}
}
@ -92,6 +98,8 @@ void OnlineUserSearch::search()
m_search_request = CurrentUser::get()->requestUserSearch(m_search_string);
else
m_fake_refresh = true;
m_user_list_widget->clear();
m_user_list_widget->addItem("spacer", L"");
m_user_list_widget->addItem("loading", Messages::searching());
m_back_widget->setDeactivated();
m_search_box_widget->setDeactivated();
@ -132,9 +140,7 @@ void OnlineUserSearch::init()
} // init
// ----------------------------------------------------------------------------
void OnlineUserSearch::eventCallback( GUIEngine::Widget* widget,
const std::string& name,
const int playerID)
void OnlineUserSearch::eventCallback( GUIEngine::Widget* widget, const std::string& name, const int playerID)
{
if (name == m_back_widget->m_properties[GUIEngine::PROP_ID])
{
@ -143,7 +149,7 @@ void OnlineUserSearch::eventCallback( GUIEngine::Widget* widget,
else if (name == m_user_list_widget->m_properties[GUIEngine::PROP_ID])
{
m_selected_index = m_user_list_widget->getSelectionID();
//new UserInfoDialog(m_users[m_selected_index]); FIXME
new UserInfoDialog(m_users[m_selected_index]);
}
else if (name == m_search_button_widget->m_properties[GUIEngine::PROP_ID])
{

View File

@ -20,7 +20,7 @@
#include "guiengine/screen.hpp"
#include "guiengine/widgets.hpp"
#include "online/user.hpp"
#include "online/profile.hpp"
#include "online/request.hpp"
#include "utils/ptr_vector.hpp"
@ -49,7 +49,7 @@ private:
int m_selected_index;
irr::core::stringw m_search_string;
irr::core::stringw m_last_search_string;
PtrVector<Online::User> m_users;
Online::Profile::IDList m_users;
const Online::XMLRequest * m_search_request;
bool m_fake_refresh;