mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-10 04:16:43 -07:00
Add button to join game as judge as well as convenience filters.
Took 1 hour 11 minutes
This commit is contained in:
parent
827f22ed37
commit
8022135d8c
6 changed files with 496 additions and 37 deletions
|
|
@ -180,6 +180,7 @@ set(cockatrice_SOURCES
|
|||
src/interface/widgets/replay/replay_timeline_widget.cpp
|
||||
src/interface/widgets/server/chat_view/chat_view.cpp
|
||||
src/interface/widgets/server/game_selector.cpp
|
||||
src/interface/widgets/server/game_selector_quick_filter_toolbar.cpp
|
||||
src/interface/widgets/server/games_model.cpp
|
||||
src/interface/widgets/server/handle_public_servers.cpp
|
||||
src/interface/widgets/server/remote/remote_decklist_tree_widget.cpp
|
||||
|
|
|
|||
|
|
@ -76,6 +76,8 @@ GameSelector::GameSelector(AbstractClient *_client,
|
|||
|
||||
gameListView->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
||||
|
||||
quickFilterToolBar = new GameSelectorQuickFilterToolBar(this, gameListProxyModel, gameTypeMap);
|
||||
|
||||
filterButton = new QPushButton;
|
||||
filterButton->setIcon(QPixmap("theme:icons/search"));
|
||||
connect(filterButton, &QPushButton::clicked, this, &GameSelector::actSetFilter);
|
||||
|
|
@ -92,6 +94,7 @@ GameSelector::GameSelector(AbstractClient *_client,
|
|||
createButton = nullptr;
|
||||
}
|
||||
joinButton = new QPushButton;
|
||||
joinAsJudgeButton = new QPushButton;
|
||||
spectateButton = new QPushButton;
|
||||
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
||||
|
|
@ -103,10 +106,17 @@ GameSelector::GameSelector(AbstractClient *_client,
|
|||
if (room)
|
||||
buttonLayout->addWidget(createButton);
|
||||
buttonLayout->addWidget(joinButton);
|
||||
if (tabSupervisor->getUserInfo()->user_level() & ServerInfo_User::IsJudge) {
|
||||
buttonLayout->addWidget(joinAsJudgeButton);
|
||||
} else {
|
||||
qInfo() << tabSupervisor->getUserInfo()->user_level();
|
||||
joinAsJudgeButton->setHidden(true);
|
||||
}
|
||||
buttonLayout->addWidget(spectateButton);
|
||||
buttonLayout->setAlignment(Qt::AlignTop);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(quickFilterToolBar);
|
||||
mainLayout->addWidget(gameListView);
|
||||
mainLayout->addLayout(buttonLayout);
|
||||
|
||||
|
|
@ -117,10 +127,11 @@ GameSelector::GameSelector(AbstractClient *_client,
|
|||
setMinimumHeight(200);
|
||||
|
||||
connect(joinButton, &QPushButton::clicked, this, &GameSelector::actJoin);
|
||||
connect(joinAsJudgeButton, &QPushButton::clicked, this, &GameSelector::actJoinAsJudge);
|
||||
connect(spectateButton, &QPushButton::clicked, this, &GameSelector::actSpectate);
|
||||
connect(gameListView->selectionModel(), &QItemSelectionModel::currentRowChanged, this,
|
||||
&GameSelector::actSelectedGameChanged);
|
||||
connect(gameListView, &QTreeView::activated, this, &GameSelector::actJoin);
|
||||
connect(gameListView, &QTreeView::activated, this, &GameSelector::actJoinAsPlayerOrJudge);
|
||||
|
||||
connect(client, &AbstractClient::ignoreListReceived, this, &GameSelector::ignoreListReceived);
|
||||
connect(client, &AbstractClient::addToListEventReceived, this, &GameSelector::processAddToListEvent);
|
||||
|
|
@ -238,7 +249,20 @@ void GameSelector::checkResponse(const Response &response)
|
|||
|
||||
void GameSelector::actJoin()
|
||||
{
|
||||
return joinGame(false);
|
||||
return joinGame();
|
||||
}
|
||||
|
||||
void GameSelector::actJoinAsJudge()
|
||||
{
|
||||
return joinGame(false, true);
|
||||
}
|
||||
|
||||
void GameSelector::actJoinAsPlayerOrJudge()
|
||||
{
|
||||
if (!(tabSupervisor->getUserInfo()->user_level() & ServerInfo_User::IsJudge)) {
|
||||
return joinGame();
|
||||
}
|
||||
return joinGame(false, (QApplication::keyboardModifiers() & Qt::ShiftModifier) != 0);
|
||||
}
|
||||
|
||||
void GameSelector::actSpectate()
|
||||
|
|
@ -270,12 +294,20 @@ void GameSelector::customContextMenu(const QPoint &point)
|
|||
|
||||
QMenu menu;
|
||||
menu.addAction(&joinGame);
|
||||
|
||||
if (tabSupervisor->getUserInfo()->user_level() & ServerInfo_User::IsJudge) {
|
||||
QAction joinGameAsJudge(tr("Join Game as Judge"));
|
||||
connect(&joinGameAsJudge, &QAction::triggered, this, &GameSelector::actJoinAsJudge);
|
||||
|
||||
menu.addAction(&joinGameAsJudge);
|
||||
}
|
||||
|
||||
menu.addAction(&spectateGame);
|
||||
menu.addAction(&getGameInfo);
|
||||
menu.exec(gameListView->mapToGlobal(point));
|
||||
}
|
||||
|
||||
void GameSelector::joinGame(const bool isSpectator)
|
||||
void GameSelector::joinGame(const bool isSpectator, const bool isJudge)
|
||||
{
|
||||
QModelIndex ind = gameListView->currentIndex();
|
||||
if (!ind.isValid()) {
|
||||
|
|
@ -304,7 +336,7 @@ void GameSelector::joinGame(const bool isSpectator)
|
|||
cmd.set_password(password.toStdString());
|
||||
cmd.set_spectator(spectator);
|
||||
cmd.set_override_restrictions(overrideRestrictions);
|
||||
cmd.set_join_as_judge((QApplication::keyboardModifiers() & Qt::ShiftModifier) != 0);
|
||||
cmd.set_join_as_judge(isJudge);
|
||||
|
||||
TabRoom *r = tabSupervisor->getRoomTabs().value(game.room_id());
|
||||
if (!r) {
|
||||
|
|
@ -356,6 +388,7 @@ void GameSelector::retranslateUi()
|
|||
if (createButton)
|
||||
createButton->setText(tr("C&reate"));
|
||||
joinButton->setText(tr("&Join"));
|
||||
joinAsJudgeButton->setText(tr("Join as judge"));
|
||||
spectateButton->setText(tr("J&oin as spectator"));
|
||||
|
||||
updateTitle();
|
||||
|
|
|
|||
|
|
@ -1,12 +1,7 @@
|
|||
/**
|
||||
* @file game_selector.h
|
||||
* @ingroup Lobby
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef GAMESELECTOR_H
|
||||
#define GAMESELECTOR_H
|
||||
|
||||
#include "game_selector_quick_filter_toolbar.h"
|
||||
#include "game_type_map.h"
|
||||
|
||||
#include <QGroupBox>
|
||||
|
|
@ -26,46 +21,163 @@ class TabRoom;
|
|||
class ServerInfo_Game;
|
||||
class Response;
|
||||
|
||||
/**
|
||||
* @class GameSelector
|
||||
* @ingroup Lobby
|
||||
* @brief Provides a widget for displaying, filtering, joining, spectating, and creating games in a room.
|
||||
*
|
||||
* The GameSelector displays all available games in a QTreeView. It supports filtering,
|
||||
* creating, joining, spectating, and viewing game details. Integrates with TabSupervisor
|
||||
* and TabRoom for room and game management.
|
||||
*/
|
||||
class GameSelector : public QGroupBox
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
/**
|
||||
* @brief Opens a dialog to set filters for the game list.
|
||||
*
|
||||
* Updates the proxy model with selected filter parameters and refreshes the displayed game list.
|
||||
*/
|
||||
void actSetFilter();
|
||||
|
||||
/**
|
||||
* @brief Clears all filters applied to the game list.
|
||||
*
|
||||
* Resets the proxy model to show all games.
|
||||
*/
|
||||
void actClearFilter();
|
||||
|
||||
/**
|
||||
* @brief Opens the dialog to create a new game in the current room.
|
||||
*/
|
||||
void actCreate();
|
||||
|
||||
/**
|
||||
* @brief Joins the currently selected game as a player.
|
||||
*/
|
||||
void actJoin();
|
||||
void actJoinAsJudge();
|
||||
void actJoinAsPlayerOrJudge();
|
||||
|
||||
/**
|
||||
* @brief Joins the currently selected game as a spectator.
|
||||
*/
|
||||
void actSpectate();
|
||||
|
||||
/**
|
||||
* @brief Shows the custom context menu for a game when right-clicked.
|
||||
* @param point The point at which the context menu is requested.
|
||||
*/
|
||||
void customContextMenu(const QPoint &point);
|
||||
|
||||
/**
|
||||
* @brief Slot called when the selected game changes.
|
||||
* @param current The currently selected index.
|
||||
* @param previous The previously selected index.
|
||||
*
|
||||
* Updates the enabled/disabled state of buttons depending on the selected game.
|
||||
*/
|
||||
void actSelectedGameChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
|
||||
/**
|
||||
* @brief Processes server responses for join or spectate commands.
|
||||
* @param response The response from the server.
|
||||
*
|
||||
* Displays error messages for failed join/spectate attempts.
|
||||
*/
|
||||
void checkResponse(const Response &response);
|
||||
|
||||
/**
|
||||
* @brief Refreshes the game list when the ignore list is received from the server.
|
||||
* @param _ignoreList The list of users being ignored.
|
||||
*/
|
||||
void ignoreListReceived(const QList<ServerInfo_User> &_ignoreList);
|
||||
|
||||
/**
|
||||
* @brief Processes events where a user is added to a list (e.g., ignore or buddy).
|
||||
* @param event The event information.
|
||||
*/
|
||||
void processAddToListEvent(const Event_AddToList &event);
|
||||
|
||||
/**
|
||||
* @brief Processes events where a user is removed from a list (e.g., ignore or buddy).
|
||||
* @param event The event information.
|
||||
*/
|
||||
void processRemoveFromListEvent(const Event_RemoveFromList &event);
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief Emitted when a game has been successfully joined.
|
||||
* @param gameId The ID of the joined game.
|
||||
*/
|
||||
void gameJoined(int gameId);
|
||||
|
||||
private:
|
||||
AbstractClient *client;
|
||||
TabSupervisor *tabSupervisor;
|
||||
TabRoom *room;
|
||||
AbstractClient *client; /**< The network client used to communicate with the server. */
|
||||
TabSupervisor *tabSupervisor; /**< Reference to TabSupervisor for managing tabs and rooms. */
|
||||
TabRoom *room; /**< The current room; nullptr if no room is selected. */
|
||||
|
||||
QTreeView *gameListView;
|
||||
GamesModel *gameListModel;
|
||||
GamesProxyModel *gameListProxyModel;
|
||||
QPushButton *filterButton, *clearFilterButton, *createButton, *joinButton, *spectateButton;
|
||||
const bool showFilters;
|
||||
GameTypeMap gameTypeMap;
|
||||
QTreeView *gameListView; /**< View widget for displaying the game list. */
|
||||
GamesModel *gameListModel; /**< Model containing all games. */
|
||||
GamesProxyModel *gameListProxyModel; /**< Proxy model for filtering and sorting the game list. */
|
||||
|
||||
GameSelectorQuickFilterToolBar *quickFilterToolBar;
|
||||
|
||||
QPushButton *filterButton; /**< Button to open the filter dialog. */
|
||||
QPushButton *clearFilterButton; /**< Button to clear active filters. */
|
||||
QPushButton *createButton; /**< Button to create a new game (only if room is set). */
|
||||
QPushButton *joinButton; /**< Button to join the selected game. */
|
||||
QPushButton *joinAsJudgeButton; /**< Button to join the selected game as a judge. */
|
||||
QPushButton *spectateButton; /**< Button to spectate the selected game. */
|
||||
|
||||
const bool showFilters; /**< Determines whether filter buttons are displayed. */
|
||||
GameTypeMap gameTypeMap; /**< Mapping of game types for the current room. */
|
||||
|
||||
/**
|
||||
* @brief Updates the widget title to reflect the current number of displayed games.
|
||||
*
|
||||
* Shows the number of visible games versus total games if filters are enabled.
|
||||
*/
|
||||
void updateTitle();
|
||||
|
||||
/**
|
||||
* @brief Disables create/join/spectate buttons.
|
||||
*/
|
||||
void disableButtons();
|
||||
|
||||
/**
|
||||
* @brief Enables buttons for the currently selected game.
|
||||
*/
|
||||
void enableButtons();
|
||||
|
||||
/**
|
||||
* @brief Enables buttons for a specific game index.
|
||||
* @param current The index of the currently selected game.
|
||||
*/
|
||||
void enableButtonsForIndex(const QModelIndex ¤t);
|
||||
void joinGame(const bool isSpectator);
|
||||
|
||||
/**
|
||||
* @brief Performs the join or spectate action for the currently selected game.
|
||||
* @param isSpectator True to join as a spectator, false to join as a player.
|
||||
* @param isJudge True to join as a judge, false to join as a player.
|
||||
*
|
||||
* Handles password prompts, overrides, and sending the join command to the server.
|
||||
*/
|
||||
void joinGame(bool isSpectator = false, bool isJudge = false);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Constructs a GameSelector widget.
|
||||
* @param _client The network client used to communicate with the server.
|
||||
* @param _tabSupervisor Reference to TabSupervisor for managing tabs and rooms.
|
||||
* @param _room Pointer to the current room; nullptr if no room is selected.
|
||||
* @param _rooms Map of room IDs to room names.
|
||||
* @param _gameTypes Map of room IDs to their available game types.
|
||||
* @param restoresettings Whether to restore filter settings from previous sessions.
|
||||
* @param _showfilters Whether to display filter buttons.
|
||||
* @param parent Parent QWidget.
|
||||
*/
|
||||
GameSelector(AbstractClient *_client,
|
||||
TabSupervisor *_tabSupervisor,
|
||||
TabRoom *_room,
|
||||
|
|
@ -74,7 +186,16 @@ public:
|
|||
const bool restoresettings,
|
||||
const bool _showfilters,
|
||||
QWidget *parent = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Updates UI text for translation/localization.
|
||||
*/
|
||||
void retranslateUi();
|
||||
|
||||
/**
|
||||
* @brief Updates or adds a game entry in the list.
|
||||
* @param info The ServerInfo_Game object containing information about the game to update.
|
||||
*/
|
||||
void processGameInfo(const ServerInfo_Game &info);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,100 @@
|
|||
#include "game_selector_quick_filter_toolbar.h"
|
||||
|
||||
#include "games_model.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
|
||||
GameSelectorQuickFilterToolBar::GameSelectorQuickFilterToolBar(QWidget *parent,
|
||||
GamesProxyModel *_model,
|
||||
const QMap<int, QString> &allGameTypes)
|
||||
: QWidget(parent), model(_model)
|
||||
{
|
||||
mainLayout = new QHBoxLayout(this);
|
||||
|
||||
searchBar = new QLineEdit(this);
|
||||
searchBar->setText(model->getCreatorNameFilter());
|
||||
connect(searchBar, &QLineEdit::textChanged, this,
|
||||
[this](const QString &text) { model->setCreatorNameFilter(text); });
|
||||
|
||||
hideGamesWithoutBuddiesCheckBox = new QCheckBox(this);
|
||||
hideGamesWithoutBuddiesCheckBox->setChecked(model->getHideBuddiesOnlyGames());
|
||||
hideGamesWithoutBuddiesLabel = new QLabel(this);
|
||||
hideGamesWithoutBuddiesLabel->setBuddy(hideGamesWithoutBuddiesCheckBox);
|
||||
connect(hideGamesWithoutBuddiesCheckBox, &QCheckBox::toggled, this,
|
||||
[this](bool checked) { model->setHideBuddiesOnlyGames(checked); });
|
||||
|
||||
hideFullGamesCheckBox = new QCheckBox(this);
|
||||
hideFullGamesCheckBox->setChecked(model->getHideFullGames());
|
||||
hideFullGamesLabel = new QLabel(this);
|
||||
hideFullGamesLabel->setBuddy(hideFullGamesCheckBox);
|
||||
connect(hideFullGamesCheckBox, &QCheckBox::toggled, this,
|
||||
[this](bool checked) { model->setHideFullGames(checked); });
|
||||
|
||||
hideStartedGamesCheckBox = new QCheckBox(this);
|
||||
hideStartedGamesCheckBox->setChecked(model->getHideGamesThatStarted());
|
||||
hideStartedGamesLabel = new QLabel(this);
|
||||
hideStartedGamesLabel->setBuddy(hideStartedGamesCheckBox);
|
||||
connect(hideStartedGamesCheckBox, &QCheckBox::toggled, this,
|
||||
[this](bool checked) { model->setHideGamesThatStarted(checked); });
|
||||
|
||||
filterToFormatComboBox = new QComboBox(this);
|
||||
filterToFormatLabel = new QLabel(this);
|
||||
filterToFormatLabel->setBuddy(filterToFormatComboBox);
|
||||
|
||||
// Add a "No filter" / "All types" option first
|
||||
filterToFormatComboBox->addItem(tr("All types"), QVariant()); // empty QVariant = no filter
|
||||
|
||||
QMapIterator<int, QString> i(allGameTypes);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
filterToFormatComboBox->addItem(i.value(), i.key()); // text = name, data = type ID
|
||||
}
|
||||
|
||||
QSet<int> currentTypes = model->getGameTypeFilter();
|
||||
if (currentTypes.size() == 1) {
|
||||
int typeId = *currentTypes.begin();
|
||||
int index = filterToFormatComboBox->findData(typeId);
|
||||
if (index >= 0)
|
||||
filterToFormatComboBox->setCurrentIndex(index);
|
||||
} else {
|
||||
filterToFormatComboBox->setCurrentIndex(0); // "All types" by default
|
||||
}
|
||||
|
||||
// Update proxy model on selection change
|
||||
connect(filterToFormatComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [this](int index) {
|
||||
QVariant data = filterToFormatComboBox->itemData(index);
|
||||
if (!data.isValid()) {
|
||||
model->setGameTypeFilter({}); // empty = no filter
|
||||
} else {
|
||||
int typeId = data.toInt();
|
||||
model->setGameTypeFilter({typeId});
|
||||
}
|
||||
});
|
||||
|
||||
mainLayout->addWidget(searchBar);
|
||||
mainLayout->addWidget(hideGamesWithoutBuddiesLabel);
|
||||
mainLayout->addWidget(hideGamesWithoutBuddiesCheckBox);
|
||||
mainLayout->addWidget(hideFullGamesLabel);
|
||||
mainLayout->addWidget(hideFullGamesCheckBox);
|
||||
mainLayout->addWidget(hideStartedGamesLabel);
|
||||
mainLayout->addWidget(hideStartedGamesCheckBox);
|
||||
mainLayout->addWidget(filterToFormatLabel);
|
||||
mainLayout->addWidget(filterToFormatComboBox);
|
||||
|
||||
setLayout(mainLayout);
|
||||
|
||||
retranslateUi();
|
||||
}
|
||||
|
||||
void GameSelectorQuickFilterToolBar::retranslateUi()
|
||||
{
|
||||
searchBar->setPlaceholderText(tr("Filter by creator name..."));
|
||||
hideGamesWithoutBuddiesLabel->setText(tr("Hide buddies only games"));
|
||||
hideFullGamesLabel->setText(tr("Hide full games"));
|
||||
hideStartedGamesLabel->setText(tr("Hide started games"));
|
||||
filterToFormatLabel->setText(tr("Filter to format"));
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef COCKATRICE_GAME_SELECTOR_QUICK_FILTER_TOOLBAR_H
|
||||
#define COCKATRICE_GAME_SELECTOR_QUICK_FILTER_TOOLBAR_H
|
||||
#include "games_model.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QWidget>
|
||||
|
||||
class GameSelectorQuickFilterToolBar : public QWidget
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GameSelectorQuickFilterToolBar(QWidget *parent,
|
||||
GamesProxyModel *model,
|
||||
const QMap<int, QString> &allGameTypes);
|
||||
void retranslateUi();
|
||||
|
||||
private:
|
||||
GamesProxyModel *model;
|
||||
|
||||
QHBoxLayout *mainLayout;
|
||||
|
||||
QLineEdit *searchBar;
|
||||
QCheckBox *hideGamesWithoutBuddiesCheckBox;
|
||||
QLabel *hideGamesWithoutBuddiesLabel;
|
||||
QCheckBox *hideFullGamesCheckBox;
|
||||
QLabel *hideFullGamesLabel;
|
||||
QCheckBox *hideStartedGamesCheckBox;
|
||||
QLabel *hideStartedGamesLabel;
|
||||
QComboBox *filterToFormatComboBox;
|
||||
QLabel *filterToFormatLabel;
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_GAME_SELECTOR_QUICK_FILTER_TOOLBAR_H
|
||||
|
|
@ -1,9 +1,3 @@
|
|||
/**
|
||||
* @file games_model.h
|
||||
* @ingroup Lobby
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef GAMESMODEL_H
|
||||
#define GAMESMODEL_H
|
||||
|
||||
|
|
@ -19,60 +13,107 @@
|
|||
|
||||
class UserListProxy;
|
||||
|
||||
/**
|
||||
* @class GamesModel
|
||||
* @ingroup Lobby
|
||||
* @brief Model storing all available games for display in a QTreeView or QTableView.
|
||||
*
|
||||
* Provides access to game information, supports sorting by different columns,
|
||||
* and updates when new game data is received from the server.
|
||||
*/
|
||||
class GamesModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QList<ServerInfo_Game> gameList;
|
||||
QMap<int, QString> rooms;
|
||||
QMap<int, GameTypeMap> gameTypes;
|
||||
QList<ServerInfo_Game> gameList; /**< List of games currently displayed. */
|
||||
QMap<int, QString> rooms; /**< Map of room IDs to room names. */
|
||||
QMap<int, GameTypeMap> gameTypes; /**< Map of room IDs to available game types. */
|
||||
|
||||
static const int NUM_COLS = 8;
|
||||
static const int NUM_COLS = 8; /**< Number of columns in the table. */
|
||||
|
||||
public:
|
||||
static const int SORT_ROLE = Qt::UserRole + 1;
|
||||
static const int SORT_ROLE = Qt::UserRole + 1; /**< Role used for sorting. */
|
||||
|
||||
/**
|
||||
* @brief Constructs a GamesModel.
|
||||
* @param _rooms Mapping of room IDs to room names.
|
||||
* @param _gameTypes Mapping of room IDs to their available game types.
|
||||
* @param parent Parent QObject.
|
||||
*/
|
||||
GamesModel(const QMap<int, QString> &_rooms, const QMap<int, GameTypeMap> &_gameTypes, QObject *parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override
|
||||
{
|
||||
return parent.isValid() ? 0 : gameList.size();
|
||||
}
|
||||
|
||||
int columnCount(const QModelIndex & /*parent*/ = QModelIndex()) const override
|
||||
{
|
||||
return NUM_COLS;
|
||||
}
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
|
||||
/**
|
||||
* @brief Formats the game creation time into a human-readable string.
|
||||
* @param secs Number of seconds since the game started.
|
||||
* @return Short string representing game age (e.g., "new", ">5 min", ">2 hr").
|
||||
*/
|
||||
static const QString getGameCreatedString(const int secs);
|
||||
|
||||
/**
|
||||
* @brief Returns a reference to a specific game by row index.
|
||||
* @param row Row index in the table.
|
||||
* @return Reference to the ServerInfo_Game at the given row.
|
||||
*/
|
||||
const ServerInfo_Game &getGame(int row);
|
||||
|
||||
/**
|
||||
* Update game list with a (possibly new) game.
|
||||
* @brief Updates the game list with a new or updated game.
|
||||
* @param game The ServerInfo_Game object to add or update.
|
||||
*/
|
||||
void updateGameList(const ServerInfo_Game &game);
|
||||
|
||||
/**
|
||||
* @brief Returns the index of the room column.
|
||||
*/
|
||||
int roomColIndex()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the index of the start time column.
|
||||
*/
|
||||
int startTimeColIndex()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the map of game types per room.
|
||||
*/
|
||||
const QMap<int, GameTypeMap> &getGameTypes()
|
||||
{
|
||||
return gameTypes;
|
||||
}
|
||||
};
|
||||
|
||||
class ServerInfo_User;
|
||||
|
||||
/**
|
||||
* @class GamesProxyModel
|
||||
* @ingroup Lobby
|
||||
* @brief Proxy model for filtering and sorting the GamesModel based on user preferences.
|
||||
*
|
||||
* Supports filtering games based on buddies-only, ignored users, password protection,
|
||||
* game types, creator, age, player count, and spectator permissions.
|
||||
*/
|
||||
class GamesProxyModel : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
const UserListProxy *userListProxy;
|
||||
const UserListProxy *userListProxy; /**< Proxy for checking user ignore/buddy lists. */
|
||||
|
||||
// If adding any additional filters, make sure to update:
|
||||
// - GamesProxyModel()
|
||||
|
|
@ -92,12 +133,20 @@ private:
|
|||
QSet<int> gameTypeFilter;
|
||||
quint32 maxPlayersFilterMin, maxPlayersFilterMax;
|
||||
QTime maxGameAge;
|
||||
bool showOnlyIfSpectatorsCanWatch, showSpectatorPasswordProtected, showOnlyIfSpectatorsCanChat,
|
||||
showOnlyIfSpectatorsCanSeeHands;
|
||||
bool showOnlyIfSpectatorsCanWatch;
|
||||
bool showSpectatorPasswordProtected;
|
||||
bool showOnlyIfSpectatorsCanChat;
|
||||
bool showOnlyIfSpectatorsCanSeeHands;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Constructs a GamesProxyModel.
|
||||
* @param parent Parent QObject.
|
||||
* @param _userListProxy Proxy for accessing ignore/buddy lists.
|
||||
*/
|
||||
explicit GamesProxyModel(QObject *parent = nullptr, const UserListProxy *_userListProxy = nullptr);
|
||||
|
||||
// Getters for filter parameters
|
||||
bool getHideBuddiesOnlyGames() const
|
||||
{
|
||||
return hideBuddiesOnlyGames;
|
||||
|
|
@ -166,6 +215,10 @@ public:
|
|||
{
|
||||
return showOnlyIfSpectatorsCanSeeHands;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets all game filters at once.
|
||||
*/
|
||||
void setGameFilters(bool _hideBuddiesOnlyGames,
|
||||
bool _hideIgnoredUserGames,
|
||||
bool _hideFullGames,
|
||||
|
|
@ -184,11 +237,123 @@ public:
|
|||
bool _showOnlyIfSpectatorsCanChat,
|
||||
bool _showOnlyIfSpectatorsCanSeeHands);
|
||||
|
||||
// Individual setters
|
||||
void setHideBuddiesOnlyGames(bool value)
|
||||
{
|
||||
hideBuddiesOnlyGames = value;
|
||||
refresh();
|
||||
}
|
||||
void setHideIgnoredUserGames(bool value)
|
||||
{
|
||||
hideIgnoredUserGames = value;
|
||||
refresh();
|
||||
}
|
||||
void setHideFullGames(bool value)
|
||||
{
|
||||
hideFullGames = value;
|
||||
refresh();
|
||||
}
|
||||
void setHideGamesThatStarted(bool value)
|
||||
{
|
||||
hideGamesThatStarted = value;
|
||||
refresh();
|
||||
}
|
||||
void setHidePasswordProtectedGames(bool value)
|
||||
{
|
||||
hidePasswordProtectedGames = value;
|
||||
refresh();
|
||||
}
|
||||
void setHideNotBuddyCreatedGames(bool value)
|
||||
{
|
||||
hideNotBuddyCreatedGames = value;
|
||||
refresh();
|
||||
}
|
||||
void setHideOpenDecklistGames(bool value)
|
||||
{
|
||||
hideOpenDecklistGames = value;
|
||||
refresh();
|
||||
}
|
||||
void setGameNameFilter(const QString &value)
|
||||
{
|
||||
gameNameFilter = value;
|
||||
refresh();
|
||||
}
|
||||
void setCreatorNameFilter(const QString &value)
|
||||
{
|
||||
creatorNameFilter = value;
|
||||
refresh();
|
||||
}
|
||||
void setGameTypeFilter(const QSet<int> &value)
|
||||
{
|
||||
gameTypeFilter = value;
|
||||
refresh();
|
||||
}
|
||||
void setMaxPlayersFilterMin(int value)
|
||||
{
|
||||
maxPlayersFilterMin = value;
|
||||
refresh();
|
||||
}
|
||||
void setMaxPlayersFilterMax(int value)
|
||||
{
|
||||
maxPlayersFilterMax = value;
|
||||
refresh();
|
||||
}
|
||||
void setMaxGameAge(const QTime &value)
|
||||
{
|
||||
maxGameAge = value;
|
||||
refresh();
|
||||
}
|
||||
void setShowOnlyIfSpectatorsCanWatch(bool value)
|
||||
{
|
||||
showOnlyIfSpectatorsCanWatch = value;
|
||||
refresh();
|
||||
}
|
||||
void setShowSpectatorPasswordProtected(bool value)
|
||||
{
|
||||
showSpectatorPasswordProtected = value;
|
||||
refresh();
|
||||
}
|
||||
void setShowOnlyIfSpectatorsCanChat(bool value)
|
||||
{
|
||||
showOnlyIfSpectatorsCanChat = value;
|
||||
refresh();
|
||||
}
|
||||
void setShowOnlyIfSpectatorsCanSeeHands(bool value)
|
||||
{
|
||||
showOnlyIfSpectatorsCanSeeHands = value;
|
||||
refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the number of games filtered out by the current filter.
|
||||
*/
|
||||
int getNumFilteredGames() const;
|
||||
|
||||
/**
|
||||
* @brief Resets all filter parameters to default values.
|
||||
*/
|
||||
void resetFilterParameters();
|
||||
|
||||
/**
|
||||
* @brief Returns true if all filter parameters are set to their defaults.
|
||||
*/
|
||||
bool areFilterParametersSetToDefaults() const;
|
||||
|
||||
/**
|
||||
* @brief Loads filter parameters from persistent settings.
|
||||
* @param allGameTypes Mapping of all game types by room ID.
|
||||
*/
|
||||
void loadFilterParameters(const QMap<int, QString> &allGameTypes);
|
||||
|
||||
/**
|
||||
* @brief Saves filter parameters to persistent settings.
|
||||
* @param allGameTypes Mapping of all game types by room ID.
|
||||
*/
|
||||
void saveFilterParameters(const QMap<int, QString> &allGameTypes);
|
||||
|
||||
/**
|
||||
* @brief Refreshes the proxy model (re-applies filters).
|
||||
*/
|
||||
void refresh();
|
||||
|
||||
protected:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue