mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-10 20:13:24 -08:00
The merged quick-host control composed a QPushButton and a separate autoRaise arrow QToolButton, which Fusion draws as two adjacent controls. Version one of the quick-host branch used a single QToolButton with MenuButtonPopup, which every style draws as one native split button. Use that split button on every style that can draw one, and keep the plain primary + settings button pair as the native macOS fallback.
299 lines
11 KiB
C++
299 lines
11 KiB
C++
#ifndef GAMESELECTOR_H
|
|
#define GAMESELECTOR_H
|
|
|
|
#include "game_type_map.h"
|
|
|
|
#include <QGroupBox>
|
|
#include <QTimer>
|
|
#include <qtmetamacros.h>
|
|
// IWYU pragma: keep
|
|
// ServerInfo_User appears by value and inside QList in slot signatures, so the
|
|
// moc-generated code needs the complete type.
|
|
#include <libcockatrice/protocol/pb/serverinfo_user.pb.h>
|
|
|
|
class QTreeView;
|
|
class GamesModel;
|
|
class GamesProxyModel;
|
|
class QLabel;
|
|
class QMenu;
|
|
class QPushButton;
|
|
class QToolButton;
|
|
class QAction;
|
|
class AbstractClient;
|
|
class TabSupervisor;
|
|
class TabRoom;
|
|
class ServerInfo_Game;
|
|
class Response;
|
|
class Event_AddToList;
|
|
class Event_RemoveFromList;
|
|
class GameSelectorQuickFilterToolBar;
|
|
class QModelIndex;
|
|
class QPoint;
|
|
class QString;
|
|
class QWidget;
|
|
class ServerInfo_User;
|
|
template <class Key, class T> class QMap;
|
|
template <typename T> class QList;
|
|
|
|
/**
|
|
* @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();
|
|
void checkClearFilterButtonState();
|
|
|
|
/**
|
|
* @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 Creates a game immediately from the remembered settings, without a dialog.
|
|
*/
|
|
void actQuickHost();
|
|
|
|
/**
|
|
* @brief Reports a failed quick-host request inline instead of as a modal box.
|
|
* @param response The server response to the create command.
|
|
*/
|
|
void checkQuickHostResponse(const Response &response);
|
|
|
|
/**
|
|
* @brief Joins the currently selected game as a player.
|
|
*/
|
|
void actJoin();
|
|
/**
|
|
* @brief Joins the currently selected game as a judge.
|
|
*/
|
|
void actJoinAsJudge();
|
|
|
|
/**
|
|
* @brief Joins the currently selected game as a spectator.
|
|
*/
|
|
void actJoinAsSpectator();
|
|
void actJoinAsJudgeSpectator();
|
|
|
|
/**
|
|
* @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);
|
|
|
|
protected:
|
|
/**
|
|
* @brief Rebuilds the host control when the application style changes.
|
|
*
|
|
* The appearance settings can switch between the native macOS style and a
|
|
* cross-platform style while the room is open, and the host control follows.
|
|
*/
|
|
void changeEvent(QEvent *event) override;
|
|
|
|
private:
|
|
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. */
|
|
|
|
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. */
|
|
QToolButton *hostGameSplitButton = nullptr; /**< Split host button, on every style that can draw one. */
|
|
QPushButton *hostGameButton = nullptr; /**< Primary quick-host button, on the native macOS style only. */
|
|
QPushButton *hostGameSettingsButton = nullptr; /**< Opens the host form; a sibling button on macOS. */
|
|
QMenu *hostGameMenu = nullptr; /**< Menu behind the split arrow (non-macOS styles only). */
|
|
QAction *hostGameAction = nullptr; /**< Quick-host action, carrying the keyboard shortcut. */
|
|
QAction *gameSettingsAction = nullptr; /**< Opens the host form with the current settings. */
|
|
QLabel *hostErrorLabel; /**< Inline failure message for a quick-host request. */
|
|
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. */
|
|
QPushButton *joinAsJudgeSpectatorButton; /**< Button to join the selected game as a spectating judge. */
|
|
|
|
const bool showFilters; /**< Determines whether filter buttons are displayed. */
|
|
GameTypeMap gameTypeMap; /**< Mapping of game types for the current room. */
|
|
|
|
QTimer filterSaveDebounceTimer; /**< Delays persisting quick-filter edits so typing does not rewrite the settings
|
|
file on every keystroke. */
|
|
|
|
bool hostCommandPending = false; /**< True while a quick-host command is in flight. */
|
|
bool joinCommandPending = false; /**< True while a join/spectate command is in flight. */
|
|
|
|
/** @brief Shows a quick-host failure above the game list. */
|
|
void showHostError(const QString &message);
|
|
/** @brief Hides the quick-host failure message. */
|
|
void clearHostError();
|
|
/**
|
|
* @brief Rebuilds the host control for the active style.
|
|
*
|
|
* The primary button always quick-hosts. Every style that can draw a split control
|
|
* gets one, whose arrow opens the menu; the native macOS style has no split control,
|
|
* so it gets a plain sibling button for the secondary action instead.
|
|
*/
|
|
void applyHostGameStyle();
|
|
/** @brief Marks a quick-host command as in flight or finished, then updates the host controls. */
|
|
void setHostCommandPending(bool pending);
|
|
/** @brief Applies the in-flight state of both host and join commands to the host controls. */
|
|
void updateHostControlsEnabled();
|
|
/** @brief Keeps the host control tooltips in sync with the current shortcut and style. */
|
|
void updateHostGameToolTip();
|
|
|
|
/**
|
|
* @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);
|
|
|
|
/**
|
|
* @brief Performs the join or spectate action for the currently selected game.
|
|
* @param asSpectator True to join as a spectator, false to join as a player.
|
|
* @param asJudge 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 asSpectator = false, bool asJudge = false);
|
|
|
|
/**
|
|
* @brief Performs the join or spectate action for a specific game.
|
|
* @param game The game to join.
|
|
* @param asSpectator True to join as a spectator, false to join as a player.
|
|
* @param asJudge True to join as a judge, false to join as a player.
|
|
*
|
|
* Unlike the selection-based overload, this does not depend on the game being
|
|
* visible in the filtered game list.
|
|
*/
|
|
void joinGame(const ServerInfo_Game &game, bool asSpectator = false, bool asJudge = 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,
|
|
const QMap<int, QString> &_rooms,
|
|
const QMap<int, GameTypeMap> &_gameTypes,
|
|
const bool restoresettings,
|
|
const bool _showfilters,
|
|
QWidget *parent = nullptr);
|
|
~GameSelector() override;
|
|
|
|
/**
|
|
* @brief Updates UI text for translation/localization.
|
|
*/
|
|
void retranslateUi();
|
|
|
|
/**
|
|
* @brief Re-reads the quick-host and review shortcuts after the user rebinds them.
|
|
*/
|
|
void refreshShortcuts();
|
|
|
|
/**
|
|
* @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);
|
|
/**
|
|
* @brief Finds a game by ID and joins or spectates it.
|
|
* @param gameId The ID of the game to join.
|
|
* @param asSpectator True to join as a spectator, false to join as a player.
|
|
* @return True if the game was found and joined, false otherwise.
|
|
*
|
|
* Unlike the selection-based overload, this does not depend on the game
|
|
* being visible in the filtered game list.
|
|
*/
|
|
bool joinGameById(int gameId, bool asSpectator = false);
|
|
};
|
|
|
|
#endif
|