diff --git a/Source/RMG/CMakeLists.txt b/Source/RMG/CMakeLists.txt
index 50e1c6ef..fb30aa2f 100644
--- a/Source/RMG/CMakeLists.txt
+++ b/Source/RMG/CMakeLists.txt
@@ -98,6 +98,10 @@ if (NETPLAY)
UserInterface/Dialog/Netplay/NetplaySessionDialog.ui
UserInterface/Dialog/Netplay/NetplaySessionPasswordDialog.cpp
UserInterface/Dialog/Netplay/NetplaySessionPasswordDialog.ui
+ UserInterface/Widget/Netplay/NetplaySessionBrowserWidget.cpp
+ UserInterface/Widget/Netplay/NetplaySessionBrowserLoadingWidget.cpp
+ UserInterface/Widget/Netplay/NetplaySessionBrowserEmptyWidget.cpp
+ UserInterface/Widget/Netplay/NetplaySessionBrowserEmptyWidget.ui
)
endif(NETPLAY)
diff --git a/Source/RMG/UserInterface/Dialog/Netplay/NetplaySessionBrowserDialog.cpp b/Source/RMG/UserInterface/Dialog/Netplay/NetplaySessionBrowserDialog.cpp
index 904c4ee6..0ee52787 100644
--- a/Source/RMG/UserInterface/Dialog/Netplay/NetplaySessionBrowserDialog.cpp
+++ b/Source/RMG/UserInterface/Dialog/Netplay/NetplaySessionBrowserDialog.cpp
@@ -8,7 +8,6 @@
* along with this program. If not, see .
*/
#include "NetplaySessionBrowserDialog.hpp"
-#include "UserInterface/NoFocusDelegate.hpp"
#include "NetplaySessionPasswordDialog.hpp"
#include "NetplayCommon.hpp"
@@ -26,37 +25,18 @@
using namespace UserInterface::Dialog;
-//
-// Local Structs
-//
-
-struct NetplaySessionData_t
-{
- QString SessionName;
- QString GameName;
- QString MD5;
- bool PasswordProtected = false;
- int Port = 0;
- QString CpuEmulator;
- QString RspPlugin;
- QString GfxPlugin;
-};
-
-Q_DECLARE_METATYPE(NetplaySessionData_t);
-
//
// Exported Functions
//
NetplaySessionBrowserDialog::NetplaySessionBrowserDialog(QWidget *parent, QWebSocket* webSocket, QMap modelData) : QDialog(parent)
{
- qRegisterMetaType();
-
this->setupUi(this);
// prepare web socket
this->webSocket = webSocket;
connect(this->webSocket, &QWebSocket::connected, this, &NetplaySessionBrowserDialog::on_webSocket_connected);
+ connect(this->webSocket, &QWebSocket::disconnected, this, &NetplaySessionBrowserDialog::on_webSocket_disconnected);
connect(this->webSocket, &QWebSocket::textMessageReceived, this, &NetplaySessionBrowserDialog::on_webSocket_textMessageReceived);
// copy rom data for later
@@ -85,25 +65,6 @@ NetplaySessionBrowserDialog::NetplaySessionBrowserDialog(QWidget *parent, QWebSo
this->nickNameLineEdit->setValidator(new QRegularExpressionValidator(re, this));
this->nickNameLineEdit->setText(QString::fromStdString(CoreSettingsGetStringValue(SettingsID::Netplay_Nickname)));
- // prepare session browser
- this->tableWidget->setFrameStyle(QFrame::NoFrame);
- this->tableWidget->setItemDelegate(new NoFocusDelegate(this));
- this->tableWidget->setWordWrap(false);
- this->tableWidget->setShowGrid(false);
- this->tableWidget->setSortingEnabled(true);
- this->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
- this->tableWidget->setSelectionBehavior(QTableView::SelectRows);
- this->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
- this->tableWidget->setVerticalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel);
- this->tableWidget->verticalHeader()->hide();
- this->tableWidget->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
- this->tableWidget->horizontalHeader()->setSectionsMovable(true);
- this->tableWidget->horizontalHeader()->setFirstSectionMovable(true);
- this->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
- this->tableWidget->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
- this->tableWidget->horizontalHeader()->setSortIndicatorShown(false);
- this->tableWidget->horizontalHeader()->setHighlightSections(false);
-
// request server list
QString serverUrl = QString::fromStdString(CoreSettingsGetStringValue(SettingsID::Netplay_ServerJsonUrl));
if (!serverUrl.isEmpty() && QUrl(serverUrl).isValid())
@@ -184,7 +145,7 @@ bool NetplaySessionBrowserDialog::validate(void)
return false;
}
- if (this->tableWidget->currentItem() == nullptr ||
+ if (!this->netplaySessionBrowserWidget->IsCurrentSessionValid() ||
this->serverComboBox->count() == 0)
{
return false;
@@ -199,51 +160,24 @@ void NetplaySessionBrowserDialog::validateJoinButton(void)
joinButton->setEnabled(this->validate());
}
-void NetplaySessionBrowserDialog::addSessionData(QString name, QString game, QString md5, bool password, int port,
- QString cpuEmulator, QString rspPlugin, QString gfxPlugin)
-{
- const NetplaySessionData_t sessionData =
- {
- name,
- game,
- md5,
- password,
- port,
- cpuEmulator,
- rspPlugin,
- gfxPlugin
- };
-
- int row = this->tableWidget->rowCount();
- this->tableWidget->insertRow(row);
-
- // Session name
- QTableWidgetItem* tableWidgetItem1 = new QTableWidgetItem(name);
- tableWidgetItem1->setData(Qt::UserRole, QVariant::fromValue(sessionData));
- this->tableWidget->setItem(row, 0, tableWidgetItem1);
-
- // Game
- QTableWidgetItem* tableWidgetItem2 = new QTableWidgetItem(game);
- this->tableWidget->setItem(row, 1, tableWidgetItem2);
-
- // MD5
- QTableWidgetItem* tableWidgetItem3 = new QTableWidgetItem(md5);
- this->tableWidget->setItem(row, 2, tableWidgetItem3);
-
- // Password
- QTableWidgetItem* tableWidgetItem4 = new QTableWidgetItem(password ? "Yes" : "No");
- this->tableWidget->setItem(row, 3, tableWidgetItem4);
-}
-
void NetplaySessionBrowserDialog::on_webSocket_connected(void)
{
if (!this->webSocket->isValid())
{
+ this->showErrorMessage("Server Error", "Connection Failed");
return;
}
- // clear sessions from the table
- this->tableWidget->model()->removeRows(0, this->tableWidget->rowCount());
+ // disable refresh button while refreshing
+ QPushButton* refreshButton = this->buttonBox->button(QDialogButtonBox::RestoreDefaults);
+ refreshButton->setEnabled(false);
+
+ // disable join button while refreshing
+ QPushButton* joinButton = this->buttonBox->button(QDialogButtonBox::Ok);
+ joinButton->setEnabled(false);
+
+ // clear sessions
+ this->netplaySessionBrowserWidget->StartRefresh();
// request session list from server
QJsonObject json;
@@ -264,14 +198,30 @@ void NetplaySessionBrowserDialog::on_webSocket_textMessageReceived(QString messa
{
if (json.value("accept").toInt() == 0)
{
- this->addSessionData(json.value("room_name").toString(),
- json.value("game_name").toString(),
- json.value("MD5").toString(),
- json.value("protected").toBool(),
- json.value("port").toInt(),
- json.value("features").toObject().value("cpu_emulator").toString(),
- json.value("features").toObject().value("rsp_plugin").toString(),
- json.value("features").toObject().value("gfx_plugin").toString());
+ this->netplaySessionBrowserWidget->AddSessionData(json.value("room_name").toString(),
+ json.value("game_name").toString(),
+ json.value("MD5").toString(),
+ json.value("protected").toBool(),
+ json.value("port").toInt(),
+ json.value("features").toObject().value("cpu_emulator").toString(),
+ json.value("features").toObject().value("rsp_plugin").toString(),
+ json.value("features").toObject().value("gfx_plugin").toString());
+ }
+ else
+ {
+ this->showErrorMessage("Server Error", json.value("message").toString());
+ }
+ }
+ else if (type == "reply_get_rooms_done")
+ {
+ if (json.value("accept").toInt() == 0)
+ {
+ this->netplaySessionBrowserWidget->RefreshDone();
+ // enable refresh button when refreshing is done
+ QPushButton* refreshButton = this->buttonBox->button(QDialogButtonBox::RestoreDefaults);
+ refreshButton->setEnabled(true);
+ // re-validate join button after refresh
+ this->validateJoinButton();
}
else
{
@@ -293,6 +243,11 @@ void NetplaySessionBrowserDialog::on_webSocket_textMessageReceived(QString messa
}
}
+void NetplaySessionBrowserDialog::on_webSocket_disconnected()
+{
+ this->netplaySessionBrowserWidget->Reset();
+}
+
void NetplaySessionBrowserDialog::on_broadcastSocket_readyRead(void)
{
while (this->broadcastSocket.hasPendingDatagrams())
@@ -314,6 +269,8 @@ void NetplaySessionBrowserDialog::on_networkAccessManager_Finished(QNetworkReply
{
if (reply->error())
{
+ this->netplaySessionBrowserWidget->Reset();
+ this->showErrorMessage("Server Error", "Failed to retrieve json server list: " + reply->errorString());
reply->deleteLater();
return;
}
@@ -340,14 +297,13 @@ void NetplaySessionBrowserDialog::on_serverComboBox_currentIndexChanged(int inde
return;
}
- // clear sessions from the table
- this->tableWidget->model()->removeRows(0, this->tableWidget->rowCount());
+ this->netplaySessionBrowserWidget->StartRefresh();
QString address = this->serverComboBox->itemData(index).toString();
this->webSocket->open(QUrl(address));
}
-void NetplaySessionBrowserDialog::on_tableWidget_currentItemChanged(QTableWidgetItem* current, QTableWidgetItem* previous)
+void NetplaySessionBrowserDialog::on_netplaySessionBrowserWidget_OnSessionChanged(bool valid)
{
this->validateJoinButton();
}
@@ -374,14 +330,17 @@ void NetplaySessionBrowserDialog::accept()
return;
}
+ // retrieve session data
+ NetplaySessionData sessionData;
+ if (!this->netplaySessionBrowserWidget->GetCurrentSession(sessionData))
+ {
+ return;
+ }
+
// disable join button while we're processing the request
QPushButton* joinButton = this->buttonBox->button(QDialogButtonBox::Ok);
joinButton->setEnabled(false);
- // retrieve information from row
- QTableWidgetItem* item = this->tableWidget->item(this->tableWidget->currentRow(), 0);
- NetplaySessionData_t sessionData = item->data(Qt::UserRole).value();
-
// request password when needed
QString password;
if (sessionData.PasswordProtected)
diff --git a/Source/RMG/UserInterface/Dialog/Netplay/NetplaySessionBrowserDialog.hpp b/Source/RMG/UserInterface/Dialog/Netplay/NetplaySessionBrowserDialog.hpp
index 6bbd3700..35e49691 100644
--- a/Source/RMG/UserInterface/Dialog/Netplay/NetplaySessionBrowserDialog.hpp
+++ b/Source/RMG/UserInterface/Dialog/Netplay/NetplaySessionBrowserDialog.hpp
@@ -50,17 +50,16 @@ class NetplaySessionBrowserDialog : public QDialog, private Ui::NetplaySessionBr
bool validate(void);
void validateJoinButton(void);
- void addSessionData(QString name, QString game, QString md5, bool password, int port,
- QString cpuEmulator, QString rspPlugin, QString gfxPlugin);
-
private slots:
void on_webSocket_connected(void);
void on_webSocket_textMessageReceived(QString message);
+ void on_webSocket_disconnected(void);
+
void on_broadcastSocket_readyRead(void);
void on_networkAccessManager_Finished(QNetworkReply* reply);
void on_serverComboBox_currentIndexChanged(int index);
- void on_tableWidget_currentItemChanged(QTableWidgetItem* current, QTableWidgetItem* previous);
+ void on_netplaySessionBrowserWidget_OnSessionChanged(bool valid);
void on_nickNameLineEdit_textChanged(void);
diff --git a/Source/RMG/UserInterface/Dialog/Netplay/NetplaySessionBrowserDialog.ui b/Source/RMG/UserInterface/Dialog/Netplay/NetplaySessionBrowserDialog.ui
index 5919bf65..97d37f4e 100644
--- a/Source/RMG/UserInterface/Dialog/Netplay/NetplaySessionBrowserDialog.ui
+++ b/Source/RMG/UserInterface/Dialog/Netplay/NetplaySessionBrowserDialog.ui
@@ -50,33 +50,15 @@
-
-
-
- true
-
-
- false
-
-
-
- Name
-
-
-
-
- Game
-
-
-
-
- Game MD5
-
-
-
-
- Password?
-
-
+
+
+
+ 0
+ 0
+
+
+
+
-
@@ -91,6 +73,14 @@
+
+
+ UserInterface::Widget::NetplaySessionBrowserWidget
+ QStackedWidget
+ UserInterface/Widget/Netplay/NetplaySessionBrowserWidget.hpp
+ 1
+
+
diff --git a/Source/RMG/UserInterface/Widget/Netplay/NetplaySessionBrowserEmptyWidget.cpp b/Source/RMG/UserInterface/Widget/Netplay/NetplaySessionBrowserEmptyWidget.cpp
new file mode 100644
index 00000000..ab116c38
--- /dev/null
+++ b/Source/RMG/UserInterface/Widget/Netplay/NetplaySessionBrowserEmptyWidget.cpp
@@ -0,0 +1,27 @@
+/*
+ * Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
+ * Copyright (C) 2020 Rosalie Wanders
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#include "NetplaySessionBrowserEmptyWidget.hpp"
+
+#include
+#include
+#include
+#include
+#include
+
+using namespace UserInterface::Widget;
+
+NetplaySessionBrowserEmptyWidget::NetplaySessionBrowserEmptyWidget(QWidget* parent) : QWidget(parent)
+{
+ this->setupUi(this);
+}
+
+NetplaySessionBrowserEmptyWidget::~NetplaySessionBrowserEmptyWidget()
+{
+}
diff --git a/Source/RMG/UserInterface/Widget/Netplay/NetplaySessionBrowserEmptyWidget.hpp b/Source/RMG/UserInterface/Widget/Netplay/NetplaySessionBrowserEmptyWidget.hpp
new file mode 100644
index 00000000..89ab5b5f
--- /dev/null
+++ b/Source/RMG/UserInterface/Widget/Netplay/NetplaySessionBrowserEmptyWidget.hpp
@@ -0,0 +1,31 @@
+/*
+ * Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
+ * Copyright (C) 2020 Rosalie Wanders
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#ifndef NETPLAYSESSIONBROWSEREMPTYWIDGET_HPP
+#define NETPLAYSESSIONBROWSEREMPTYWIDGET_HPP
+
+#include
+
+#include "ui_NetplaySessionBrowserEmptyWidget.h"
+
+namespace UserInterface
+{
+namespace Widget
+{
+class NetplaySessionBrowserEmptyWidget : public QWidget, private Ui::NetplaySessionBrowserEmptyWidget
+{
+ Q_OBJECT
+public:
+ NetplaySessionBrowserEmptyWidget(QWidget* parent);
+ ~NetplaySessionBrowserEmptyWidget();
+};
+} // namespace Widget
+} // namespace UserInterface
+
+#endif // NETPLAYSESSIONBROWSEREMPTYWIDGET_HPP
diff --git a/Source/RMG/UserInterface/Widget/Netplay/NetplaySessionBrowserEmptyWidget.ui b/Source/RMG/UserInterface/Widget/Netplay/NetplaySessionBrowserEmptyWidget.ui
new file mode 100644
index 00000000..143d0dda
--- /dev/null
+++ b/Source/RMG/UserInterface/Widget/Netplay/NetplaySessionBrowserEmptyWidget.ui
@@ -0,0 +1,63 @@
+
+
+ NetplaySessionBrowserEmptyWidget
+
+
+
+ 0
+ 0
+ 743
+ 562
+
+
+
+ Form
+
+
+ -
+
+
+ Qt::Orientation::Vertical
+
+
+
+ 20
+ 169
+
+
+
+
+ -
+
+
+ <html><head/><body><p><span style=" font-weight:700;">No sessions were found.</span></p><p>You can create your own session or refresh the session list.</p></body></html>
+
+
+ Qt::TextFormat::RichText
+
+
+ Qt::AlignmentFlag::AlignCenter
+
+
+ true
+
+
+
+ -
+
+
+ Qt::Orientation::Vertical
+
+
+
+ 20
+ 170
+
+
+
+
+
+
+
+
+
diff --git a/Source/RMG/UserInterface/Widget/Netplay/NetplaySessionBrowserLoadingWidget.cpp b/Source/RMG/UserInterface/Widget/Netplay/NetplaySessionBrowserLoadingWidget.cpp
new file mode 100644
index 00000000..ff2b64d5
--- /dev/null
+++ b/Source/RMG/UserInterface/Widget/Netplay/NetplaySessionBrowserLoadingWidget.cpp
@@ -0,0 +1,96 @@
+/*
+ * Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
+ * Copyright (C) 2020 Rosalie Wanders
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#include "NetplaySessionBrowserLoadingWidget.hpp"
+
+#include
+#include
+#include
+
+using namespace UserInterface::Widget;
+
+NetplaySessionBrowserLoadingWidget::NetplaySessionBrowserLoadingWidget(QWidget* parent) : QWidget(parent)
+{
+ QHBoxLayout* layout = new QHBoxLayout(this);
+
+ this->loadingLabel = new QLabel(this);
+ this->loadingLabel->setText("Loading");
+ this->loadingLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
+
+ layout->addWidget(loadingLabel);
+
+ this->setLayout(layout);
+}
+
+NetplaySessionBrowserLoadingWidget::~NetplaySessionBrowserLoadingWidget()
+{
+}
+
+void NetplaySessionBrowserLoadingWidget::SetWidgetIndex(int index)
+{
+ this->widgetIndex = index;
+}
+
+void NetplaySessionBrowserLoadingWidget::on_NetplaySessionBrowserWidget_currentChanged(int index)
+{
+ // start timer when it isnt running
+ // and when we've switched to our widget,
+ // else kill the timer
+ if (this->widgetIndex == index)
+ {
+ if (this->loadingLabelTimerId == -1)
+ {
+ this->dotCount = 0;
+ this->elapsedTimeSinceLoading.start();
+ // reset loading text
+ this->updateLoadingText();
+ this->loadingLabelTimerId = this->startTimer(1000);
+ }
+ }
+ else
+ {
+ if (this->loadingLabelTimerId != -1)
+ {
+ this->elapsedTimeSinceLoading.invalidate();
+ this->killTimer(this->loadingLabelTimerId);
+ this->loadingLabelTimerId = -1;
+ }
+ }
+}
+
+void NetplaySessionBrowserLoadingWidget::updateLoadingText()
+{
+ QString loadingText = "Loading";
+
+ if (dotCount <= 3)
+ {
+ for (int i = 0; i < dotCount; i++)
+ {
+ loadingText += ".";
+ }
+
+ dotCount++;
+ }
+ else
+ {
+ dotCount = 1;
+ }
+
+ this->loadingLabel->setText(loadingText);
+}
+
+void NetplaySessionBrowserLoadingWidget::timerEvent(QTimerEvent *event)
+{
+ if (event->timerId() != this->loadingLabelTimerId)
+ {
+ return;
+ }
+
+ this->updateLoadingText();
+}
diff --git a/Source/RMG/UserInterface/Widget/Netplay/NetplaySessionBrowserLoadingWidget.hpp b/Source/RMG/UserInterface/Widget/Netplay/NetplaySessionBrowserLoadingWidget.hpp
new file mode 100644
index 00000000..cd92ba96
--- /dev/null
+++ b/Source/RMG/UserInterface/Widget/Netplay/NetplaySessionBrowserLoadingWidget.hpp
@@ -0,0 +1,49 @@
+/*
+ * Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
+ * Copyright (C) 2020 Rosalie Wanders
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#ifndef NETPLAYSESSIONLOADINGWIDGET_HPP
+#define NETPLAYSESSIONLOADINGWIDGET_HPP
+
+#include
+#include
+#include
+
+namespace UserInterface
+{
+namespace Widget
+{
+class NetplaySessionBrowserLoadingWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ NetplaySessionBrowserLoadingWidget(QWidget* parent);
+ ~NetplaySessionBrowserLoadingWidget();
+
+ void SetWidgetIndex(int index);
+
+public slots:
+ void on_NetplaySessionBrowserWidget_currentChanged(int index);
+
+private:
+ QLabel* loadingLabel;
+ int loadingLabelTimerId = -1;
+ int widgetIndex = -1;
+ int dotCount = 0;
+
+ QElapsedTimer elapsedTimeSinceLoading;
+
+ void updateLoadingText();
+
+protected:
+ void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE;
+};
+} // namespace Widget
+} // namespace UserInterface
+
+#endif // NETPLAYSESSIONLOADINGWIDGET_HPP
diff --git a/Source/RMG/UserInterface/Widget/Netplay/NetplaySessionBrowserWidget.cpp b/Source/RMG/UserInterface/Widget/Netplay/NetplaySessionBrowserWidget.cpp
new file mode 100644
index 00000000..e9f3e135
--- /dev/null
+++ b/Source/RMG/UserInterface/Widget/Netplay/NetplaySessionBrowserWidget.cpp
@@ -0,0 +1,188 @@
+/*
+ * Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
+ * Copyright (C) 2020 Rosalie Wanders
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#include "NetplaySessionBrowserWidget.hpp"
+#include "UserInterface/NoFocusDelegate.hpp"
+
+#include
+
+Q_DECLARE_METATYPE(NetplaySessionData);
+
+using namespace UserInterface::Widget;
+
+//
+// Exported Functions
+//
+
+NetplaySessionBrowserWidget::NetplaySessionBrowserWidget(QWidget* parent) : QStackedWidget(parent)
+{
+ // configure signal types
+ qRegisterMetaType("NetplaySessionData");
+
+ // configure empty widget
+ this->emptyWidget = new Widget::NetplaySessionBrowserEmptyWidget(this);
+ this->addWidget(this->emptyWidget);
+
+ // configure loading widget
+ this->loadingWidget = new Widget::NetplaySessionBrowserLoadingWidget(this);
+ connect(this, &QStackedWidget::currentChanged, this->loadingWidget, &NetplaySessionBrowserLoadingWidget::on_NetplaySessionBrowserWidget_currentChanged);
+ this->loadingWidget->SetWidgetIndex(this->addWidget(this->loadingWidget));
+
+ // configure table widget
+ this->tableWidget = new QTableWidget(this);
+ this->tableWidget->setFrameStyle(QFrame::NoFrame);
+ this->tableWidget->setItemDelegate(new NoFocusDelegate(this));
+ this->tableWidget->setWordWrap(false);
+ this->tableWidget->setShowGrid(false);
+ this->tableWidget->setSortingEnabled(true);
+ this->tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
+ this->tableWidget->setSelectionBehavior(QTableView::SelectRows);
+ this->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
+ this->tableWidget->setVerticalScrollMode(QAbstractItemView::ScrollMode::ScrollPerPixel);
+ this->tableWidget->verticalHeader()->hide();
+ this->tableWidget->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
+ this->tableWidget->horizontalHeader()->setSectionsMovable(true);
+ this->tableWidget->horizontalHeader()->setFirstSectionMovable(true);
+ this->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
+ this->tableWidget->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
+ this->tableWidget->horizontalHeader()->setSortIndicatorShown(false);
+ this->tableWidget->horizontalHeader()->setHighlightSections(false);
+ this->tableWidget->horizontalHeader()->setStretchLastSection(true);
+ this->addWidget(this->tableWidget);
+ connect(this->tableWidget, &QTableWidget::currentItemChanged, this, &NetplaySessionBrowserWidget::on_tableWidget_currentItemChanged);
+ /*connect(this->listViewWidget, &QTableView::doubleClicked, this, &RomBrowserWidget::on_DoubleClicked);
+ connect(this->listViewWidget->horizontalHeader(), &QHeaderView::sortIndicatorChanged, this, &RomBrowserWidget::on_listViewWidget_sortIndicatorChanged);
+ connect(this->listViewWidget->horizontalHeader(), &QHeaderView::sectionResized, this, &RomBrowserWidget::on_listViewWidget_sectionResized);
+ connect(this->listViewWidget->horizontalHeader(), &QHeaderView::sectionMoved, this, &RomBrowserWidget::on_listViewWidget_sectionMoved);
+ connect(this->listViewWidget->horizontalHeader(), &QHeaderView::customContextMenuRequested, this, &RomBrowserWidget::on_listViewWidget_headerContextMenuRequested);
+ connect(this->listViewWidget, &Widget::RomBrowserListViewWidget::ZoomIn, this, &RomBrowserWidget::on_ZoomIn);
+ connect(this->listViewWidget, &Widget::RomBrowserListViewWidget::ZoomOut, this, &RomBrowserWidget::on_ZoomOut);
+ connect(this->listViewWidget, &Widget::RomBrowserListViewWidget::FileDropped, this, &RomBrowserWidget::FileDropped);*/
+
+ // set up table widget's columns
+ QStringList labels;
+ labels << "Name";
+ labels << "Game";
+ labels << "Game MD5";
+ labels << "Password?";
+ this->tableWidget->setColumnCount(labels.size());
+ this->tableWidget->setHorizontalHeaderLabels(labels);
+
+ this->setCurrentWidget(this->loadingWidget);
+}
+
+NetplaySessionBrowserWidget::~NetplaySessionBrowserWidget()
+{
+}
+
+void NetplaySessionBrowserWidget::Reset(void)
+{
+ this->setCurrentWidget(this->emptyWidget);
+ this->tableWidget->model()->removeRows(0, this->tableWidget->rowCount());
+}
+
+void NetplaySessionBrowserWidget::StartRefresh(void)
+{
+ this->refreshTimer.start();
+ this->setCurrentWidget(this->loadingWidget);
+ this->tableWidget->model()->removeRows(0, this->tableWidget->rowCount());
+}
+
+void NetplaySessionBrowserWidget::AddSessionData(QString name, QString game, QString md5, bool password, int port,
+ QString cpuEmulator, QString rspPlugin, QString gfxPlugin)
+{
+ const NetplaySessionData sessionData =
+ {
+ name,
+ game,
+ md5,
+ password,
+ port,
+ cpuEmulator,
+ rspPlugin,
+ gfxPlugin
+ };
+
+ int row = this->tableWidget->rowCount();
+ this->tableWidget->insertRow(row);
+
+ // Session name
+ QTableWidgetItem* tableWidgetItem1 = new QTableWidgetItem(name);
+ tableWidgetItem1->setData(Qt::UserRole, QVariant::fromValue(sessionData));
+ this->tableWidget->setItem(row, 0, tableWidgetItem1);
+
+ // Game
+ QTableWidgetItem* tableWidgetItem2 = new QTableWidgetItem(game);
+ this->tableWidget->setItem(row, 1, tableWidgetItem2);
+
+ // MD5
+ QTableWidgetItem* tableWidgetItem3 = new QTableWidgetItem(md5);
+ this->tableWidget->setItem(row, 2, tableWidgetItem3);
+
+ // Password
+ QTableWidgetItem* tableWidgetItem4 = new QTableWidgetItem(password ? "Yes" : "No");
+ this->tableWidget->setItem(row, 3, tableWidgetItem4);
+}
+
+void NetplaySessionBrowserWidget::RefreshDone(void)
+{
+ if (this->tableWidget->rowCount() == 0)
+ {
+ this->setCurrentWidget(this->emptyWidget);
+ return;
+ }
+
+ // prevent flicker by forcing the loading screen
+ // to be shown at least 300ms
+ qint64 elapsedTime = this->refreshTimer.elapsed();
+ if (elapsedTime < 300)
+ {
+ this->startTimer(300 - elapsedTime);
+ return;
+ }
+
+ this->setCurrentWidget(this->tableWidget);
+}
+
+bool NetplaySessionBrowserWidget::IsCurrentSessionValid()
+{
+ return this->currentWidget() == this->tableWidget &&
+ this->tableWidget->currentItem() != nullptr;
+}
+
+bool NetplaySessionBrowserWidget::GetCurrentSession(NetplaySessionData& data)
+{
+ if (!this->IsCurrentSessionValid())
+ {
+ return false;
+ }
+
+ QTableWidgetItem* item = this->tableWidget->item(this->tableWidget->currentRow(), 0);
+ if (item == nullptr)
+ {
+ return false;
+ }
+
+ data = item->data(Qt::UserRole).value();
+ return true;
+}
+
+void NetplaySessionBrowserWidget::timerEvent(QTimerEvent *event)
+{
+ this->killTimer(event->timerId());
+ this->setCurrentWidget(this->tableWidget);
+}
+
+void NetplaySessionBrowserWidget::on_tableWidget_currentItemChanged(QTableWidgetItem* current, QTableWidgetItem* previous)
+{
+ if (this->currentWidget() == this->tableWidget)
+ {
+ emit this->OnSessionChanged(current != nullptr);
+ }
+}
diff --git a/Source/RMG/UserInterface/Widget/Netplay/NetplaySessionBrowserWidget.hpp b/Source/RMG/UserInterface/Widget/Netplay/NetplaySessionBrowserWidget.hpp
new file mode 100644
index 00000000..50af4370
--- /dev/null
+++ b/Source/RMG/UserInterface/Widget/Netplay/NetplaySessionBrowserWidget.hpp
@@ -0,0 +1,79 @@
+/*
+ * Rosalie's Mupen GUI - https://github.com/Rosalie241/RMG
+ * Copyright (C) 2020 Rosalie Wanders
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+#ifndef NETPLAYSESSIONBROWSERWIDGET_HPP
+#define NETPLAYSESSIONBROWSERWIDGET_HPP
+
+#include "NetplaySessionBrowserEmptyWidget.hpp"
+#include "NetplaySessionBrowserLoadingWidget.hpp"
+
+#include
+#include
+#include
+
+// session data
+struct NetplaySessionData
+{
+ QString SessionName;
+ QString GameName;
+ QString MD5;
+ bool PasswordProtected = false;
+ int Port = 0;
+ QString CpuEmulator;
+ QString RspPlugin;
+ QString GfxPlugin;
+};
+
+namespace UserInterface
+{
+namespace Widget
+{
+class NetplaySessionBrowserWidget : public QStackedWidget
+{
+ Q_OBJECT
+
+ public:
+ NetplaySessionBrowserWidget(QWidget *);
+ ~NetplaySessionBrowserWidget(void);
+
+ void Reset(void);
+
+ void StartRefresh(void);
+
+ void AddSessionData(QString name, QString game, QString md5, bool password, int port,
+ QString cpuEmulator, QString rspPlugin, QString gfxPlugin);
+
+ void RefreshDone(void);
+
+ bool IsCurrentSessionValid(void);
+ bool GetCurrentSession(NetplaySessionData& data);
+
+ private:
+ Widget::NetplaySessionBrowserEmptyWidget* emptyWidget = nullptr;
+ Widget::NetplaySessionBrowserLoadingWidget* loadingWidget = nullptr;
+
+ QTableWidget* tableWidget = nullptr;
+ QWidget* currentViewWidget = nullptr;
+
+ QElapsedTimer refreshTimer;
+
+ protected:
+ void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE;
+
+ private slots:
+ void on_tableWidget_currentItemChanged(QTableWidgetItem* current, QTableWidgetItem* previous);
+
+ signals:
+ void OnSessionChanged(bool valid);
+
+};
+} // namespace Widget
+} // namespace UserInterface
+
+#endif // NETPLAYSESSIONBROWSERWIDGET_HPP