File indexing completed on 2024-03-24 04:05:16

0001 /*
0002     SPDX-FileCopyrightText: 2019 Christian Krippendorf <Coding@Christian-Krippendorf.de>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 // own
0008 #include "gameremovedtiles.h"
0009 #include "gamedata.h"
0010 
0011 // Qt
0012 #include <QGraphicsSceneMouseEvent>
0013 #include <QPainter>
0014 #include <QPixmap>
0015 
0016 // KF
0017 #include <KLocalizedString>
0018 
0019 // LibKMahjongg
0020 #include <KMahjonggTileset>
0021 
0022 
0023 GameRemovedTiles::GameRemovedTiles(QGraphicsObject * object)
0024     : QGraphicsObject(object)
0025     , m_width(100)
0026     , m_height(100)
0027     , m_borderWidthFrac(0.05)
0028     , m_tileScale(0.9)
0029     , m_titleHeightFrac(0.1)
0030     , m_borderWidthPixel(0)
0031     , m_titleHeightPixel(0)
0032     , m_tileSpaceRow(0)
0033     , m_tileSpaceCol(0)
0034     , m_tileFaceWidth(0)
0035     , m_tileFaceHeight(0)
0036     , m_faceScale(1.0)
0037     , m_tileFaceWidthScaled(0)
0038     , m_tileFaceHeightScaled(0)
0039     , m_maxTilesRow(0)
0040     , m_maxTilesCol(0)
0041     , m_itemFaces(new QList<USHORT>())
0042     , m_tiles(nullptr)
0043     , m_gameData(nullptr)
0044 {
0045 }
0046 
0047 GameRemovedTiles::~GameRemovedTiles()
0048 {
0049     delete m_itemFaces;
0050 }
0051 
0052 void GameRemovedTiles::setSize(qreal width, qreal height)
0053 {
0054     m_width = width;
0055     m_height = height;
0056 }
0057 
0058 void GameRemovedTiles::setTileset(KMahjonggTileset * tiles)
0059 {
0060     m_tiles = tiles;
0061 }
0062 
0063 void GameRemovedTiles::prepareForGeometryChange()
0064 {
0065     prepareGeometryChange();
0066 }
0067 
0068 void GameRemovedTiles::setGameData(GameData * gameData)
0069 {
0070     m_gameData = gameData;
0071 }
0072 
0073 void GameRemovedTiles::updateTileCalculations()
0074 {
0075     int maxTilesRow = 0;
0076     int maxTilesCol = 0;
0077 
0078     // Get the height and the width of the face tile. This has to be multiplied
0079     // by two, cause the value is related to half tile. (half positioning)
0080     m_tileFaceWidth = m_tiles->qWidth() * 2.0;
0081     m_tileFaceHeight = m_tiles->qHeight() * 2.0;
0082     m_tileFaceWidthScaled = m_tileFaceWidth * m_faceScale;
0083     m_tileFaceHeightScaled = m_tileFaceHeight * m_faceScale;
0084 
0085     m_borderWidthPixel = m_borderWidthFrac * m_width;
0086     m_titleHeightPixel = m_titleHeightFrac * m_height;
0087 
0088     maxTilesRow = static_cast<int>(
0089         (m_width - 2 * m_borderWidthPixel) / m_tileFaceWidthScaled
0090     );
0091     maxTilesCol = static_cast<int>(
0092         (m_height - 2 * m_borderWidthPixel - m_titleHeightPixel) /
0093         m_tileFaceHeightScaled
0094     );
0095 
0096     m_tileSpaceRow = ((m_width - 2 * m_borderWidthPixel) - 
0097         maxTilesRow * m_tileFaceWidthScaled) / (maxTilesRow - 1);
0098     m_tileSpaceCol = ((m_height - 
0099         2 * m_borderWidthPixel - m_titleHeightPixel) -
0100         maxTilesCol * m_tileFaceHeightScaled) / (maxTilesCol - 1);
0101 
0102     m_maxTilesRow = maxTilesRow;
0103     m_maxTilesCol = maxTilesCol;
0104 }
0105 
0106 void GameRemovedTiles::paint(QPainter *painter, const QStyleOptionGraphicsItem *, 
0107     QWidget *)
0108 {
0109     updateTileCalculations();
0110 
0111     // General painter settings.
0112     painter->setRenderHint(QPainter::Antialiasing);
0113 
0114     // Paint the background.
0115     painter->setOpacity(0.5);
0116     QPainterPath path;
0117     path.addRoundedRect(QRectF(0, 0, m_width, m_height), 10, 10);
0118     painter->fillPath(path, Qt::black);
0119 
0120     // Paint the title text.
0121     painter->setPen(Qt::white);
0122     QFont font(painter->font());
0123     font.setPointSize(m_titleHeightPixel * 0.15);
0124     painter->setFont(font);
0125     painter->drawText(
0126         QRectF(m_borderWidthPixel, m_borderWidthPixel, m_width, m_titleHeightPixel),
0127         i18n("Removed tiles")
0128     );
0129 
0130     // Exit if no tileset has been set to this object.
0131     if (m_tiles == nullptr || m_itemFaces->isEmpty()) {
0132         return;
0133     }
0134 
0135     // Paint all the tiles.
0136     painter->setPen(QPen(Qt::white, 10));
0137 
0138     unsigned int row = 0;
0139     unsigned int col = 0;
0140     int start = m_itemFaces->size() - (m_maxTilesCol * m_maxTilesRow * 2);
0141     if (start < 0) {
0142         start *= 0;
0143     }
0144     for (int pos = start; pos < m_itemFaces->size() - 1; pos+=2) {
0145         if (col >= m_maxTilesRow) {
0146             row++;
0147             col = 0;
0148         }
0149 
0150         // Get the pixmap of the face.
0151         QPixmap face;
0152         face = m_tiles->tileface(m_itemFaces->at(pos));
0153         face = face.scaledToHeight(
0154             m_tileFaceHeightScaled, Qt::SmoothTransformation
0155         );
0156 
0157         // Paint the background of the face.
0158         QPainterPath pixPath;
0159         pixPath.addRoundedRect(
0160             QRectF(
0161                 m_borderWidthPixel + col * m_tileSpaceRow + col * m_tileFaceWidth, 
0162                 m_titleHeightPixel + row * m_tileSpaceCol + row * m_tileFaceHeight,
0163                 m_tileFaceWidth, m_tileFaceHeight
0164             ), 10, 10
0165         );
0166         painter->setOpacity(1.0 - (m_itemFaces->size() - pos) / 100.0);
0167         painter->fillPath(pixPath, Qt::white);
0168 
0169         // Paint the pixmap of the face.
0170         painter->setOpacity(1.0 - (m_itemFaces->size() - pos) / 100.0);
0171         painter->drawPixmap(
0172             QPointF(
0173                 m_borderWidthPixel + col * m_tileSpaceRow + col * m_tileFaceWidth,
0174                 m_titleHeightPixel + row * m_tileSpaceCol + row * m_tileFaceHeight
0175             ), face
0176         );
0177 
0178         col++;
0179     }
0180 }
0181 
0182 void GameRemovedTiles::undo()
0183 {
0184     if (m_itemFaces->size() >= 2) {
0185         m_itemFaces->removeLast();
0186         m_itemFaces->removeLast();
0187     }
0188 }
0189 
0190 void GameRemovedTiles::reset()
0191 {
0192     m_itemFaces->clear();
0193 }
0194 
0195 QRectF GameRemovedTiles::boundingRect() const
0196 {
0197     return QRectF(QPointF(0.0, 0.0), QSizeF(m_width, m_height));
0198 }
0199 
0200 QRectF GameRemovedTiles::rect() const
0201 {
0202     return boundingRect();
0203 }
0204 
0205 void GameRemovedTiles::addItem(const POSITION & itemPos) 
0206 {
0207     m_itemFaces->append(itemPos.f);
0208 }
0209 
0210 void GameRemovedTiles::removeLastItem()
0211 {
0212     m_itemFaces->removeLast();
0213 }
0214 
0215 #include "moc_gameremovedtiles.cpp"