diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt index 4ffec752f..6b0e12521 100644 --- a/cockatrice/CMakeLists.txt +++ b/cockatrice/CMakeLists.txt @@ -109,6 +109,8 @@ set(cockatrice_SOURCES src/game/replay.cpp src/game/tally/tally_manager.cpp src/game/tally/tally_manager.h + src/game/tally/tally_widget.cpp + src/game/tally/tally_widget.h src/game/zones/card_zone_logic.cpp src/game/zones/hand_zone_logic.cpp src/game/zones/pile_zone_logic.cpp diff --git a/cockatrice/src/game/tally/tally_widget.cpp b/cockatrice/src/game/tally/tally_widget.cpp new file mode 100644 index 000000000..5c18c0e38 --- /dev/null +++ b/cockatrice/src/game/tally/tally_widget.cpp @@ -0,0 +1,76 @@ +#include "tally_widget.h" + +#include +#include +#include + +TallyWidget::TallyWidget(QWidget *parent, TallyManager *tallyManager) : QWidget(parent), tallyManager(tallyManager) +{ + auto layout = new QVBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->setAlignment(Qt::AlignCenter); + setLayout(layout); + + auto scrollArea = new QScrollArea(this); + scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); + + layout->addWidget(scrollArea); + + auto gridLayoutWidget = new QWidget(scrollArea); + gridLayout = new QGridLayout(gridLayoutWidget); + gridLayout->setAlignment(Qt::AlignLeft | Qt::AlignTop); + + resetGridLayout({TallyManager::TOTAL_POWER, TallyManager::TOTAL_MANA_VALUE}); +} + +void TallyWidget::resetGridLayout(QList entryTypes) +{ + // clear all existing + while (auto item = gridLayout->takeAt(0)) { + item->widget()->deleteLater(); + delete item; + } + + // create all labels + for (auto entryType : entryTypes) { + auto textLabel = createTextLabel(entryType); + auto valueLabel = createValueLabel(entryType); + + int row = gridLayout->rowCount(); + gridLayout->addWidget(textLabel, row, 0); + gridLayout->addWidget(valueLabel, row, 1); + } +} + +QLabel *TallyWidget::createTextLabel(TallyManager::EntryType entryType) +{ + auto label = new QLabel; + + auto updateLabel = [label, entryType](const QMap &results) { + QString text = results.value(entryType).text; + label->setText(text); + }; + + updateLabel(tallyManager->getAllResults()); + + connect(tallyManager, &TallyManager::tallyChanged, label, updateLabel); + + return label; +} + +QLabel *TallyWidget::createValueLabel(TallyManager::EntryType entryType) +{ + auto label = new QLabel; + + auto updateLabel = [label, entryType](const QMap &results) { + int value = results.value(entryType).value; + label->setText(QString::number(value)); + }; + + updateLabel(tallyManager->getAllResults()); + + connect(tallyManager, &TallyManager::tallyChanged, label, updateLabel); + + return label; +} diff --git a/cockatrice/src/game/tally/tally_widget.h b/cockatrice/src/game/tally/tally_widget.h new file mode 100644 index 000000000..e6ab16c8f --- /dev/null +++ b/cockatrice/src/game/tally/tally_widget.h @@ -0,0 +1,38 @@ +#ifndef COCKATRICE_TALLY_WIDGET_H +#define COCKATRICE_TALLY_WIDGET_H +#include "tally_manager.h" + +#include +#include +#include + +class QLabel; +class CardItem; + +class TallyWidget : public QWidget +{ + Q_OBJECT + +public: + explicit TallyWidget(QWidget *parent, TallyManager *tallyManager); + +private: + TallyManager *tallyManager; + + struct TallyEntryInternal + { + TallyManager::EntryType type; + QLabel *textLabel; + QLabel *valueLabel; + }; + + QList tallyEntriesInternal; + + QGridLayout *gridLayout; + + void resetGridLayout(QList entryTypes); + QLabel *createTextLabel(TallyManager::EntryType entryType); + QLabel *createValueLabel(TallyManager::EntryType entryType); +}; + +#endif // COCKATRICE_TALLY_WIDGET_H diff --git a/cockatrice/src/interface/widgets/tabs/tab_game.cpp b/cockatrice/src/interface/widgets/tabs/tab_game.cpp index 9fc123a8c..1f40e05b9 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_game.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_game.cpp @@ -13,6 +13,7 @@ #include "../game/player/player_list_widget.h" #include "../game/player/player_logic.h" #include "../game/replay.h" +#include "../game/tally/tally_widget.h" #include "../interface/card_picture_loader/card_picture_loader.h" #include "../interface/widgets/cards/card_info_frame_widget.h" #include "../interface/widgets/dialogs/dlg_create_game.h" @@ -49,8 +50,11 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, GameReplay *_replay) // THIS CTOR IS USED ON REPLAY game = new Replay(this, _replay); + tallyManager = new TallyManager(this); + createCardInfoDock(true); createPlayerListDock(true); + createTallyDock(true); createMessageDock(true); createPlayAreaWidget(true); createDeckViewContainerWidget(true); @@ -58,6 +62,7 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, GameReplay *_replay) addDockWidget(Qt::RightDockWidgetArea, cardInfoDock); addDockWidget(Qt::RightDockWidgetArea, playerListDock); + addDockWidget(Qt::RightDockWidgetArea, tallyDock); addDockWidget(Qt::RightDockWidgetArea, messageLayoutDock); addDockWidget(Qt::BottomDockWidgetArea, replayDock); @@ -93,8 +98,11 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, // THIS CTOR IS USED ON GAMES game = new Game(this, _clients, event, _roomGameTypes); + tallyManager = new TallyManager(this); + createCardInfoDock(); createPlayerListDock(); + createTallyDock(); createMessageDock(); createPlayAreaWidget(); createDeckViewContainerWidget(); @@ -102,6 +110,7 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, addDockWidget(Qt::RightDockWidgetArea, cardInfoDock); addDockWidget(Qt::RightDockWidgetArea, playerListDock); + addDockWidget(Qt::RightDockWidgetArea, tallyDock); addDockWidget(Qt::RightDockWidgetArea, messageLayoutDock); mainWidget = new QStackedWidget(this); @@ -282,6 +291,7 @@ void TabGame::retranslateUi() updatePlayerListDockTitle(); cardInfoDock->setWindowTitle(tr("Card Info") + (cardInfoDock->isWindow() ? tabText : QString())); + tallyDock->setWindowTitle(tr("Tally") + (tallyDock->isWindow() ? tabText : QString())); messageLayoutDock->setWindowTitle(tr("Messages") + (messageLayoutDock->isWindow() ? tabText : QString())); if (replayDock) { replayDock->setWindowTitle(tr("Replay Timeline") + (replayDock->isWindow() ? tabText : QString())); @@ -348,6 +358,7 @@ void TabGame::retranslateUi() dockToActions[cardInfoDock].menu->setTitle(tr("Card Info")); dockToActions[messageLayoutDock].menu->setTitle(tr("Messages")); + dockToActions[tallyDock].menu->setTitle(tr("Tally")); dockToActions[playerListDock].menu->setTitle(tr("Player List")); if (replayDock) { @@ -1053,6 +1064,7 @@ void TabGame::createViewMenuItems() registerDockWidget(viewMenu, cardInfoDock, {250, 360}); registerDockWidget(viewMenu, messageLayoutDock, {250, 200}); + registerDockWidget(viewMenu, tallyDock, {250, 50}); registerDockWidget(viewMenu, playerListDock, {250, 50}); if (replayDock) { @@ -1114,29 +1126,24 @@ void TabGame::actResetLayout() { cardInfoDock->setVisible(true); playerListDock->setVisible(true); + tallyDock->setVisible(true); messageLayoutDock->setVisible(true); cardInfoDock->setFloating(false); playerListDock->setFloating(false); + tallyDock->setVisible(false); messageLayoutDock->setFloating(false); addDockWidget(Qt::RightDockWidgetArea, cardInfoDock); addDockWidget(Qt::RightDockWidgetArea, playerListDock); + addDockWidget(Qt::RightDockWidgetArea, tallyDock); addDockWidget(Qt::RightDockWidgetArea, messageLayoutDock); - if (replayDock) { - replayDock->setVisible(true); - replayDock->setFloating(false); - addDockWidget(Qt::BottomDockWidgetArea, replayDock); + for (auto i = dockToActions.cbegin(); i != dockToActions.cend(); ++i) { + QDockWidget *dock = i.key(); + QSize defaultSize = i.value().defaultSize; - cardInfoDock->resize(250, 360); - messageLayoutDock->resize(250, 200); - playerListDock->resize(250, 50); - replayDock->resize(900, 100); - } else { - cardInfoDock->resize(250, 360); - messageLayoutDock->resize(250, 250); - playerListDock->resize(250, 50); + dock->resize(defaultSize); } } @@ -1155,6 +1162,9 @@ void TabGame::createPlayAreaWidget(bool bReplay) connect(game->getGameEventHandler(), &GameEventHandler::arrowDeleted, scene, &GameScene::deleteArrow); gameView = new GameView(scene); + connect(scene, &GameScene::selectionChanged, tallyManager, + [this] { tallyManager->updateSelection(scene->selectedCards()); }); + auto gamePlayAreaVBox = new QVBoxLayout; gamePlayAreaVBox->setContentsMargins(0, 0, 0, 0); gamePlayAreaVBox->addWidget(gameView); @@ -1233,6 +1243,19 @@ void TabGame::createPlayerListDock(bool bReplay) playerListDock->setFloating(false); } +void TabGame::createTallyDock(bool bReplay) +{ + Q_UNUSED(bReplay); + + tallyWidget = new TallyWidget(this, tallyManager); + + tallyDock = new QDockWidget(this); + tallyDock->setObjectName("tallyDock"); + tallyDock->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable | + QDockWidget::DockWidgetMovable); + tallyDock->setWidget(tallyWidget); +} + void TabGame::createMessageDock(bool bReplay) { auto messageLogLayout = new QVBoxLayout; diff --git a/cockatrice/src/interface/widgets/tabs/tab_game.h b/cockatrice/src/interface/widgets/tabs/tab_game.h index 7f9392034..8d152d94a 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_game.h +++ b/cockatrice/src/interface/widgets/tabs/tab_game.h @@ -20,6 +20,8 @@ #include #include +class TallyManager; +class TallyWidget; class ServerInfo_PlayerProperties; class TabbedDeckViewContainer; inline Q_LOGGING_CATEGORY(TabGameLog, "tab_game"); @@ -66,6 +68,7 @@ private: CardInfoFrameWidget *cardInfoFrameWidget; PlayerListWidget *playerListWidget; + TallyWidget *tallyWidget; QLabel *timeElapsedLabel; MessageLogWidget *messageLog; QLabel *sayLabel; @@ -73,10 +76,11 @@ private: PhasesToolbar *phasesToolbar; GameScene *scene; GameView *gameView; + TallyManager *tallyManager; QMap deckViewContainers; QVBoxLayout *deckViewContainerLayout; QWidget *gamePlayAreaWidget, *deckViewContainerWidget; - QDockWidget *cardInfoDock, *messageLayoutDock, *playerListDock, *replayDock; + QDockWidget *cardInfoDock, *messageLayoutDock, *playerListDock, *tallyDock, *replayDock; QAction *playersSeparator; QMenu *gameMenu, *viewMenu; TearOffMenu *phasesMenu; @@ -121,6 +125,7 @@ private: void registerDockWidget(QMenu *_viewMenu, QDockWidget *widget, const QSize &defaultSize); void createCardInfoDock(bool bReplay = false); void createPlayerListDock(bool bReplay = false); + void createTallyDock(bool bReplay = false); void createMessageDock(bool bReplay = false); void createPlayAreaWidget(bool bReplay = false); void createDeckViewContainerWidget(bool bReplay = false);