diff --git a/src/states_screens/dialogs/network_user_dialog.cpp b/src/states_screens/dialogs/network_user_dialog.cpp index 35af4cb13..50f1439b0 100644 --- a/src/states_screens/dialogs/network_user_dialog.cpp +++ b/src/states_screens/dialogs/network_user_dialog.cpp @@ -43,9 +43,23 @@ void NetworkUserDialog::beforeAddingWidgets() assert(m_name_widget != NULL); m_name_widget->setText(m_name, false); + m_info_widget = getWidget("info"); + assert(m_info_widget != NULL); + if (m_online_id != 0) + { + updatePlayerRanking(m_name, m_online_id, m_info_widget, + m_fetched_ranking); + } + else + { + m_info_widget->setVisible(false); + } + m_friend_widget = getWidget("friend"); assert(m_friend_widget != NULL); - m_friend_widget->setVisible(m_online_id != 0); + m_friend_widget->setVisible(m_online_id != 0 && + PlayerManager::getCurrentOnlineState() == PlayerProfile::OS_SIGNED_IN + && m_online_id != PlayerManager::getCurrentPlayer()->getOnlineId()); // Hide friend request button if already friend Online::OnlineProfile* opp = @@ -66,7 +80,8 @@ void NetworkUserDialog::beforeAddingWidgets() //I18N: In the network user dialog m_kick_widget->setText(_("Kick")); - m_kick_widget->setVisible(STKHost::get()->isAuthorisedToControl()); + m_kick_widget->setVisible(STKHost::get()->isAuthorisedToControl() + && m_host_id != STKHost::get()->getMyHostId()); m_cancel_widget = getWidget("cancel"); assert(m_cancel_widget != NULL); @@ -79,9 +94,29 @@ void NetworkUserDialog::beforeAddingWidgets() getWidget("accept")->setVisible(false); getWidget("remove")->setVisible(false); getWidget("enter")->setVisible(false); - getWidget("info")->setVisible(false); } // beforeAddingWidgets +// ----------------------------------------------------------------------------- +void NetworkUserDialog::onUpdate(float dt) +{ + if (*m_fetched_ranking == false) + { + // I18N: In the network player dialog, showing when waiting for + // the result of the ranking info of a player + core::stringw fetching = + StringUtils::loadingDots(_("Fetching ranking info for %s.", + m_name)); + m_info_widget->setText(fetching, false); + } + + // It's unsafe to delete from inside the event handler so we do it here + if (m_self_destroy) + { + ModalDialog::dismiss(); + return; + } +} // onUpdate + // ----------------------------------------------------------------------------- GUIEngine::EventPropagation NetworkUserDialog::processEvent(const std::string& source) diff --git a/src/states_screens/dialogs/network_user_dialog.hpp b/src/states_screens/dialogs/network_user_dialog.hpp index 2b1ee1345..7131ae5b6 100644 --- a/src/states_screens/dialogs/network_user_dialog.hpp +++ b/src/states_screens/dialogs/network_user_dialog.hpp @@ -20,9 +20,11 @@ #define HEADER_NETWORK_USER_DIALOG_HPP #include "guiengine/modaldialog.hpp" +#include "states_screens/dialogs/ranking_callback.hpp" #include "utils/types.hpp" #include +#include namespace GUIEngine { @@ -35,7 +37,8 @@ namespace GUIEngine * \brief Dialog that handle user in network lobby * \ingroup states_screens */ -class NetworkUserDialog : public GUIEngine::ModalDialog +class NetworkUserDialog : public GUIEngine::ModalDialog, + public RankingCallback { private: const uint32_t m_host_id; @@ -46,21 +49,26 @@ private: bool m_self_destroy; - GUIEngine::RibbonWidget * m_options_widget; + std::shared_ptr m_fetched_ranking; - GUIEngine::LabelWidget * m_name_widget; + GUIEngine::RibbonWidget* m_options_widget; - GUIEngine::IconButtonWidget * m_friend_widget; + GUIEngine::LabelWidget* m_name_widget; - GUIEngine::IconButtonWidget * m_kick_widget; + GUIEngine::LabelWidget* m_info_widget; - GUIEngine::IconButtonWidget * m_cancel_widget; + GUIEngine::IconButtonWidget* m_friend_widget; + + GUIEngine::IconButtonWidget* m_kick_widget; + + GUIEngine::IconButtonWidget* m_cancel_widget; public: NetworkUserDialog(uint32_t host_id, uint32_t online_id, const core::stringw& name) : ModalDialog(0.8f,0.8f), m_host_id(host_id), m_online_id(online_id), - m_name(name), m_self_destroy(false) + m_name(name), m_self_destroy(false), + m_fetched_ranking(std::make_shared(false)) { loadFromFile("online/user_info_dialog.stkgui"); } @@ -75,15 +83,8 @@ public: // ------------------------------------------------------------------------ virtual bool onEscapePressed(); // ------------------------------------------------------------------------ - virtual void onUpdate(float dt) - { - // It's unsafe to delete from inside the event handler so we do it here - if (m_self_destroy) - { - ModalDialog::dismiss(); - return; - } - } + virtual void onUpdate(float dt); + }; #endif diff --git a/src/states_screens/dialogs/player_rankings_dialog.cpp b/src/states_screens/dialogs/player_rankings_dialog.cpp index 31df6e258..6ecd49270 100644 --- a/src/states_screens/dialogs/player_rankings_dialog.cpp +++ b/src/states_screens/dialogs/player_rankings_dialog.cpp @@ -42,16 +42,17 @@ std::vector > PlayerRankingsDialog::PlayerRankingsDialog(uint32_t online_id, const core::stringw& name) : ModalDialog(0.8f,0.9f), m_online_id(online_id), - m_name(name), m_self_destroy(false) + m_name(name), m_self_destroy(false), + m_fetched_ranking(std::make_shared(false)) { loadFromFile("online/player_rankings_dialog.stkgui"); m_top_ten = getWidget("top-ten"); assert(m_top_ten != NULL); if (m_rankings.empty()) - updateTopTen(); + updateTopTenList(); else - addTopTen(); + fillTopTenList(); } // PlayerRankingsDialog // ----------------------------------------------------------------------------- @@ -67,66 +68,18 @@ void PlayerRankingsDialog::beforeAddingWidgets() m_ranking_info = getWidget("cur-rank"); assert(m_ranking_info != NULL); - core::stringw fetching = _("Fetching ranking info for %s.", m_name); - m_ranking_info->setText(fetching, false); - updatePlayerRanking(); - + updatePlayerRanking(m_name, m_online_id, m_ranking_info, + m_fetched_ranking); } // beforeAddingWidgets -// ----------------------------------------------------------------------------- -void PlayerRankingsDialog::updatePlayerRanking() -{ - class UpdatePlayerRankingRequest : public XMLRequest - { - // ------------------------------------------------------------------------ - /** Callback for the request to send a friend invitation. Shows a - * confirmation message and takes care of updating all the cached - * information. - */ - virtual void callback() - { - PlayerRankingsDialog* prd = dynamic_cast - (getCurrent()); - if (prd == NULL) - return; - core::stringw result = _("%s has no ranking yet.", prd->m_name); - if (isSuccess()) - { - int rank = -1; - float score = 0.0; - getXMLData()->get("rank", &rank); - getXMLData()->get("scores", &score); - if (rank > 0) - { - result = _("%s has a rank of %d with score %d.", - prd->m_name, rank, (int)score); - } - } - prd->m_ranking_info->setText(result, false); - - } // callback - public: - UpdatePlayerRankingRequest() : XMLRequest(true) {} - }; // UpdatePlayerRankingRequest - - // ------------------------------------------------------------------------ - - UpdatePlayerRankingRequest* request = new UpdatePlayerRankingRequest(); - PlayerManager::setUserDetails(request, "get-ranking"); - request->addParameter("id", m_online_id); - request->queue(); - -} // updatePlayerRanking - // ---------------------------------------------------------------------------- -void PlayerRankingsDialog::updateTopTen() +void PlayerRankingsDialog::updateTopTenList() { - // ---------------------------------------------------------------- + // ------------------------------------------------------------------------ class UpdateTopTenRequest : public XMLRequest { - /** Callback for the request to accept a friend invitation. Shows a - * confirmation message and takes care of updating all the cached - * information. + /** Callback for the request to update top 10 players and update the + * list. */ virtual void callback() { @@ -148,7 +101,7 @@ void PlayerRankingsDialog::updateTopTen() players->getNode(i)->get("scores", &score); prd->m_rankings.emplace_back(rank, user, score); } - prd->addTopTen(); + prd->fillTopTenList(); } } // callback public: @@ -160,10 +113,10 @@ void PlayerRankingsDialog::updateTopTen() PlayerManager::setUserDetails(request, "top-players"); request->addParameter("ntop", 10); request->queue(); -} // updateTopTen +} // updateTopTenList // ----------------------------------------------------------------------------- -void PlayerRankingsDialog::addTopTen() +void PlayerRankingsDialog::fillTopTenList() { m_top_ten->clear(); for (auto& r : m_rankings) @@ -177,7 +130,28 @@ void PlayerRankingsDialog::addTopTen() StringUtils::toWString(std::get<2>(r)), -1, 1, true)); m_top_ten->addItem("rank", row); } -} // addTopTen +} // fillTopTenList + +// ----------------------------------------------------------------------------- +void PlayerRankingsDialog::onUpdate(float dt) +{ + if (*m_fetched_ranking == false) + { + // I18N: In the network player dialog, showing when waiting for + // the result of the ranking info of a player + core::stringw fetching = + StringUtils::loadingDots(_("Fetching ranking info for %s.", + m_name)); + m_ranking_info->setText(fetching, false); + } + + // It's unsafe to delete from inside the event handler so we do it here + if (m_self_destroy) + { + ModalDialog::dismiss(); + return; + } +} // onUpdate // ----------------------------------------------------------------------------- GUIEngine::EventPropagation @@ -201,8 +175,10 @@ GUIEngine::EventPropagation return GUIEngine::EVENT_BLOCK; timer = StkTime::getRealTime(); - updatePlayerRanking(); - updateTopTen(); + *m_fetched_ranking = false; + updatePlayerRanking(m_name, m_online_id, m_ranking_info, + m_fetched_ranking); + updateTopTenList(); return GUIEngine::EVENT_BLOCK; } } diff --git a/src/states_screens/dialogs/player_rankings_dialog.hpp b/src/states_screens/dialogs/player_rankings_dialog.hpp index a1d65152e..119d273c4 100644 --- a/src/states_screens/dialogs/player_rankings_dialog.hpp +++ b/src/states_screens/dialogs/player_rankings_dialog.hpp @@ -20,9 +20,11 @@ #define HEADER_PLAYER_RANKINGS_DIALOG_HPP #include "guiengine/modaldialog.hpp" +#include "states_screens/dialogs/ranking_callback.hpp" #include "utils/types.hpp" #include +#include #include #include @@ -38,7 +40,8 @@ namespace GUIEngine * \brief Dialog that handle user in network lobby * \ingroup states_screens */ -class PlayerRankingsDialog : public GUIEngine::ModalDialog +class PlayerRankingsDialog : public GUIEngine::ModalDialog, + public RankingCallback { private: const uint32_t m_online_id; @@ -47,6 +50,8 @@ private: bool m_self_destroy; + std::shared_ptr m_fetched_ranking; + GUIEngine::RibbonWidget* m_options_widget; GUIEngine::LabelWidget* m_ranking_info; @@ -61,11 +66,9 @@ private: /*scores*/float> > m_rankings; // ------------------------------------------------------------------------ - void updatePlayerRanking(); + void updateTopTenList(); // ------------------------------------------------------------------------ - void updateTopTen(); - // ------------------------------------------------------------------------ - void addTopTen(); + void fillTopTenList(); public: PlayerRankingsDialog(uint32_t online_id, const core::stringw& name); @@ -84,15 +87,7 @@ public: return false; } // ------------------------------------------------------------------------ - virtual void onUpdate(float dt) - { - // It's unsafe to delete from inside the event handler so we do it here - if (m_self_destroy) - { - ModalDialog::dismiss(); - return; - } - } + virtual void onUpdate(float dt); }; #endif diff --git a/src/states_screens/dialogs/ranking_callback.hpp b/src/states_screens/dialogs/ranking_callback.hpp new file mode 100644 index 000000000..b6c5e8d24 --- /dev/null +++ b/src/states_screens/dialogs/ranking_callback.hpp @@ -0,0 +1,97 @@ +// SuperTuxKart - a fun racing game with go-kart +// Copyright (C) 2018 SuperTuxKart-Team +// +// 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_RANKING_CALLBACK_HPP +#define HEADER_RANKING_CALLBACK_HPP + +#include "config/player_manager.hpp" +#include "guiengine/widgets/label_widget.hpp" +#include "online/xml_request.hpp" + +#include + +class RankingCallback +{ +protected: + // ------------------------------------------------------------------------ + void updatePlayerRanking(const core::stringw& name, uint32_t online_id, + GUIEngine::LabelWidget* info, + std::shared_ptr done) + { + // -------------------------------------------------------------------- + class UpdatePlayerRankingRequest : public Online::XMLRequest + { + private: + std::weak_ptr m_done; + + core::stringw m_name; + + GUIEngine::LabelWidget* m_info; + // ---------------------------------------------------------------- + /** Callback for the request to update rank of a player. Shows his + * rank and score. + */ + virtual void callback() + { + auto done = m_done.lock(); + // Dialog deleted + if (!done) + return; + // I18N: In the network player dialog, indiciating a network + // player has no ranking + core::stringw result = _("%s has no ranking yet.", m_name); + if (isSuccess()) + { + int rank = -1; + float score = 0.0; + getXMLData()->get("rank", &rank); + getXMLData()->get("scores", &score); + if (rank > 0) + { + // I18N: In the network player dialog show rank and + // score of a player + result = _("%s has a rank of %d with score %d.", + m_name, rank, (int)score); + } + } + *done = true; + m_info->setText(result, false); + + } // callback + public: + UpdatePlayerRankingRequest(const core::stringw& name, + uint32_t online_id, + GUIEngine::LabelWidget* info, + std::shared_ptr done) + : XMLRequest(true) + { + m_name = name; + m_info = info; + m_done = done; + } + }; // UpdatePlayerRankingRequest + + // -------------------------------------------------------------------- + UpdatePlayerRankingRequest* request = + new UpdatePlayerRankingRequest(name, online_id, info, done); + PlayerManager::setUserDetails(request, "get-ranking"); + request->addParameter("id", online_id); + request->queue(); + } +}; +#endif diff --git a/src/states_screens/networking_lobby.cpp b/src/states_screens/networking_lobby.cpp index dee5b91ef..bd2b89b55 100644 --- a/src/states_screens/networking_lobby.cpp +++ b/src/states_screens/networking_lobby.cpp @@ -302,8 +302,7 @@ void NetworkingLobby::eventCallback(Widget* widget, const std::string& name, { auto host_online_ids = StringUtils::splitToUInt (m_player_list->getSelectionInternalName(), '_'); - if (host_online_ids.size() != 2 || - STKHost::get()->getMyHostId() == host_online_ids[0]) + if (host_online_ids.size() != 2) { return; }