Cockatrice/cockatrice/src/interface/widgets/tabs/tab_game.h
Lukas Brübach 17a1f8cf78 [Client] Add shuffle players option and turn order dialog
Adds the 'Shuffle players at start' checkbox to game creation and a
host-only 'Set turn order...' action that opens a dialog to reorder or
randomize the seats before the game starts. Seating changes are shown in
the game's message log.
2026-11-02 23:58:53 +01:00

227 lines
6.8 KiB
C++

/**
* @file tab_game.h
* @ingroup Tabs
* @ingroup GameWidgets
* @ingroup Lobby
*/
//! \todo Document this file.
#ifndef TAB_GAME_H
#define TAB_GAME_H
#include "tab.h"
#include <QList>
#include <QLoggingCategory>
#include <QMap>
#include <QPair>
#include <QSize>
#include <QString>
#include <QStringList>
#include <QVector>
#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 CardMenu;
class TabbedDeckViewContainer;
class AbstractGame;
class Event_GameJoined;
class GameEventContext;
class MessageLogWidget;
class PlayerLogic;
class QAction;
class QCompleter;
class QStringListModel;
class QWidget;
class ServerInfo_Player;
class ServerInfo_User;
class TabSupervisor;
class TearOffMenu;
struct CardRef;
struct LoadedDeck;
inline Q_LOGGING_CATEGORY(TabGameLog, "tab_game");
class UserListProxy;
class AbstractClient;
class GameView;
class GameScene;
class ReplayWidget;
class CardInfoFrameWidget;
class QLabel;
class QPushButton;
class QMenu;
class PhasesToolbar;
class PlayerListWidget;
class AbstractCardItem;
class QVBoxLayout;
class GameReplay;
class LineEditCompleter;
class QDockWidget;
class QStackedWidget;
class TabGame : public Tab
{
Q_OBJECT
private:
AbstractGame *game;
const UserListProxy *userListProxy;
ReplayWidget *replayWidget = nullptr;
QStringList gameTypes;
QCompleter *mentionCompleter;
QStringListModel *mentionModel;
QStringList autocompleteUserList;
QStackedWidget *mainWidget;
CardInfoFrameWidget *cardInfoFrameWidget;
PlayerListWidget *playerListWidget;
QPushButton *inviteButton = nullptr;
QLabel *timeElapsedLabel;
MessageLogWidget *messageLog;
QLabel *sayLabel;
LineEditCompleter *sayEdit;
PhasesToolbar *phasesToolbar;
GameScene *scene;
GameView *gameView;
QMap<int, TabbedDeckViewContainer *> deckViewContainers;
QVBoxLayout *deckViewContainerLayout;
QWidget *gamePlayAreaWidget, *deckViewContainerWidget;
QDockWidget *cardInfoDock, *messageLayoutDock, *playerListDock, *replayDock;
QAction *playersSeparator;
QMenu *gameMenu, *viewMenu;
TearOffMenu *phasesMenu;
QAction *aGameInfo, *aConcede, *aCopyGameLink, *aLeaveGame, *aNextPhase, *aNextPhaseAction, *aNextTurn,
*aReverseTurn, *aTurnOrder, *aRemoveLocalArrows, *aRotateViewCW, *aRotateViewCCW, *aResetLayout,
*aResetReplayLayout;
QAction *aFocusChat;
QAction *aInviteToGame = nullptr;
QList<QAction *> phaseActions;
QAction *aCardMenu;
/**
* @brief The actions associated with managing a QDockWidget
*/
struct DockActions
{
QMenu *menu;
QAction *aVisible;
QAction *aFloating;
QSize defaultSize;
};
QMap<QDockWidget *, DockActions> dockToActions;
PlayerLogic *addPlayer(PlayerLogic *newPlayer);
void addLocalPlayer(PlayerLogic *newPlayer, int playerId);
void processRemotePlayerDeckSelect(QString deckList, int playerId, QString playerName);
void processMultipleRemotePlayerDeckSelect(QVector<QPair<int, QPair<QString, QString>>> playerIdDeckMap);
void processLocalPlayerDeckSelect(PlayerLogic *localPlayer, int playerId, ServerInfo_Player playerInfo);
void loadDeckForLocalPlayer(PlayerLogic *localPlayer, int playerId, ServerInfo_Player playerInfo);
void processLocalPlayerReady(int playerId, ServerInfo_Player playerInfo);
void createZoneForPlayer(PlayerLogic *newPlayer, int playerId);
void startGame(bool resuming);
void stopGame();
void closeGame();
bool leaveGame();
PlayerLogic *setActivePlayer(int id);
void setActivePhase(int phase);
void createMenuItems();
void createReplayMenuItems();
void createViewMenuItems();
void registerDockWidget(QMenu *_viewMenu, QDockWidget *widget, const QSize &defaultSize);
void createCardInfoDock(bool bReplay = false);
void createPlayerListDock(bool bReplay = false);
void createMessageDock(bool bReplay = false);
void createPlayAreaWidget(bool bReplay = false);
void createDeckViewContainerWidget(bool bReplay = false);
void createReplayDock(GameReplay *replay);
void updateInviteButtonState();
signals:
void gameClosing(TabGame *tab);
void containerProcessingStarted(const GameEventContext &context);
void containerProcessingDone();
void openMessageDialog(const QString &userName, bool focus);
void openDeckEditor(const LoadedDeck &deck);
void notIdle();
void phaseChanged(int phase);
void gameLeft();
void chatMessageSent(QString chatMessage);
void turnAdvanced();
private slots:
void adminLockChanged(bool lock);
void newCardAdded(AbstractCardItem *card);
void setCardMenu(CardMenu *menu);
void actGameInfo();
void actInviteToGame();
void actConcede();
void actCopyGameLink();
void actTurnOrder();
void actRemoveLocalArrows();
void actRotateViewCW();
void actRotateViewCCW();
void actSay();
void actPhaseAction();
void actNextPhase();
void actNextPhaseAction();
void addMentionTag(const QString &value);
void linkCardToChat(const QString &cardName);
void refreshShortcuts();
void loadLayout();
void actCompleterChanged();
void notifyPlayerJoin(QString playerName);
void notifyPlayerKicked();
void processPlayerLeave(PlayerLogic *leavingPlayer);
void actResetLayout();
void hideEvent(QHideEvent *event) override;
protected slots:
void closeEvent(QCloseEvent *event) override;
public:
TabGame(TabSupervisor *_tabSupervisor,
QList<AbstractClient *> &_clients,
const Event_GameJoined &event,
const QMap<int, QString> &_roomGameTypes);
void connectToGameState();
void connectToPlayerManager();
void connectToGameEventHandler();
void connectMessageLogToGameEventHandler();
void connectPlayerListToGameEventHandler();
TabGame(TabSupervisor *_tabSupervisor, GameReplay *replay);
~TabGame() override;
void retranslateUi() override;
void updatePlayerListDockTitle();
bool closeRequest() override;
[[nodiscard]] QString getTabText() const override;
[[nodiscard]] AbstractGame *getGame() const
{
return game;
}
public slots:
void viewCardInfo(const CardRef &cardRef = {}) const;
void resetForRewind();
void updateTimeElapsedLabel(QString newTime);
void addPlayerToAutoCompleteList(QString playerName);
void removePlayerFromAutoCompleteList(QString playerName);
void removeSpectator(int spectatorId, ServerInfo_User spectator);
void processLocalPlayerSideboardLocked(int playerId, bool sideboardLocked);
void processLocalPlayerReadyStateChanged(int playerId, bool ready);
void emitUserEvent();
};
#endif