From a85511cd7d783ab9fcf85ee6040f6c006cad0351 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Tue, 17 Apr 2018 12:01:14 -0600 Subject: [PATCH] Fix multiplayer dropdowns and proxy model * Filters in the lobby properly remove rooms * Multiplayer menu items for Show Room and Leave Room work as intended --- src/citra_qt/main.cpp | 19 +-- src/citra_qt/main.h | 2 - src/citra_qt/main.ui | 12 +- src/citra_qt/multiplayer/direct_connect.ui | 24 +--- src/citra_qt/multiplayer/lobby.cpp | 36 +---- src/citra_qt/multiplayer/lobby.h | 2 - src/citra_qt/multiplayer/lobby.ui | 153 ++++++++++----------- src/citra_qt/multiplayer/state.cpp | 25 +++- src/citra_qt/multiplayer/state.h | 5 +- 9 files changed, 107 insertions(+), 171 deletions(-) diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 41528718be..306c79acec 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -172,7 +172,8 @@ void GMainWindow::InitializeWidgets() { game_list = new GameList(this); ui.horizontalLayout->addWidget(game_list); - multiplayer_state = new MultiplayerState(this, game_list->GetModel()); + multiplayer_state = new MultiplayerState(this, game_list->GetModel(), ui.action_Leave_Room, + ui.action_Show_Room); multiplayer_state->setVisible(false); // Setup updater @@ -436,11 +437,11 @@ void GMainWindow::ConnectMenuEvents() { &MultiplayerState::OnViewLobby); connect(ui.action_Start_Room, &QAction::triggered, multiplayer_state, &MultiplayerState::OnCreateRoom); - connect(ui.action_Stop_Room, &QAction::triggered, multiplayer_state, + connect(ui.action_Leave_Room, &QAction::triggered, multiplayer_state, &MultiplayerState::OnCloseRoom); connect(ui.action_Connect_To_Room, &QAction::triggered, multiplayer_state, &MultiplayerState::OnDirectConnectToRoom); - connect(ui.action_Chat, &QAction::triggered, multiplayer_state, + connect(ui.action_Show_Room, &QAction::triggered, multiplayer_state, &MultiplayerState::OnOpenNetworkRoom); ui.action_Fullscreen->setShortcut(GetHotkey("Main Window", "Fullscreen", this)->key()); @@ -1331,18 +1332,6 @@ void GMainWindow::SyncMenuUISettings() { ui.action_Screen_Layout_Swap_Screens->setChecked(Settings::values.swap_screen); } -void GMainWindow::ChangeRoomState() { - if (auto room = Network::GetRoom().lock()) { - if (room->GetState() == Network::Room::State::Open) { - ui.action_Start_Room->setDisabled(true); - ui.action_Stop_Room->setEnabled(true); - return; - } - ui.action_Start_Room->setEnabled(true); - ui.action_Stop_Room->setDisabled(true); - } -} - #ifdef main #undef main #endif diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h index a3f2371fa1..f0aaf91143 100644 --- a/src/citra_qt/main.h +++ b/src/citra_qt/main.h @@ -12,7 +12,6 @@ #include "common/announce_multiplayer_room.h" #include "core/core.h" #include "core/hle/service/am/am.h" -#include "network/network.h" #include "ui_main.h" class AboutDialog; @@ -55,7 +54,6 @@ class GMainWindow : public QMainWindow { public: void filterBarSetChecked(bool state); void UpdateUITheme(); - void ChangeRoomState(); GameList* game_list; GMainWindow(); diff --git a/src/citra_qt/main.ui b/src/citra_qt/main.ui index d7ffc6b060..86c4e46ed5 100644 --- a/src/citra_qt/main.ui +++ b/src/citra_qt/main.ui @@ -116,10 +116,10 @@ - - + + @@ -259,12 +259,12 @@ Create Room - + false - Close Room + Leave Room @@ -272,12 +272,12 @@ Direct Connect to Room - + false - Current Room + Show Current Room diff --git a/src/citra_qt/multiplayer/direct_connect.ui b/src/citra_qt/multiplayer/direct_connect.ui index 81aac7431a..681b6bf69d 100644 --- a/src/citra_qt/multiplayer/direct_connect.ui +++ b/src/citra_qt/multiplayer/direct_connect.ui @@ -7,7 +7,7 @@ 0 0 455 - 239 + 161 @@ -18,28 +18,6 @@ - - - - Instructions - - - - - - <html><head/><body><p>Directly connect to a friend by <span style=" font-weight:600;">Traversal server</span> or by<span style=" font-weight:600;"> IP address</span>. </p><p>To use the <span style=" font-weight:600;">Traversal Server</span>, ask the game host for their &quot;<span style=" font-weight:600;">Host Code</span>&quot; which will be visible on the create room screen after it is created.</p></body></html> - - - Qt::RichText - - - true - - - - - - diff --git a/src/citra_qt/multiplayer/lobby.cpp b/src/citra_qt/multiplayer/lobby.cpp index 6780ac4304..b4e91d6ede 100644 --- a/src/citra_qt/multiplayer/lobby.cpp +++ b/src/citra_qt/multiplayer/lobby.cpp @@ -32,6 +32,7 @@ Lobby::Lobby(QWidget* parent, QStandardItemModel* list, model = new QStandardItemModel(ui->room_list); proxy = new LobbyFilterProxyModel(this, game_list); proxy->setSourceModel(model); + proxy->setDynamicSortFilter(true); proxy->setFilterCaseSensitivity(Qt::CaseInsensitive); proxy->setSortLocaleAware(true); ui->room_list->setModel(proxy); @@ -45,7 +46,6 @@ Lobby::Lobby(QWidget* parent, QStandardItemModel* list, ui->room_list->setSortingEnabled(true); ui->room_list->setEditTriggers(QHeaderView::NoEditTriggers); ui->room_list->setExpandsOnDoubleClick(false); - // ui->room_list->setUniformRowHeights(true); ui->room_list->setContextMenuPolicy(Qt::CustomContextMenu); ui->nickname->setValidator(Validation::nickname); @@ -54,7 +54,6 @@ Lobby::Lobby(QWidget* parent, QStandardItemModel* list, // UI Buttons MultiplayerState* p = reinterpret_cast(parent); connect(ui->refresh_list, &QPushButton::pressed, this, &Lobby::RefreshLobby); - connect(ui->chat, &QPushButton::pressed, p, &MultiplayerState::OnOpenNetworkRoom); connect(ui->games_owned, &QCheckBox::stateChanged, proxy, &LobbyFilterProxyModel::SetFilterOwned); connect(ui->hide_full, &QCheckBox::stateChanged, proxy, &LobbyFilterProxyModel::SetFilterFull); @@ -68,28 +67,11 @@ Lobby::Lobby(QWidget* parent, QStandardItemModel* list, // TODO(jroweboy): change this slot to OnConnected? connect(this, &Lobby::Connected, p, &MultiplayerState::OnOpenNetworkRoom); - // setup the callbacks for network updates - if (auto member = Network::GetRoomMember().lock()) { - member->BindOnStateChanged( - [this](const Network::RoomMember::State& state) { emit StateChanged(state); }); - connect(this, &Lobby::StateChanged, this, &Lobby::OnStateChanged); - } else { - // TODO (jroweboy) network was not initialized? - } - // manually start a refresh when the window is opening // TODO(jroweboy): if this refresh is slow for people with bad internet, then don't do it as // part of the constructor, but offload the refresh until after the window shown. perhaps emit a // refreshroomlist signal from places that open the lobby RefreshLobby(); - - if (auto member = Network::GetRoomMember().lock()) { - if (member->IsConnected()) { - ui->chat->setEnabled(true); - return; - } - } - ui->chat->setDisabled(true); } const QString Lobby::PasswordPrompt() { @@ -148,16 +130,6 @@ void Lobby::OnJoinRoom(const QModelIndex& index) { Settings::Apply(); } -void Lobby::OnStateChanged(const Network::RoomMember::State& state) { - if (auto member = Network::GetRoomMember().lock()) { - if (member->IsConnected()) { - ui->chat->setEnabled(true); - return; - } - } - ui->chat->setDisabled(true); -} - void Lobby::ResetModel() { model->clear(); model->insertColumns(0, Column::TOTAL); @@ -218,7 +190,7 @@ void Lobby::OnRefreshLobby() { first_item->appendRow(new LobbyItemExpandedMemberList(members)); } } - ui->room_list->setModel(model); + proxy->setSourceModel(model); // Reenable the refresh button and resize the columns ui->refresh_list->setEnabled(true); @@ -311,12 +283,12 @@ void LobbyFilterProxyModel::sort(int column, Qt::SortOrder order) { void LobbyFilterProxyModel::SetFilterOwned(bool filter) { filter_owned = filter; - invalidateFilter(); + invalidate(); } void LobbyFilterProxyModel::SetFilterFull(bool filter) { filter_full = filter; - invalidateFilter(); + invalidate(); } void Lobby::OnConnection() { diff --git a/src/citra_qt/multiplayer/lobby.h b/src/citra_qt/multiplayer/lobby.h index c68a7fd7b5..4fbc56b9ac 100644 --- a/src/citra_qt/multiplayer/lobby.h +++ b/src/citra_qt/multiplayer/lobby.h @@ -68,8 +68,6 @@ private slots: */ void OnConnection(); - void OnStateChanged(const Network::RoomMember::State&); - signals: /** * Signalled when the latest lobby data is retrieved. diff --git a/src/citra_qt/multiplayer/lobby.ui b/src/citra_qt/multiplayer/lobby.ui index b21a7c928c..835d03238f 100644 --- a/src/citra_qt/multiplayer/lobby.ui +++ b/src/citra_qt/multiplayer/lobby.ui @@ -6,7 +6,7 @@ 0 0 - 850 + 903 487 @@ -24,98 +24,83 @@ 6 - - - - Nickname - - - false - - - - 6 - - - 1 - - - 6 - - - 4 - - - - - Nickname - - - - - - - - - - Filters - - - false - - - - 6 - - - 1 - - - 6 - - - 4 - - - - - Search - - - true - - - - - - - Games I Own - - - - - - - Hide Full Games - - - - - - - + - Refresh Lobby + Nickname - + + + Nickname + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + - Chat + Filters + + + + + + + Search + + + true + + + + + + + Games I Own + + + + + + + Hide Full Games + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Refresh Lobby diff --git a/src/citra_qt/multiplayer/state.cpp b/src/citra_qt/multiplayer/state.cpp index 8882f1c535..d90046c52c 100644 --- a/src/citra_qt/multiplayer/state.cpp +++ b/src/citra_qt/multiplayer/state.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include #include #include #include @@ -16,8 +17,10 @@ #include "common/announce_multiplayer_room.h" #include "common/logging/log.h" -MultiplayerState::MultiplayerState(QWidget* parent, QStandardItemModel* game_list_model) - : QWidget(parent), game_list_model(game_list_model) { +MultiplayerState::MultiplayerState(QWidget* parent, QStandardItemModel* game_list_model, + QAction* leave_room, QAction* show_room) + : QWidget(parent), game_list_model(game_list_model), leave_room(leave_room), + show_room(show_room) { if (auto member = Network::GetRoomMember().lock()) { // register the network structs to use in slots and signals state_callback_handle = member->BindOnStateChanged( @@ -67,10 +70,14 @@ void MultiplayerState::OnNetworkStateChanged(const Network::RoomMember::State& s if (state == Network::RoomMember::State::Joined) { status_icon->setPixmap(QIcon::fromTheme("connected").pixmap(16)); status_text->setText(tr("Connected")); + leave_room->setEnabled(true); + show_room->setEnabled(true); return; } status_icon->setPixmap(QIcon::fromTheme("disconnected").pixmap(16)); status_text->setText(tr("Not Connected")); + leave_room->setEnabled(false); + show_room->setEnabled(false); } void MultiplayerState::OnAnnounceFailed(const Common::WebResult& result) { @@ -103,14 +110,20 @@ void MultiplayerState::OnCreateRoom() { } void MultiplayerState::OnCloseRoom() { + if (!NetworkMessage::WarnCloseRoom()) + return; if (auto room = Network::GetRoom().lock()) { + // if you are in a room, leave it + if (auto member = Network::GetRoomMember().lock()) { + member->Leave(); + } + + // if you are hosting a room, also stop hosting if (room->GetState() != Network::Room::State::Open) { return; } - if (NetworkMessage::WarnCloseRoom()) { - room->Destroy(); - announce_multiplayer_session->Stop(); - } + room->Destroy(); + announce_multiplayer_session->Stop(); } } diff --git a/src/citra_qt/multiplayer/state.h b/src/citra_qt/multiplayer/state.h index 7bfff6d4ec..1829d19fb2 100644 --- a/src/citra_qt/multiplayer/state.h +++ b/src/citra_qt/multiplayer/state.h @@ -21,7 +21,8 @@ class MultiplayerState : public QWidget { Q_OBJECT; public: - explicit MultiplayerState(QWidget* parent, QStandardItemModel* game_list); + explicit MultiplayerState(QWidget* parent, QStandardItemModel* game_list, QAction* leave_room, + QAction* show_room); ~MultiplayerState(); /** @@ -58,6 +59,8 @@ private: ClickableLabel* status_icon = nullptr; ClickableLabel* status_text = nullptr; QStandardItemModel* game_list_model = nullptr; + QAction* leave_room; + QAction* show_room; std::shared_ptr announce_multiplayer_session; Network::RoomMember::CallbackHandle state_callback_handle; };