File indexing completed on 2024-05-12 08:00:00
0001 /*************************************************************************** 0002 File : board.cpp 0003 Project : Knights 0004 Description : Game board (scene) 0005 -------------------------------------------------------------------- 0006 SPDX-FileCopyrightText: 2016 Alexander Semke (alexander.semke@web.de) 0007 SPDX-FileCopyrightText: 2009-2011 Miha Čančula (miha@noughmad.eu) 0008 0009 ***************************************************************************/ 0010 0011 /*************************************************************************** 0012 * * 0013 * SPDX-License-Identifier: GPL-2.0-or-later 0014 * * 0015 * This program is distributed in the hope that it will be useful, * 0016 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0018 * GNU General Public License for more details. * 0019 * * 0020 * You should have received a copy of the GNU General Public License * 0021 * along with this program; if not, write to the Free Software * 0022 * Foundation, Inc., 51 Franklin Street, Fifth Floor, * 0023 * Boston, MA 02110-1301 USA * 0024 * * 0025 ***************************************************************************/ 0026 0027 #include "board.h" 0028 #include "gamemanager.h" 0029 #include "settings.h" 0030 #include "core/pos.h" 0031 #include "core/move.h" 0032 #include "core/item.h" 0033 #include "rules/chessrules.h" 0034 #include "ui_promotiondialog.h" 0035 0036 #include <KGameGraphicsViewRenderer> 0037 0038 #include <QDialog> 0039 #include <QDialogButtonBox> 0040 #include <QDrag> 0041 #include <QGraphicsSceneMouseEvent> 0042 #include <QMimeData> 0043 #include <QPushButton> 0044 #include <QtMath> 0045 0046 using namespace Knights; 0047 0048 const qreal backgroundZValue = -3.0; 0049 const qreal borderZValue = -2.0; 0050 const qreal notationZValue = -1.0; 0051 const qreal tileZValue = 0.0; 0052 const qreal pieceZValue = 1.0; 0053 const qreal legalMarkerZValue = 3.0; 0054 const qreal dragZValue = 4.0; 0055 0056 const QString backgroundKey = QStringLiteral ( "Background" ); 0057 const QString whiteTileKey = QStringLiteral ( "WhiteTile" ); 0058 const QString blackTileKey = QStringLiteral ( "BlackTile" ); 0059 const QString legalMarkerKey = QStringLiteral ( "Marker" ); 0060 const QString motionMarkerKey = QStringLiteral ( "Motion" ); 0061 const QString dangerMarkerKey = QStringLiteral ( "Danger" ); 0062 0063 const QString tbBorderKey = QStringLiteral ( "TopBottomBorder" ); 0064 const QString lrBorderKey = QStringLiteral ( "LeftRightBorder" ); 0065 const QString whiteLettersKey = QStringLiteral ( "WhiteLetters" ); 0066 const QString blackLettersKey = QStringLiteral ( "BlackLetters" ); 0067 const QString whiteNumbersKey = QStringLiteral ( "WhiteNumbers" ); 0068 const QString blackNumbersKey = QStringLiteral ( "BlackNumbers" ); 0069 0070 Board::Board(KGameThemeProvider* provider, QObject* parent) : QGraphicsScene(parent), 0071 m_rules(nullptr), 0072 m_background(nullptr), 0073 m_displayBorders(true), 0074 m_displayNotations(true), 0075 renderer(nullptr), 0076 m_themeProvider(provider), 0077 m_dragActive(false), 0078 draggedPiece(nullptr), 0079 selectedPiece(nullptr), 0080 m_paused(false), 0081 m_animated(true), 0082 m_currentPlayer(White), 0083 m_displayedPlayer(NoColor), 0084 m_drawFrame(true) { 0085 0086 renderer = new KGameGraphicsViewRenderer(m_themeProvider); 0087 if (!Manager::self()->rules()) 0088 Manager::self()->setRules(new ChessRules); 0089 Manager::self()->rules()->setGrid(&m_grid); 0090 updateTheme(); 0091 0092 connect (provider, &KGameThemeProvider::currentThemeChanged, this, &Board::updateTheme); 0093 } 0094 0095 Board::~Board() { 0096 qDeleteAll(m_grid); 0097 qDeleteAll(m_tiles); 0098 qDeleteAll(markers); 0099 delete renderer; 0100 //TODO: this crashes the application, s.a. BUG 405763 0101 //delete Manager::self()->rules(); 0102 } 0103 0104 void Board::addPiece(PieceType type, Color color, const Pos& pos) { 0105 Piece* t_piece = new Piece ( renderer, type, color, this, pos ); 0106 if ( Settings::animationSpeed() != Settings::EnumAnimationSpeed::Instant ) 0107 t_piece->setPos ( mapToScene ( Pos ( ( pos.first > 4 ) ? 5 : 4, ( pos.second > 4 ) ? 5 : 4 ) ) ); 0108 t_piece->setZValue ( pieceZValue ); 0109 m_grid.insert ( pos, t_piece ); 0110 } 0111 0112 void Board::movePiece(const Move& move) { 0113 qCDebug(LOG_KNIGHTS) << move; 0114 Move m = move; 0115 if ( ( m.flag ( Move::Illegal ) && !m.flag ( Move::Forced ) ) || m.to() == m.from() || !m_grid.contains ( m.from() ) ) { 0116 qCWarning(LOG_KNIGHTS) << "Invalid move:" << m; 0117 return; 0118 } 0119 if ( !m.flag ( Move::Forced ) && 0120 ( m_grid[m.from()]->color() != m_currentPlayer || !Manager::self()->rules()->legalMoves(m.from()).contains(m) ) ) { 0121 qCWarning(LOG_KNIGHTS) << "Move not allowed:" << m; 0122 return; 0123 } 0124 qDeleteAll ( markers ); 0125 markers.clear(); 0126 if ( m.flag(Move::Promote) ) 0127 m_grid[m.from() ]->setPieceType ( m.promotedType() ? m.promotedType() : Queen ); 0128 0129 PieceDataMap map = m.removedPieces(); 0130 PieceDataMap::const_iterator it = map.constBegin(); 0131 PieceDataMap::const_iterator end = map.constEnd(); 0132 for ( ; it != end; ++it ) { 0133 delete m_grid.value ( it.key(), nullptr ); 0134 m_grid.remove ( it.key() ); 0135 } 0136 0137 centerOnPos ( m_grid.value ( m.from() ), m.to() ); 0138 m_grid.insert ( m.to(), m_grid.take ( m.from() ) ); 0139 0140 map = m.addedPieces(); 0141 it = map.constBegin(); 0142 end = map.constEnd(); 0143 for ( ; it != end; ++it ) 0144 addPiece ( it.value().second, it.value().first, it.key() ); 0145 0146 if ( m_playerColors & oppositeColor ( m_currentPlayer ) ) { 0147 // We only display motion and danger markers if the next player is a human 0148 if ( Settings::showMotion() ) { 0149 addMarker ( m.from(), Motion ); 0150 addMarker ( m.to(), Motion ); 0151 } 0152 if ( Settings::showDanger() ) { 0153 bool check = false; 0154 for ( Piece* piece : std::as_const(m_grid) ) { 0155 if ( piece->color() == m_currentPlayer && Manager::self()->rules()->isAttacking ( piece->boardPos() ) ) { 0156 check = true; 0157 addMarker ( piece->boardPos(), Danger ); 0158 } 0159 } 0160 if ( check ) { 0161 for ( Piece* piece : std::as_const(m_grid) ) { 0162 if ( piece->color() != m_currentPlayer && piece->pieceType() == King ) 0163 addMarker ( piece->boardPos(), Danger ); 0164 } 0165 } 0166 } 0167 } 0168 0169 for ( const Move& additionalMove : m.additionalMoves() ) 0170 movePiece ( additionalMove ); 0171 0172 updateGraphics(); 0173 } 0174 0175 void Board::populate() { 0176 const PieceDataMap pieces = Manager::self()->rules()->startingPieces(); 0177 PieceDataMap::const_iterator it = pieces.constBegin(); 0178 PieceDataMap::const_iterator end = pieces.constEnd(); 0179 for ( ; it != end; ++it ) 0180 addPiece ( it.value().second, it.value().first, it.key() ); 0181 updateGraphics(); 0182 } 0183 0184 void Board::addTiles() { 0185 if ( !m_tiles.isEmpty() ) { 0186 qCWarning(LOG_KNIGHTS) << "Tiles are already present, delete them first"; 0187 return; 0188 } 0189 for ( int i = 1; i < 9; ++i ) { 0190 for ( int j = 1; j < 9; ++j ) { 0191 QString key = ( ( i + j ) % 2 == 0 ) ? blackTileKey : whiteTileKey; 0192 Item* tile = new Item ( renderer, key, this, Pos ( i, j ) ); 0193 tile->setZValue ( tileZValue ); 0194 m_tiles.insert ( Pos ( i, j ), tile ); 0195 } 0196 } 0197 } 0198 0199 void Board::mousePressEvent(QGraphicsSceneMouseEvent* e) { 0200 if ( !Manager::self()->canLocalMove() ) { 0201 // It is not the human player's turn 0202 e->ignore(); 0203 return; 0204 } 0205 0206 Piece* d_piece = pieceAt ( e->scenePos() ); 0207 if ( !d_piece || d_piece->color() != m_currentPlayer ) { 0208 // The piece doesn't belong to the player whose turn it is, or there is no piece 0209 if ( !selectedPiece ) { 0210 e->ignore(); 0211 return; 0212 } 0213 Pos from = selectedPiece->boardPos(); 0214 Pos to = mapFromScene ( e->scenePos() ); 0215 if ( Manager::self()->rules()->legalMoves ( from ).contains ( Move ( from, to ) ) ) { 0216 Move move ( from, to ); 0217 move.setFlag ( Move::Take, m_grid.contains ( to ) ); 0218 0219 if ( m_grid[from]->pieceType() == Pawn && ( to.second == 1 || to.second == 8 ) ) { 0220 move.setFlag ( Move::Promote, true ); 0221 move.setPromotedType ( getPromotedType() ); 0222 } 0223 Q_EMIT pieceMoved(move); 0224 selectedPiece = nullptr; 0225 } 0226 } else { 0227 // The active player clicked on his/her own piece 0228 if (d_piece != selectedPiece) { 0229 qDeleteAll ( markers ); 0230 markers.clear(); 0231 0232 selectedPiece = d_piece; 0233 0234 Pos t_pos = mapFromScene ( e->scenePos() ); 0235 QList<Move> t_legalMoves = Manager::self()->rules()->legalMoves ( t_pos ); 0236 if ( t_legalMoves.isEmpty() ) { 0237 e->ignore(); 0238 return; 0239 } 0240 d_piece->setZValue ( dragZValue ); 0241 if ( Settings::showMarker() ) { 0242 for ( const Move& t_move : std::as_const(t_legalMoves) ) 0243 addMarker ( t_move.to(), LegalMove ); 0244 } 0245 draggedPiece = d_piece; 0246 } 0247 m_draggedPos = e->scenePos(); 0248 dragStartPoint = e->screenPos(); 0249 } 0250 } 0251 0252 void Board::mouseReleaseEvent(QGraphicsSceneMouseEvent* e) { 0253 Q_UNUSED(e); 0254 draggedPiece = nullptr; 0255 } 0256 0257 void Board::mouseMoveEvent(QGraphicsSceneMouseEvent* e) { 0258 if (!(e->buttons() & Qt::LeftButton) || m_dragActive) 0259 return; 0260 if (draggedPiece && ((e->screenPos() - dragStartPoint).manhattanLength() >= QApplication::startDragDistance()) ) { 0261 //initiate a new drag event 0262 drag = new QDrag ( e->widget() ); 0263 drag->setMimeData ( new QMimeData() ); 0264 m_dragActive = true; 0265 selectedPiece = nullptr; 0266 drag->exec(); 0267 } 0268 } 0269 0270 void Board::dragLeaveEvent(QGraphicsSceneDragDropEvent* e) { 0271 Q_UNUSED(e); 0272 if ( !m_dragActive ) 0273 return; 0274 0275 qDeleteAll(markers); 0276 markers.clear(); 0277 centerOnPos(draggedPiece); 0278 draggedPiece->setZValue(pieceZValue); 0279 draggedPiece = nullptr; 0280 m_dragActive = false; 0281 } 0282 0283 void Board::dropEvent(QGraphicsSceneDragDropEvent* e) { 0284 qDeleteAll(markers); 0285 markers.clear(); 0286 0287 if (draggedPiece) { 0288 m_dragActive = false; 0289 Pos from = draggedPiece->boardPos(); 0290 Pos to = mapFromScene ( e->scenePos() ); 0291 Move move ( from, to ); 0292 if ( !Manager::self()->rules()->legalMoves ( from ).contains ( move ) ) 0293 centerOnPos ( draggedPiece ); 0294 else { 0295 if ( m_grid[from]->pieceType() == Pawn && ( to.second == 1 || to.second == 8 ) ) { 0296 move.setFlag ( Move::Promote, true ); 0297 move.setPromotedType ( getPromotedType() ); 0298 } 0299 Q_EMIT pieceMoved(move); 0300 } 0301 draggedPiece->setZValue(pieceZValue); 0302 draggedPiece = nullptr; 0303 } 0304 } 0305 0306 void Board::dragEnterEvent(QGraphicsSceneDragDropEvent* e) { 0307 e->setAccepted(Manager::self()->canLocalMove()); 0308 } 0309 0310 void Board::dragMoveEvent(QGraphicsSceneDragDropEvent* e) { 0311 if ( !draggedPiece ) { 0312 e->ignore(); 0313 return; 0314 } 0315 e->accept(); 0316 qreal x = e->scenePos().x() - m_draggedPos.x(); 0317 qreal y = e->scenePos().y() - m_draggedPos.y(); 0318 0319 draggedPiece->moveBy ( x, y ); 0320 m_draggedPos = e->scenePos(); 0321 } 0322 0323 Piece* Board::pieceAt(const QPointF& point) { 0324 return m_grid.value(mapFromScene(point), nullptr); 0325 } 0326 0327 Pos Board::mapFromScene(const QPointF& point) { 0328 Pos pos; 0329 pos.first = ( point.x() - m_boardRect.left() ) / m_tileSize + 1; 0330 pos.second = 1 - ( point.y() - m_boardRect.bottom() ) / m_tileSize; 0331 if ( m_displayedPlayer != White ) 0332 pos = Pos ( 9, 9 ) - pos; 0333 return pos; 0334 } 0335 0336 QPointF Board::mapToScene(Pos pos) { 0337 if ( m_displayedPlayer != White ) 0338 pos = Pos ( 9, 9 ) - pos; 0339 QPointF point; 0340 point.setX ( m_boardRect.left() + ( pos.first - 1 ) * m_tileSize ); 0341 point.setY ( m_boardRect.bottom() - pos.second * m_tileSize ); 0342 return point; 0343 } 0344 0345 void Board::centerOnPos(Item* item, const Pos& pos, bool animated) { 0346 item->setBoardPos(pos); 0347 centerOnPos(item, animated); 0348 } 0349 0350 void Board::centerOnPos(Item* item, bool animated) { 0351 item->move(mapToScene(item->boardPos()), m_tileSize, animated); 0352 } 0353 0354 void Board::centerAndResize(Item* item, QSize size, bool animated) { 0355 item->moveAndResize(mapToScene ( item->boardPos() ), m_tileSize, size, animated); 0356 } 0357 0358 bool Board::isInBoard(const Pos& pos) { 0359 return pos.first > 0 && pos.first < 9 && pos.second > 0 && pos.second < 9; 0360 } 0361 0362 void Board::setPlayerColors(Colors colors) { 0363 m_playerColors = colors; 0364 if ( m_playerColors & m_currentPlayer ) 0365 m_displayedPlayer = m_currentPlayer; 0366 else { 0367 if ( m_playerColors == Black ) 0368 m_displayedPlayer = Black; 0369 else 0370 m_displayedPlayer = White; 0371 } 0372 changeDisplayedPlayer(); 0373 populate(); 0374 } 0375 0376 void Board::setCurrentColor(Color color) { 0377 m_currentPlayer = color; 0378 Color nextPlayer = m_displayedPlayer; 0379 if ( ( ( m_playerColors & (Black|White) ) == (Black|White) ) && !Settings::flipBoard() ) 0380 nextPlayer = White; 0381 else if ( m_playerColors & color ) 0382 nextPlayer = color; 0383 if ( m_displayedPlayer != nextPlayer ) { 0384 m_displayedPlayer = nextPlayer; 0385 changeDisplayedPlayer(); 0386 } 0387 Q_EMIT activePlayerChanged ( m_currentPlayer ); 0388 } 0389 0390 0391 void Board::addMarker(const Pos& pos, MarkerType type) { 0392 QString key; 0393 switch ( type ) { 0394 case LegalMove: 0395 key = legalMarkerKey; 0396 break; 0397 case Danger: 0398 key = dangerMarkerKey; 0399 break; 0400 case Motion: 0401 key = motionMarkerKey; 0402 break; 0403 } 0404 addMarker ( pos, key ); 0405 } 0406 0407 void Board::addMarker(const Pos& pos, const QString& spriteKey) { 0408 if ( markers.contains ( pos ) ) { 0409 // Prevent two markers (usually Motion and Danger) from being on the same square 0410 delete markers[pos]; 0411 } 0412 Item* marker = new Item ( renderer, spriteKey, this, pos ); 0413 centerOnPos ( marker, false ); 0414 marker->setRenderSize ( QSizeF ( m_tileSize, m_tileSize ).toSize() ); 0415 marker->setZValue ( legalMarkerZValue ); 0416 markers.insert ( pos, marker ); 0417 } 0418 0419 void Board::updateTheme() { 0420 delete m_background; 0421 qDebug()<<"background key " << backgroundKey; 0422 if ( renderer->spriteExists ( backgroundKey ) ) { 0423 m_background = new Item ( renderer, backgroundKey, this, Pos() ); 0424 m_background->setZValue ( backgroundZValue ); 0425 } else 0426 m_background = nullptr; 0427 0428 qDeleteAll ( m_borders ); 0429 m_borders.clear(); 0430 qDeleteAll ( m_notations ); 0431 m_notations.clear(); 0432 m_displayBorders = Settings::borderDisplayType() != Settings::EnumBorderDisplayType::None 0433 && renderer->spriteExists ( lrBorderKey ) 0434 && renderer->spriteExists ( tbBorderKey ); 0435 m_displayNotations = Settings::borderDisplayType() == Settings::EnumBorderDisplayType::Notation 0436 && renderer->spriteExists ( whiteLettersKey ) 0437 && renderer->spriteExists ( blackLettersKey ) 0438 && renderer->spriteExists ( whiteNumbersKey ) 0439 && renderer->spriteExists ( blackNumbersKey ); 0440 if ( m_displayBorders ) { 0441 m_borders << new Item ( renderer, tbBorderKey, this, Pos() ); 0442 0443 Item *tItem = new Item ( renderer, lrBorderKey, this, Pos() ); 0444 tItem->setRotation ( 180 ); 0445 m_borders << tItem; 0446 0447 tItem = new Item ( renderer, tbBorderKey, this, Pos() ); 0448 tItem->setRotation ( 180 ); 0449 m_borders << tItem; 0450 0451 m_borders << new Item ( renderer, lrBorderKey, this, Pos() ); 0452 for ( Item* item : std::as_const(m_borders) ) 0453 item->setZValue ( borderZValue ); 0454 } 0455 if ( m_displayNotations ) { 0456 QString lettersKey; 0457 QString numbersKey; 0458 if ( m_displayedPlayer == White ) { 0459 lettersKey = whiteLettersKey; 0460 numbersKey = whiteNumbersKey; 0461 } else { 0462 lettersKey = blackLettersKey; 0463 numbersKey = blackNumbersKey; 0464 } 0465 m_notations << new Item ( renderer, lettersKey, this, Pos() ); 0466 m_notations << new Item ( renderer, numbersKey, this, Pos() ); 0467 m_notations << new Item ( renderer, lettersKey, this, Pos() ); 0468 m_notations << new Item ( renderer, numbersKey, this, Pos() ); 0469 for ( Item* item : std::as_const(m_notations) ) 0470 item->setZValue ( notationZValue ); 0471 } 0472 addTiles(); 0473 updateGraphics(); 0474 } 0475 0476 void Board::updateGraphics() { 0477 if ( m_background ) 0478 m_background->setRenderSize ( sceneRect().size().toSize() ); 0479 QSizeF tileSize = renderer->boundsOnSprite ( whiteTileKey ).size(); 0480 QSizeF boardSize = 8 * tileSize; 0481 qreal sideMargin; 0482 qreal topMargin; 0483 if ( m_displayBorders ) { 0484 sideMargin = renderer->boundsOnSprite ( lrBorderKey ).width(); 0485 topMargin = renderer->boundsOnSprite ( tbBorderKey ).height(); 0486 } else { 0487 sideMargin = 0.0; 0488 topMargin = 0.0; 0489 } 0490 boardSize = boardSize + 2 * QSize ( sideMargin, topMargin ); 0491 qreal ratio = qMin ( sceneRect().width() / boardSize.width(), sceneRect().height() / boardSize.height() ); 0492 sideMargin *= ratio; 0493 topMargin *= ratio; 0494 0495 QSizeF tpSize = tileSize * ratio; 0496 m_tileSize = qFloor ( qMin ( tpSize.width(), tpSize.height() ) ); 0497 /* 0498 if ( m_displayBorders ) 0499 { 0500 if ( m_tileSize % 2 ) 0501 { 0502 m_tileSize -= 1; 0503 } 0504 sideMargin = m_tileSize / 2; 0505 topMargin = m_tileSize / 2; 0506 } 0507 */ 0508 0509 QSize hBorderSize = QSize ( 8 * m_tileSize + 2 * qRound ( sideMargin ), qRound ( topMargin ) ); 0510 QSize vBorderSize = QSize ( qRound ( sideMargin ), 8 * m_tileSize ); 0511 int hBorderMargin = qRound ( topMargin ); 0512 int vBorderMargin = qRound ( sideMargin ); 0513 0514 0515 sideMargin = qMax ( sideMargin, ( sceneRect().width() - 8 * m_tileSize ) / 2 ); 0516 topMargin = qMax ( topMargin, ( sceneRect().height() - 8 * m_tileSize ) / 2 ); 0517 m_boardRect = QRect( sceneRect().topLeft().toPoint() + QPoint( sideMargin, topMargin ), 0518 QSize( m_tileSize, m_tileSize ) * 8); 0519 0520 QSize tSize = QSizeF ( m_tileSize, m_tileSize ).toSize(); 0521 /* 0522 * For historical reasons, QRect's 0523 */ 0524 QPointF topBorderPoint = m_boardRect.topRight() + QPoint ( vBorderMargin, 0 ); 0525 QPointF rightBorderPoint = m_boardRect.bottomRight() + QPoint ( vBorderMargin, 0 ); 0526 QPointF bottomBorderPoint = m_boardRect.bottomLeft() - QPoint ( vBorderMargin, 0 ); 0527 QPointF leftBorderPoint = m_boardRect.topLeft() - QPoint ( vBorderMargin, 0 ); 0528 0529 for ( Piece* p : std::as_const(m_grid) ) 0530 centerAndResize ( p, tSize ); 0531 for ( Item* t : std::as_const(m_tiles) ) 0532 centerAndResize ( t, tSize, Settings::animateBoard() ); 0533 for ( Item* t : std::as_const(markers) ) 0534 centerAndResize ( t, tSize ); 0535 if ( m_displayBorders ) { 0536 m_borders[0]->moveAndResize ( bottomBorderPoint, m_tileSize, hBorderSize, Settings::animateBoard() ); 0537 m_borders[1]->moveAndResize ( rightBorderPoint, m_tileSize, vBorderSize, Settings::animateBoard() ); 0538 m_borders[2]->moveAndResize ( topBorderPoint, m_tileSize, hBorderSize, Settings::animateBoard() ); 0539 m_borders[3]->moveAndResize ( leftBorderPoint, m_tileSize, vBorderSize, Settings::animateBoard() ); 0540 } 0541 if ( m_displayNotations ) { 0542 m_notations[0]->moveAndResize ( bottomBorderPoint, m_tileSize, hBorderSize, Settings::animateBoard() ); 0543 m_notations[1]->moveAndResize ( m_boardRect.topRight(), m_tileSize, vBorderSize, Settings::animateBoard() ); 0544 m_notations[2]->moveAndResize ( m_boardRect.topLeft() - QPointF ( vBorderMargin, hBorderMargin ), m_tileSize, hBorderSize, Settings::animateBoard() ); 0545 m_notations[3]->moveAndResize ( leftBorderPoint, m_tileSize, vBorderSize, Settings::animateBoard() ); 0546 } 0547 } 0548 0549 void Board::changeDisplayedPlayer() { 0550 for ( Piece* p : std::as_const(m_grid) ) 0551 centerOnPos ( p ); 0552 for ( Item* i : std::as_const(markers) ) 0553 centerOnPos ( i ); 0554 if ( Settings::animateBoard() ) { 0555 for ( Item* i : std::as_const(m_tiles) ) 0556 centerOnPos ( i ); 0557 } 0558 if ( m_displayNotations ) { 0559 if ( m_displayedPlayer == White ) { 0560 m_notations[0]->setSpriteKey ( whiteLettersKey ); 0561 m_notations[1]->setSpriteKey ( whiteNumbersKey ); 0562 m_notations[2]->setSpriteKey ( whiteLettersKey ); 0563 m_notations[3]->setSpriteKey ( whiteNumbersKey ); 0564 } else { 0565 m_notations[0]->setSpriteKey ( blackLettersKey ); 0566 m_notations[1]->setSpriteKey ( blackNumbersKey ); 0567 m_notations[2]->setSpriteKey ( blackLettersKey ); 0568 m_notations[3]->setSpriteKey ( blackNumbersKey ); 0569 } 0570 } 0571 Q_EMIT displayedPlayerChanged(m_displayedPlayer); 0572 } 0573 0574 PieceType Board::getPromotedType() { 0575 PieceType piece = Queen; 0576 QPointer<QDialog> dialog = new QDialog(); 0577 dialog->setWindowTitle(i18nc("@title:window", "Promotion")); 0578 QWidget *widget = new QWidget(); 0579 QVBoxLayout *layout = new QVBoxLayout(); 0580 QDialogButtonBox *bBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); 0581 bBox->button(QDialogButtonBox::Ok)->setText(i18n("Promote")); 0582 bBox->button(QDialogButtonBox::Ok)->setDefault(true); 0583 0584 Ui::PromotionWidget ui; 0585 ui.setupUi ( widget ); 0586 0587 layout->addWidget ( widget ); 0588 layout->addWidget ( bBox ); 0589 dialog->setLayout ( layout ); 0590 0591 connect (bBox, &QDialogButtonBox::accepted, dialog, &QDialog::accept); 0592 connect (bBox, &QDialogButtonBox::rejected, dialog, &QDialog::reject); 0593 0594 if ( dialog->exec() == QDialog::Accepted ) { 0595 if ( ui.radioButtonKnight->isChecked() ) 0596 piece = Knight; 0597 else if ( ui.radioButtonBishop->isChecked() ) 0598 piece = Bishop; 0599 else if ( ui.radioButtonRook->isChecked() ) 0600 piece = Rook; 0601 } 0602 delete dialog; 0603 return piece; 0604 } 0605 0606 #include "moc_board.cpp"