mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-14 14:32:15 -07:00
Clean up game scene code.
Took 18 minutes
This commit is contained in:
parent
891e7bf6e4
commit
100b363892
2 changed files with 229 additions and 143 deletions
|
|
@ -15,6 +15,7 @@
|
||||||
#include <QGraphicsView>
|
#include <QGraphicsView>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QtMath>
|
#include <QtMath>
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
GameScene::GameScene(PhasesToolbar *_phasesToolbar, QObject *parent)
|
GameScene::GameScene(PhasesToolbar *_phasesToolbar, QObject *parent)
|
||||||
: QGraphicsScene(parent), phasesToolbar(_phasesToolbar), viewSize(QSize()), playerRotation(0)
|
: QGraphicsScene(parent), phasesToolbar(_phasesToolbar), viewSize(QSize()), playerRotation(0)
|
||||||
|
|
@ -32,8 +33,6 @@ GameScene::~GameScene()
|
||||||
delete animationTimer;
|
delete animationTimer;
|
||||||
|
|
||||||
// DO NOT call clearViews() here
|
// DO NOT call clearViews() here
|
||||||
// clearViews calls close() on the zoneViews, which sends signals; sending signals in destructors leads to segfaults
|
|
||||||
// deleteLater() deletes the zoneView without allowing it to send signals
|
|
||||||
for (const auto &zoneView : zoneViews) {
|
for (const auto &zoneView : zoneViews) {
|
||||||
zoneView->deleteLater();
|
zoneView->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
@ -41,13 +40,14 @@ GameScene::~GameScene()
|
||||||
|
|
||||||
void GameScene::retranslateUi()
|
void GameScene::retranslateUi()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < zoneViews.size(); ++i)
|
for (ZoneViewWidget *view : zoneViews)
|
||||||
zoneViews[i]->retranslateUi();
|
view->retranslateUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameScene::addPlayer(Player *player)
|
void GameScene::addPlayer(Player *player)
|
||||||
{
|
{
|
||||||
qCInfo(GameScenePlayerAdditionRemovalLog) << "GameScene::addPlayer name=" << player->getPlayerInfo()->getName();
|
qCInfo(GameScenePlayerAdditionRemovalLog) << "GameScene::addPlayer name=" << player->getPlayerInfo()->getName();
|
||||||
|
|
||||||
players << player->getGraphicsItem();
|
players << player->getGraphicsItem();
|
||||||
addItem(player->getGraphicsItem());
|
addItem(player->getGraphicsItem());
|
||||||
connect(player->getGraphicsItem(), &PlayerGraphicsItem::sizeChanged, this, &GameScene::rearrange);
|
connect(player->getGraphicsItem(), &PlayerGraphicsItem::sizeChanged, this, &GameScene::rearrange);
|
||||||
|
|
@ -55,7 +55,9 @@ void GameScene::addPlayer(Player *player)
|
||||||
|
|
||||||
void GameScene::removePlayer(Player *player)
|
void GameScene::removePlayer(Player *player)
|
||||||
{
|
{
|
||||||
qCInfo(GameScenePlayerAdditionRemovalLog) << "GameScene::removePlayer name=" << player->getPlayerInfo()->getName();
|
qCInfo(GameScenePlayerAdditionRemovalLog)
|
||||||
|
<< "GameScene::removePlayer name=" << player->getPlayerInfo()->getName();
|
||||||
|
|
||||||
for (ZoneViewWidget *zone : zoneViews) {
|
for (ZoneViewWidget *zone : zoneViews) {
|
||||||
if (zone->getPlayer() == player) {
|
if (zone->getPlayer() == player) {
|
||||||
zone->close();
|
zone->close();
|
||||||
|
|
@ -74,104 +76,50 @@ void GameScene::adjustPlayerRotation(int rotationAdjustment)
|
||||||
|
|
||||||
void GameScene::rearrange()
|
void GameScene::rearrange()
|
||||||
{
|
{
|
||||||
playersByColumn.clear();
|
|
||||||
|
|
||||||
// Create the list of players playing, noting the first player's index.
|
|
||||||
QList<Player *> playersPlaying;
|
|
||||||
int firstPlayerIndex = 0;
|
int firstPlayerIndex = 0;
|
||||||
bool firstPlayerFound = false;
|
auto playersPlaying = collectActivePlayers(firstPlayerIndex);
|
||||||
QListIterator<PlayerGraphicsItem *> playersIter(players);
|
playersPlaying = rotatePlayers(playersPlaying, firstPlayerIndex);
|
||||||
while (playersIter.hasNext()) {
|
|
||||||
Player *p = playersIter.next()->getPlayer();
|
|
||||||
if (p && !p->getConceded()) {
|
|
||||||
playersPlaying.append(p);
|
|
||||||
if (!firstPlayerFound && p->getPlayerInfo()->getLocal()) {
|
|
||||||
firstPlayerIndex = playersPlaying.size() - 1;
|
|
||||||
firstPlayerFound = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rotate the players playing list so that first player is first, then
|
int columns = determineColumnCount(playersPlaying.size());
|
||||||
// adjust by the additional rotation setting.
|
QSizeF sceneSize = computeSceneSizeAndPlayerLayout(playersPlaying, columns);
|
||||||
if (!playersPlaying.isEmpty()) {
|
|
||||||
int totalRotation = firstPlayerIndex + playerRotation;
|
|
||||||
while (totalRotation < 0)
|
|
||||||
totalRotation += playersPlaying.size();
|
|
||||||
for (int i = 0; i < totalRotation; ++i) {
|
|
||||||
playersPlaying.append(playersPlaying.takeFirst());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const int playersCount = playersPlaying.size();
|
phasesToolbar->setHeight(sceneSize.height());
|
||||||
const int columns = playersCount < SettingsCache::instance().getMinPlayersForMultiColumnLayout() ? 1 : 2;
|
setSceneRect(0, 0, sceneSize.width(), sceneSize.height());
|
||||||
const int rows = qCeil((qreal)playersCount / columns);
|
|
||||||
qreal sceneHeight = 0, sceneWidth = -playerAreaSpacing;
|
|
||||||
QList<int> columnWidth;
|
|
||||||
|
|
||||||
QListIterator<Player *> playersPlayingIter(playersPlaying);
|
|
||||||
for (int col = 0; col < columns; ++col) {
|
|
||||||
playersByColumn.append(QList<PlayerGraphicsItem *>());
|
|
||||||
columnWidth.append(0);
|
|
||||||
qreal thisColumnHeight = -playerAreaSpacing;
|
|
||||||
const int rowsInColumn = rows - (playersCount % columns) * col; // only correct for max. 2 cols
|
|
||||||
for (int j = 0; j < rowsInColumn; ++j) {
|
|
||||||
Player *player = playersPlayingIter.next();
|
|
||||||
if (col == 0)
|
|
||||||
playersByColumn[col].prepend(player->getGraphicsItem());
|
|
||||||
else
|
|
||||||
playersByColumn[col].append(player->getGraphicsItem());
|
|
||||||
thisColumnHeight += player->getGraphicsItem()->boundingRect().height() + playerAreaSpacing;
|
|
||||||
if (player->getGraphicsItem()->boundingRect().width() > columnWidth[col])
|
|
||||||
columnWidth[col] = player->getGraphicsItem()->boundingRect().width();
|
|
||||||
}
|
|
||||||
if (thisColumnHeight > sceneHeight)
|
|
||||||
sceneHeight = thisColumnHeight;
|
|
||||||
sceneWidth += columnWidth[col] + playerAreaSpacing;
|
|
||||||
}
|
|
||||||
|
|
||||||
phasesToolbar->setHeight(sceneHeight);
|
|
||||||
qreal phasesWidth = phasesToolbar->getWidth();
|
|
||||||
sceneWidth += phasesWidth;
|
|
||||||
|
|
||||||
qreal x = phasesWidth;
|
|
||||||
for (int col = 0; col < columns; ++col) {
|
|
||||||
qreal y = 0;
|
|
||||||
for (int row = 0; row < playersByColumn[col].size(); ++row) {
|
|
||||||
PlayerGraphicsItem *player = playersByColumn[col][row];
|
|
||||||
player->setPos(x, y);
|
|
||||||
player->setMirrored(row != rows - 1);
|
|
||||||
y += player->boundingRect().height() + playerAreaSpacing;
|
|
||||||
}
|
|
||||||
x += columnWidth[col] + playerAreaSpacing;
|
|
||||||
}
|
|
||||||
|
|
||||||
setSceneRect(sceneRect().x(), sceneRect().y(), sceneWidth, sceneHeight);
|
|
||||||
processViewSizeChange(viewSize);
|
processViewSizeChange(viewSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------- Zone Views ----------
|
||||||
|
|
||||||
void GameScene::toggleZoneView(Player *player, const QString &zoneName, int numberCards, bool isReversed)
|
void GameScene::toggleZoneView(Player *player, const QString &zoneName, int numberCards, bool isReversed)
|
||||||
{
|
{
|
||||||
for (auto &view : zoneViews) {
|
for (auto &view : zoneViews) {
|
||||||
ZoneViewZone *temp = view->getZone();
|
ZoneViewZone *temp = view->getZone();
|
||||||
if (temp->getLogic()->getName() == zoneName && temp->getLogic()->getPlayer() == player &&
|
if (temp->getLogic()->getName() == zoneName &&
|
||||||
|
temp->getLogic()->getPlayer() == player &&
|
||||||
qobject_cast<ZoneViewZoneLogic *>(temp->getLogic())->getNumberCards() == numberCards) {
|
qobject_cast<ZoneViewZoneLogic *>(temp->getLogic())->getNumberCards() == numberCards) {
|
||||||
view->close();
|
view->close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ZoneViewWidget *item =
|
ZoneViewWidget *item =
|
||||||
new ZoneViewWidget(player, player->getZones().value(zoneName), numberCards, false, false, {}, isReversed);
|
new ZoneViewWidget(
|
||||||
|
player,
|
||||||
|
player->getZones().value(zoneName),
|
||||||
|
numberCards,
|
||||||
|
false,
|
||||||
|
false, {}, isReversed);
|
||||||
|
|
||||||
zoneViews.append(item);
|
zoneViews.append(item);
|
||||||
connect(item, &ZoneViewWidget::closePressed, this, &GameScene::removeZoneView);
|
connect(item, &ZoneViewWidget::closePressed, this, &GameScene::removeZoneView);
|
||||||
addItem(item);
|
addItem(item);
|
||||||
if (zoneName == "grave") {
|
|
||||||
|
if (zoneName == "grave")
|
||||||
item->setPos(360, 100);
|
item->setPos(360, 100);
|
||||||
} else if (zoneName == "rfg") {
|
else if (zoneName == "rfg")
|
||||||
item->setPos(380, 120);
|
item->setPos(380, 120);
|
||||||
} else {
|
else
|
||||||
item->setPos(340, 80);
|
item->setPos(340, 80);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameScene::addRevealedZoneView(Player *player,
|
void GameScene::addRevealedZoneView(Player *player,
|
||||||
|
|
@ -204,6 +152,8 @@ void GameScene::closeMostRecentZoneView()
|
||||||
zoneViews.last()->close();
|
zoneViews.last()->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------- View Transforms ----------
|
||||||
|
|
||||||
QTransform GameScene::getViewTransform() const
|
QTransform GameScene::getViewTransform() const
|
||||||
{
|
{
|
||||||
return views().at(0)->transform();
|
return views().at(0)->transform();
|
||||||
|
|
@ -214,83 +164,35 @@ QTransform GameScene::getViewportTransform() const
|
||||||
return views().at(0)->viewportTransform();
|
return views().at(0)->viewportTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------- View Size ----------
|
||||||
|
|
||||||
void GameScene::processViewSizeChange(const QSize &newSize)
|
void GameScene::processViewSizeChange(const QSize &newSize)
|
||||||
{
|
{
|
||||||
viewSize = newSize;
|
viewSize = newSize;
|
||||||
|
|
||||||
qreal newRatio = ((qreal)newSize.width()) / newSize.height();
|
QList<qreal> minWidthByColumn = calculateMinWidthByColumn();
|
||||||
qreal minWidth = 0;
|
qreal minWidth = std::accumulate(minWidthByColumn.begin(),
|
||||||
QList<qreal> minWidthByColumn;
|
minWidthByColumn.end(), phasesToolbar->getWidth());
|
||||||
for (int col = 0; col < playersByColumn.size(); ++col) {
|
|
||||||
minWidthByColumn.append(0);
|
|
||||||
for (int row = 0; row < playersByColumn[col].size(); ++row) {
|
|
||||||
qreal w = playersByColumn[col][row]->getMinimumWidth();
|
|
||||||
if (w > minWidthByColumn[col])
|
|
||||||
minWidthByColumn[col] = w;
|
|
||||||
}
|
|
||||||
minWidth += minWidthByColumn[col];
|
|
||||||
}
|
|
||||||
minWidth += phasesToolbar->getWidth();
|
|
||||||
|
|
||||||
qreal minRatio = minWidth / sceneRect().height();
|
qreal newWidth = calculateNewSceneWidth(newSize, minWidth);
|
||||||
qreal newWidth;
|
|
||||||
if (minRatio > newRatio) {
|
|
||||||
// Aspect ratio is dominated by table width.
|
|
||||||
newWidth = minWidth;
|
|
||||||
} else {
|
|
||||||
// Aspect ratio is dominated by window dimensions.
|
|
||||||
newWidth = newRatio * sceneRect().height();
|
|
||||||
}
|
|
||||||
setSceneRect(0, 0, newWidth, sceneRect().height());
|
setSceneRect(0, 0, newWidth, sceneRect().height());
|
||||||
|
|
||||||
qreal extraWidthPerColumn = (newWidth - minWidth) / playersByColumn.size();
|
resizeColumnsAndPlayers(minWidthByColumn, newWidth);
|
||||||
qreal newx = phasesToolbar->getWidth();
|
|
||||||
for (int col = 0; col < playersByColumn.size(); ++col) {
|
|
||||||
for (int row = 0; row < playersByColumn[col].size(); ++row) {
|
|
||||||
playersByColumn[col][row]->processSceneSizeChange(minWidthByColumn[col] + extraWidthPerColumn);
|
|
||||||
playersByColumn[col][row]->setPos(newx, playersByColumn[col][row]->y());
|
|
||||||
}
|
|
||||||
newx += minWidthByColumn[col] + extraWidthPerColumn;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------- Hover Handling ----------
|
||||||
|
|
||||||
void GameScene::updateHover(const QPointF &scenePos)
|
void GameScene::updateHover(const QPointF &scenePos)
|
||||||
{
|
{
|
||||||
QList<QGraphicsItem *> itemList =
|
auto itemList = items(scenePos, Qt::IntersectsItemBoundingRect, Qt::DescendingOrder, getViewTransform());
|
||||||
items(scenePos, Qt::IntersectsItemBoundingRect, Qt::DescendingOrder, getViewTransform());
|
|
||||||
|
|
||||||
// Search for the topmost zone and ignore all cards not belonging to that zone.
|
CardZone *zone = findTopmostZone(itemList);
|
||||||
CardZone *zone = 0;
|
CardItem *topCard = zone ? findTopmostCardInZone(itemList, zone) : nullptr;
|
||||||
for (int i = 0; i < itemList.size(); ++i)
|
updateHoveredCard(topCard);
|
||||||
if ((zone = qgraphicsitem_cast<CardZone *>(itemList[i])))
|
|
||||||
break;
|
|
||||||
|
|
||||||
CardItem *maxZCard = 0;
|
|
||||||
if (zone) {
|
|
||||||
qreal maxZ = -1;
|
|
||||||
for (int i = 0; i < itemList.size(); ++i) {
|
|
||||||
CardItem *card = qgraphicsitem_cast<CardItem *>(itemList[i]);
|
|
||||||
if (!card)
|
|
||||||
continue;
|
|
||||||
if (card->getAttachedTo()) {
|
|
||||||
if (card->getAttachedTo()->getZone() != zone->getLogic())
|
|
||||||
continue;
|
|
||||||
} else if (card->getZone() != zone->getLogic())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (card->getRealZValue() > maxZ) {
|
|
||||||
maxZ = card->getRealZValue();
|
|
||||||
maxZCard = card;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (hoveredCard && (maxZCard != hoveredCard))
|
|
||||||
hoveredCard->setHovered(false);
|
|
||||||
if (maxZCard && (maxZCard != hoveredCard))
|
|
||||||
maxZCard->setHovered(true);
|
|
||||||
hoveredCard = maxZCard;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------- Event Handling ----------
|
||||||
|
|
||||||
bool GameScene::event(QEvent *event)
|
bool GameScene::event(QEvent *event)
|
||||||
{
|
{
|
||||||
if (event->type() == QEvent::GraphicsSceneMouseMove)
|
if (event->type() == QEvent::GraphicsSceneMouseMove)
|
||||||
|
|
@ -325,6 +227,8 @@ void GameScene::unregisterAnimationItem(AbstractCardItem *card)
|
||||||
animationTimer->stop();
|
animationTimer->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------- Rubber Band ----------
|
||||||
|
|
||||||
void GameScene::startRubberBand(const QPointF &selectionOrigin)
|
void GameScene::startRubberBand(const QPointF &selectionOrigin)
|
||||||
{
|
{
|
||||||
emit sigStartRubberBand(selectionOrigin);
|
emit sigStartRubberBand(selectionOrigin);
|
||||||
|
|
@ -339,3 +243,175 @@ void GameScene::stopRubberBand()
|
||||||
{
|
{
|
||||||
emit sigStopRubberBand();
|
emit sigStopRubberBand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================================================================
|
||||||
|
// Private Helpers
|
||||||
|
// ==================================================================
|
||||||
|
|
||||||
|
QList<Player *> GameScene::collectActivePlayers(int &firstPlayerIndex) const
|
||||||
|
{
|
||||||
|
QList<Player *> activePlayers;
|
||||||
|
firstPlayerIndex = 0;
|
||||||
|
bool firstPlayerFound = false;
|
||||||
|
|
||||||
|
for (auto *pgItem : players) {
|
||||||
|
Player *p = pgItem->getPlayer();
|
||||||
|
if (p && !p->getConceded()) {
|
||||||
|
activePlayers.append(p);
|
||||||
|
if (!firstPlayerFound && p->getPlayerInfo()->getLocal()) {
|
||||||
|
firstPlayerIndex = activePlayers.size() - 1;
|
||||||
|
firstPlayerFound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return activePlayers;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<Player *> GameScene::rotatePlayers(const QList<Player *> &players, int firstPlayerIndex) const
|
||||||
|
{
|
||||||
|
QList<Player *> rotated = players;
|
||||||
|
if (!rotated.isEmpty()) {
|
||||||
|
int totalRotation = firstPlayerIndex + playerRotation;
|
||||||
|
while (totalRotation < 0)
|
||||||
|
totalRotation += rotated.size();
|
||||||
|
for (int i = 0; i < totalRotation; ++i)
|
||||||
|
rotated.append(rotated.takeFirst());
|
||||||
|
}
|
||||||
|
return rotated;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GameScene::determineColumnCount(int playerCount) const
|
||||||
|
{
|
||||||
|
return playerCount < SettingsCache::instance().getMinPlayersForMultiColumnLayout() ? 1 : 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSizeF GameScene::computeSceneSizeAndPlayerLayout(const QList<Player *> &playersPlaying, int columns)
|
||||||
|
{
|
||||||
|
playersByColumn.clear();
|
||||||
|
|
||||||
|
int rows = qCeil((qreal)playersPlaying.size() / columns);
|
||||||
|
qreal sceneHeight = 0, sceneWidth = -playerAreaSpacing;
|
||||||
|
QList<int> columnWidth;
|
||||||
|
|
||||||
|
QListIterator<Player *> playersIter(playersPlaying);
|
||||||
|
for (int col = 0; col < columns; ++col) {
|
||||||
|
playersByColumn.append(QList<PlayerGraphicsItem *>());
|
||||||
|
columnWidth.append(0);
|
||||||
|
qreal thisColumnHeight = -playerAreaSpacing;
|
||||||
|
int rowsInColumn = rows - (playersPlaying.size() % columns) * col; // for 2 cols
|
||||||
|
|
||||||
|
for (int j = 0; j < rowsInColumn; ++j) {
|
||||||
|
Player *player = playersIter.next();
|
||||||
|
if (col == 0)
|
||||||
|
playersByColumn[col].prepend(player->getGraphicsItem());
|
||||||
|
else
|
||||||
|
playersByColumn[col].append(player->getGraphicsItem());
|
||||||
|
|
||||||
|
auto *pgItem = player->getGraphicsItem();
|
||||||
|
thisColumnHeight += pgItem->boundingRect().height() + playerAreaSpacing;
|
||||||
|
columnWidth[col] = std::max(columnWidth[col], (int)pgItem->boundingRect().width());
|
||||||
|
}
|
||||||
|
|
||||||
|
sceneHeight = std::max(sceneHeight, thisColumnHeight);
|
||||||
|
sceneWidth += columnWidth[col] + playerAreaSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal phasesWidth = phasesToolbar->getWidth();
|
||||||
|
sceneWidth += phasesWidth;
|
||||||
|
|
||||||
|
// Position players
|
||||||
|
qreal x = phasesWidth;
|
||||||
|
for (int col = 0; col < columns; ++col) {
|
||||||
|
qreal y = 0;
|
||||||
|
for (int row = 0; row < playersByColumn[col].size(); ++row) {
|
||||||
|
PlayerGraphicsItem *player = playersByColumn[col][row];
|
||||||
|
player->setPos(x, y);
|
||||||
|
player->setMirrored(row != rows - 1);
|
||||||
|
y += player->boundingRect().height() + playerAreaSpacing;
|
||||||
|
}
|
||||||
|
x += columnWidth[col] + playerAreaSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QSizeF(sceneWidth, sceneHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<qreal> GameScene::calculateMinWidthByColumn() const
|
||||||
|
{
|
||||||
|
QList<qreal> minWidthByColumn;
|
||||||
|
for (const auto &col : playersByColumn) {
|
||||||
|
qreal maxWidth = 0;
|
||||||
|
for (PlayerGraphicsItem *player : col)
|
||||||
|
maxWidth = std::max(maxWidth, player->getMinimumWidth());
|
||||||
|
minWidthByColumn.append(maxWidth);
|
||||||
|
}
|
||||||
|
return minWidthByColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal GameScene::calculateNewSceneWidth(const QSize &newSize, qreal minWidth) const
|
||||||
|
{
|
||||||
|
qreal newRatio = (qreal)newSize.width() / newSize.height();
|
||||||
|
qreal minRatio = minWidth / sceneRect().height();
|
||||||
|
|
||||||
|
if (minRatio > newRatio) {
|
||||||
|
return minWidth; // dominated by table width
|
||||||
|
} else {
|
||||||
|
return newRatio * sceneRect().height(); // dominated by window dimensions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameScene::resizeColumnsAndPlayers(const QList<qreal> &minWidthByColumn, qreal newWidth)
|
||||||
|
{
|
||||||
|
qreal minWidth = std::accumulate(minWidthByColumn.begin(), minWidthByColumn.end(), phasesToolbar->getWidth());
|
||||||
|
|
||||||
|
qreal extraWidthPerColumn = (newWidth - minWidth) / playersByColumn.size();
|
||||||
|
qreal newx = phasesToolbar->getWidth();
|
||||||
|
|
||||||
|
for (int col = 0; col < playersByColumn.size(); ++col) {
|
||||||
|
for (PlayerGraphicsItem *player : playersByColumn[col]) {
|
||||||
|
player->processSceneSizeChange(minWidthByColumn[col] + extraWidthPerColumn);
|
||||||
|
player->setPos(newx, player->y());
|
||||||
|
}
|
||||||
|
newx += minWidthByColumn[col] + extraWidthPerColumn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CardZone *GameScene::findTopmostZone(const QList<QGraphicsItem *> &items) const
|
||||||
|
{
|
||||||
|
for (QGraphicsItem *item : items)
|
||||||
|
if (auto *zone = qgraphicsitem_cast<CardZone *>(item))
|
||||||
|
return zone;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
CardItem *GameScene::findTopmostCardInZone(const QList<QGraphicsItem *> &items, CardZone *zone) const
|
||||||
|
{
|
||||||
|
CardItem *maxZCard = nullptr;
|
||||||
|
qreal maxZ = -1;
|
||||||
|
|
||||||
|
for (QGraphicsItem *item : items) {
|
||||||
|
CardItem *card = qgraphicsitem_cast<CardItem *>(item);
|
||||||
|
if (!card)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (card->getAttachedTo()) {
|
||||||
|
if (card->getAttachedTo()->getZone() != zone->getLogic())
|
||||||
|
continue;
|
||||||
|
} else if (card->getZone() != zone->getLogic())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (card->getRealZValue() > maxZ) {
|
||||||
|
maxZ = card->getRealZValue();
|
||||||
|
maxZCard = card;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return maxZCard;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameScene::updateHoveredCard(CardItem *newCard)
|
||||||
|
{
|
||||||
|
if (hoveredCard && (newCard != hoveredCard))
|
||||||
|
hoveredCard->setHovered(false);
|
||||||
|
if (newCard && (newCard != hoveredCard))
|
||||||
|
newCard->setHovered(true);
|
||||||
|
hoveredCard = newCard;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,16 @@ public:
|
||||||
void startRubberBand(const QPointF &selectionOrigin);
|
void startRubberBand(const QPointF &selectionOrigin);
|
||||||
void resizeRubberBand(const QPointF &cursorPoint);
|
void resizeRubberBand(const QPointF &cursorPoint);
|
||||||
void stopRubberBand();
|
void stopRubberBand();
|
||||||
|
QList<Player *> collectActivePlayers(int &firstPlayerIndex) const;
|
||||||
|
QList<Player *> rotatePlayers(const QList<Player *> &players, int firstPlayerIndex) const;
|
||||||
|
int determineColumnCount(int playerCount) const;
|
||||||
|
QSizeF computeSceneSizeAndPlayerLayout(const QList<Player *> &playersPlaying, int columns);
|
||||||
|
QList<qreal> calculateMinWidthByColumn() const;
|
||||||
|
qreal calculateNewSceneWidth(const QSize &newSize, qreal minWidth) const;
|
||||||
|
void resizeColumnsAndPlayers(const QList<qreal> &minWidthByColumn, qreal newWidth);
|
||||||
|
CardZone *findTopmostZone(const QList<QGraphicsItem *> &items) const;
|
||||||
|
CardItem *findTopmostCardInZone(const QList<QGraphicsItem *> &items, CardZone *zone) const;
|
||||||
|
void updateHoveredCard(CardItem *newCard);
|
||||||
|
|
||||||
void registerAnimationItem(AbstractCardItem *item);
|
void registerAnimationItem(AbstractCardItem *item);
|
||||||
void unregisterAnimationItem(AbstractCardItem *card);
|
void unregisterAnimationItem(AbstractCardItem *card);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue