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
This commit is contained in:
James Rowe 2018-04-17 12:01:14 -06:00
parent 601fd81d5c
commit a85511cd7d
9 changed files with 107 additions and 171 deletions

View file

@ -172,7 +172,8 @@ void GMainWindow::InitializeWidgets() {
game_list = new GameList(this); game_list = new GameList(this);
ui.horizontalLayout->addWidget(game_list); 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); multiplayer_state->setVisible(false);
// Setup updater // Setup updater
@ -436,11 +437,11 @@ void GMainWindow::ConnectMenuEvents() {
&MultiplayerState::OnViewLobby); &MultiplayerState::OnViewLobby);
connect(ui.action_Start_Room, &QAction::triggered, multiplayer_state, connect(ui.action_Start_Room, &QAction::triggered, multiplayer_state,
&MultiplayerState::OnCreateRoom); &MultiplayerState::OnCreateRoom);
connect(ui.action_Stop_Room, &QAction::triggered, multiplayer_state, connect(ui.action_Leave_Room, &QAction::triggered, multiplayer_state,
&MultiplayerState::OnCloseRoom); &MultiplayerState::OnCloseRoom);
connect(ui.action_Connect_To_Room, &QAction::triggered, multiplayer_state, connect(ui.action_Connect_To_Room, &QAction::triggered, multiplayer_state,
&MultiplayerState::OnDirectConnectToRoom); &MultiplayerState::OnDirectConnectToRoom);
connect(ui.action_Chat, &QAction::triggered, multiplayer_state, connect(ui.action_Show_Room, &QAction::triggered, multiplayer_state,
&MultiplayerState::OnOpenNetworkRoom); &MultiplayerState::OnOpenNetworkRoom);
ui.action_Fullscreen->setShortcut(GetHotkey("Main Window", "Fullscreen", this)->key()); 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); 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 #ifdef main
#undef main #undef main
#endif #endif

View file

@ -12,7 +12,6 @@
#include "common/announce_multiplayer_room.h" #include "common/announce_multiplayer_room.h"
#include "core/core.h" #include "core/core.h"
#include "core/hle/service/am/am.h" #include "core/hle/service/am/am.h"
#include "network/network.h"
#include "ui_main.h" #include "ui_main.h"
class AboutDialog; class AboutDialog;
@ -55,7 +54,6 @@ class GMainWindow : public QMainWindow {
public: public:
void filterBarSetChecked(bool state); void filterBarSetChecked(bool state);
void UpdateUITheme(); void UpdateUITheme();
void ChangeRoomState();
GameList* game_list; GameList* game_list;
GMainWindow(); GMainWindow();

View file

@ -116,10 +116,10 @@
</property> </property>
<addaction name="action_View_Lobby"/> <addaction name="action_View_Lobby"/>
<addaction name="action_Start_Room"/> <addaction name="action_Start_Room"/>
<addaction name="action_Stop_Room"/>
<addaction name="action_Connect_To_Room"/> <addaction name="action_Connect_To_Room"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="action_Chat"/> <addaction name="action_Show_Room"/>
<addaction name="action_Leave_Room"/>
</widget> </widget>
<widget class="QMenu" name="menu_Help"> <widget class="QMenu" name="menu_Help">
<property name="title"> <property name="title">
@ -259,12 +259,12 @@
<string>Create Room</string> <string>Create Room</string>
</property> </property>
</action> </action>
<action name="action_Stop_Room"> <action name="action_Leave_Room">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="text"> <property name="text">
<string>Close Room</string> <string>Leave Room</string>
</property> </property>
</action> </action>
<action name="action_Connect_To_Room"> <action name="action_Connect_To_Room">
@ -272,12 +272,12 @@
<string>Direct Connect to Room</string> <string>Direct Connect to Room</string>
</property> </property>
</action> </action>
<action name="action_Chat"> <action name="action_Show_Room">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>
</property> </property>
<property name="text"> <property name="text">
<string>Current Room</string> <string>Show Current Room</string>
</property> </property>
</action> </action>
<action name="action_Fullscreen"> <action name="action_Fullscreen">

View file

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>455</width> <width>455</width>
<height>239</height> <height>161</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -18,28 +18,6 @@
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_3">
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="instructions_2">
<property name="title">
<string>Instructions</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="instructions">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Directly connect to a friend by &lt;span style=&quot; font-weight:600;&quot;&gt;Traversal server&lt;/span&gt; or by&lt;span style=&quot; font-weight:600;&quot;&gt; IP address&lt;/span&gt;. &lt;/p&gt;&lt;p&gt;To use the &lt;span style=&quot; font-weight:600;&quot;&gt;Traversal Server&lt;/span&gt;, ask the game host for their &amp;quot;&lt;span style=&quot; font-weight:600;&quot;&gt;Host Code&lt;/span&gt;&amp;quot; which will be visible on the create room screen after it is created.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing"> <property name="spacing">

View file

@ -32,6 +32,7 @@ Lobby::Lobby(QWidget* parent, QStandardItemModel* list,
model = new QStandardItemModel(ui->room_list); model = new QStandardItemModel(ui->room_list);
proxy = new LobbyFilterProxyModel(this, game_list); proxy = new LobbyFilterProxyModel(this, game_list);
proxy->setSourceModel(model); proxy->setSourceModel(model);
proxy->setDynamicSortFilter(true);
proxy->setFilterCaseSensitivity(Qt::CaseInsensitive); proxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
proxy->setSortLocaleAware(true); proxy->setSortLocaleAware(true);
ui->room_list->setModel(proxy); ui->room_list->setModel(proxy);
@ -45,7 +46,6 @@ Lobby::Lobby(QWidget* parent, QStandardItemModel* list,
ui->room_list->setSortingEnabled(true); ui->room_list->setSortingEnabled(true);
ui->room_list->setEditTriggers(QHeaderView::NoEditTriggers); ui->room_list->setEditTriggers(QHeaderView::NoEditTriggers);
ui->room_list->setExpandsOnDoubleClick(false); ui->room_list->setExpandsOnDoubleClick(false);
// ui->room_list->setUniformRowHeights(true);
ui->room_list->setContextMenuPolicy(Qt::CustomContextMenu); ui->room_list->setContextMenuPolicy(Qt::CustomContextMenu);
ui->nickname->setValidator(Validation::nickname); ui->nickname->setValidator(Validation::nickname);
@ -54,7 +54,6 @@ Lobby::Lobby(QWidget* parent, QStandardItemModel* list,
// UI Buttons // UI Buttons
MultiplayerState* p = reinterpret_cast<MultiplayerState*>(parent); MultiplayerState* p = reinterpret_cast<MultiplayerState*>(parent);
connect(ui->refresh_list, &QPushButton::pressed, this, &Lobby::RefreshLobby); connect(ui->refresh_list, &QPushButton::pressed, this, &Lobby::RefreshLobby);
connect(ui->chat, &QPushButton::pressed, p, &MultiplayerState::OnOpenNetworkRoom);
connect(ui->games_owned, &QCheckBox::stateChanged, proxy, connect(ui->games_owned, &QCheckBox::stateChanged, proxy,
&LobbyFilterProxyModel::SetFilterOwned); &LobbyFilterProxyModel::SetFilterOwned);
connect(ui->hide_full, &QCheckBox::stateChanged, proxy, &LobbyFilterProxyModel::SetFilterFull); 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? // TODO(jroweboy): change this slot to OnConnected?
connect(this, &Lobby::Connected, p, &MultiplayerState::OnOpenNetworkRoom); 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 // 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 // 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 // part of the constructor, but offload the refresh until after the window shown. perhaps emit a
// refreshroomlist signal from places that open the lobby // refreshroomlist signal from places that open the lobby
RefreshLobby(); RefreshLobby();
if (auto member = Network::GetRoomMember().lock()) {
if (member->IsConnected()) {
ui->chat->setEnabled(true);
return;
}
}
ui->chat->setDisabled(true);
} }
const QString Lobby::PasswordPrompt() { const QString Lobby::PasswordPrompt() {
@ -148,16 +130,6 @@ void Lobby::OnJoinRoom(const QModelIndex& index) {
Settings::Apply(); 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() { void Lobby::ResetModel() {
model->clear(); model->clear();
model->insertColumns(0, Column::TOTAL); model->insertColumns(0, Column::TOTAL);
@ -218,7 +190,7 @@ void Lobby::OnRefreshLobby() {
first_item->appendRow(new LobbyItemExpandedMemberList(members)); first_item->appendRow(new LobbyItemExpandedMemberList(members));
} }
} }
ui->room_list->setModel(model); proxy->setSourceModel(model);
// Reenable the refresh button and resize the columns // Reenable the refresh button and resize the columns
ui->refresh_list->setEnabled(true); ui->refresh_list->setEnabled(true);
@ -311,12 +283,12 @@ void LobbyFilterProxyModel::sort(int column, Qt::SortOrder order) {
void LobbyFilterProxyModel::SetFilterOwned(bool filter) { void LobbyFilterProxyModel::SetFilterOwned(bool filter) {
filter_owned = filter; filter_owned = filter;
invalidateFilter(); invalidate();
} }
void LobbyFilterProxyModel::SetFilterFull(bool filter) { void LobbyFilterProxyModel::SetFilterFull(bool filter) {
filter_full = filter; filter_full = filter;
invalidateFilter(); invalidate();
} }
void Lobby::OnConnection() { void Lobby::OnConnection() {

View file

@ -68,8 +68,6 @@ private slots:
*/ */
void OnConnection(); void OnConnection();
void OnStateChanged(const Network::RoomMember::State&);
signals: signals:
/** /**
* Signalled when the latest lobby data is retrieved. * Signalled when the latest lobby data is retrieved.

View file

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>850</width> <width>903</width>
<height>487</height> <height>487</height>
</rect> </rect>
</property> </property>
@ -25,26 +25,14 @@
<number>6</number> <number>6</number>
</property> </property>
<item> <item>
<widget class="QGroupBox" name="general"> <layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="title"> <item>
<widget class="QLabel" name="label">
<property name="text">
<string>Nickname</string> <string>Nickname</string>
</property> </property>
<property name="flat"> </widget>
<bool>false</bool> </item>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>1</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item> <item>
<widget class="QLineEdit" name="nickname"> <widget class="QLineEdit" name="nickname">
<property name="placeholderText"> <property name="placeholderText">
@ -52,30 +40,26 @@
</property> </property>
</widget> </widget>
</item> </item>
</layout> <item>
</widget> <spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item> </item>
<item> <item>
<widget class="QGroupBox" name="filters"> <widget class="QLabel" name="label_2">
<property name="title"> <property name="text">
<string>Filters</string> <string>Filters</string>
</property> </property>
<property name="flat"> </widget>
<bool>false</bool> </item>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>1</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item> <item>
<widget class="QLineEdit" name="search"> <widget class="QLineEdit" name="search">
<property name="placeholderText"> <property name="placeholderText">
@ -100,11 +84,19 @@
</property> </property>
</widget> </widget>
</item> </item>
</layout>
</widget>
</item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout_5"> <spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item> <item>
<widget class="QPushButton" name="refresh_list"> <widget class="QPushButton" name="refresh_list">
<property name="text"> <property name="text">
@ -112,13 +104,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="chat">
<property name="text">
<string>Chat</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>

View file

@ -2,6 +2,7 @@
// Licensed under GPLv2 or any later version // Licensed under GPLv2 or any later version
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include <QAction>
#include <QIcon> #include <QIcon>
#include <QMessageBox> #include <QMessageBox>
#include <QStandardItemModel> #include <QStandardItemModel>
@ -16,8 +17,10 @@
#include "common/announce_multiplayer_room.h" #include "common/announce_multiplayer_room.h"
#include "common/logging/log.h" #include "common/logging/log.h"
MultiplayerState::MultiplayerState(QWidget* parent, QStandardItemModel* game_list_model) MultiplayerState::MultiplayerState(QWidget* parent, QStandardItemModel* game_list_model,
: QWidget(parent), game_list_model(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()) { if (auto member = Network::GetRoomMember().lock()) {
// register the network structs to use in slots and signals // register the network structs to use in slots and signals
state_callback_handle = member->BindOnStateChanged( state_callback_handle = member->BindOnStateChanged(
@ -67,10 +70,14 @@ void MultiplayerState::OnNetworkStateChanged(const Network::RoomMember::State& s
if (state == Network::RoomMember::State::Joined) { if (state == Network::RoomMember::State::Joined) {
status_icon->setPixmap(QIcon::fromTheme("connected").pixmap(16)); status_icon->setPixmap(QIcon::fromTheme("connected").pixmap(16));
status_text->setText(tr("Connected")); status_text->setText(tr("Connected"));
leave_room->setEnabled(true);
show_room->setEnabled(true);
return; return;
} }
status_icon->setPixmap(QIcon::fromTheme("disconnected").pixmap(16)); status_icon->setPixmap(QIcon::fromTheme("disconnected").pixmap(16));
status_text->setText(tr("Not Connected")); status_text->setText(tr("Not Connected"));
leave_room->setEnabled(false);
show_room->setEnabled(false);
} }
void MultiplayerState::OnAnnounceFailed(const Common::WebResult& result) { void MultiplayerState::OnAnnounceFailed(const Common::WebResult& result) {
@ -103,15 +110,21 @@ void MultiplayerState::OnCreateRoom() {
} }
void MultiplayerState::OnCloseRoom() { void MultiplayerState::OnCloseRoom() {
if (!NetworkMessage::WarnCloseRoom())
return;
if (auto room = Network::GetRoom().lock()) { 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) { if (room->GetState() != Network::Room::State::Open) {
return; return;
} }
if (NetworkMessage::WarnCloseRoom()) {
room->Destroy(); room->Destroy();
announce_multiplayer_session->Stop(); announce_multiplayer_session->Stop();
} }
}
} }
void MultiplayerState::OnOpenNetworkRoom() { void MultiplayerState::OnOpenNetworkRoom() {

View file

@ -21,7 +21,8 @@ class MultiplayerState : public QWidget {
Q_OBJECT; Q_OBJECT;
public: public:
explicit MultiplayerState(QWidget* parent, QStandardItemModel* game_list); explicit MultiplayerState(QWidget* parent, QStandardItemModel* game_list, QAction* leave_room,
QAction* show_room);
~MultiplayerState(); ~MultiplayerState();
/** /**
@ -58,6 +59,8 @@ private:
ClickableLabel* status_icon = nullptr; ClickableLabel* status_icon = nullptr;
ClickableLabel* status_text = nullptr; ClickableLabel* status_text = nullptr;
QStandardItemModel* game_list_model = nullptr; QStandardItemModel* game_list_model = nullptr;
QAction* leave_room;
QAction* show_room;
std::shared_ptr<Core::AnnounceMultiplayerSession> announce_multiplayer_session; std::shared_ptr<Core::AnnounceMultiplayerSession> announce_multiplayer_session;
Network::RoomMember::CallbackHandle<Network::RoomMember::State> state_callback_handle; Network::RoomMember::CallbackHandle<Network::RoomMember::State> state_callback_handle;
}; };