1 /*
2     SPDX-FileCopyrightText: 2019 Christian Krippendorf <Coding@Christian-Krippendorf.de>
3 
4     SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 // own
8 #include "gameremovedtiles.h"
9 #include "gamedata.h"
10 
11 // Qt
12 #include <QGraphicsSceneMouseEvent>
13 #include <QPainter>
14 #include <QPixmap>
15 
16 // KF
17 #include <KLocalizedString>
18 
19 // LibKMahjongg
20 #include <KMahjonggTileset>
21 
22 
GameRemovedTiles(QGraphicsObject * object)23 GameRemovedTiles::GameRemovedTiles(QGraphicsObject * object)
24     : QGraphicsObject(object)
25     , m_width(100)
26     , m_height(100)
27     , m_borderWidthFrac(0.05)
28     , m_tileScale(0.9)
29     , m_titleHeightFrac(0.1)
30     , m_borderWidthPixel(0)
31     , m_titleHeightPixel(0)
32     , m_tileSpaceRow(0)
33     , m_tileSpaceCol(0)
34     , m_tileFaceWidth(0)
35     , m_tileFaceHeight(0)
36     , m_faceScale(1.0)
37     , m_tileFaceWidthScaled(0)
38     , m_tileFaceHeightScaled(0)
39     , m_maxTilesRow(0)
40     , m_maxTilesCol(0)
41     , m_itemFaces(new QList<USHORT>())
42     , m_tiles(nullptr)
43     , m_gameData(nullptr)
44 {
45 }
46 
~GameRemovedTiles()47 GameRemovedTiles::~GameRemovedTiles()
48 {
49     delete m_itemFaces;
50 }
51 
setSize(qreal width,qreal height)52 void GameRemovedTiles::setSize(qreal width, qreal height)
53 {
54     m_width = width;
55     m_height = height;
56 }
57 
setTileset(KMahjonggTileset * tiles)58 void GameRemovedTiles::setTileset(KMahjonggTileset * tiles)
59 {
60     m_tiles = tiles;
61 }
62 
prepareForGeometryChange()63 void GameRemovedTiles::prepareForGeometryChange()
64 {
65     prepareGeometryChange();
66 }
67 
setGameData(GameData * gameData)68 void GameRemovedTiles::setGameData(GameData * gameData)
69 {
70     m_gameData = gameData;
71 }
72 
updateTileCalculations()73 void GameRemovedTiles::updateTileCalculations()
74 {
75     int maxTilesRow = 0;
76     int maxTilesCol = 0;
77 
78     // Get the height and the width of the face tile. This has to be multiplied
79     // by two, cause the value is related to half tile. (half positioning)
80     m_tileFaceWidth = m_tiles->qWidth() * 2.0;
81     m_tileFaceHeight = m_tiles->qHeight() * 2.0;
82     m_tileFaceWidthScaled = m_tileFaceWidth * m_faceScale;
83     m_tileFaceHeightScaled = m_tileFaceHeight * m_faceScale;
84 
85     m_borderWidthPixel = m_borderWidthFrac * m_width;
86     m_titleHeightPixel = m_titleHeightFrac * m_height;
87 
88     maxTilesRow = static_cast<int>(
89         (m_width - 2 * m_borderWidthPixel) / m_tileFaceWidthScaled
90     );
91     maxTilesCol = static_cast<int>(
92         (m_height - 2 * m_borderWidthPixel - m_titleHeightPixel) /
93         m_tileFaceHeightScaled
94     );
95 
96     m_tileSpaceRow = ((m_width - 2 * m_borderWidthPixel) -
97         maxTilesRow * m_tileFaceWidthScaled) / (maxTilesRow - 1);
98     m_tileSpaceCol = ((m_height -
99         2 * m_borderWidthPixel - m_titleHeightPixel) -
100         maxTilesCol * m_tileFaceHeightScaled) / (maxTilesCol - 1);
101 
102     m_maxTilesRow = maxTilesRow;
103     m_maxTilesCol = maxTilesCol;
104 }
105 
paint(QPainter * painter,const QStyleOptionGraphicsItem *,QWidget *)106 void GameRemovedTiles::paint(QPainter *painter, const QStyleOptionGraphicsItem *,
107     QWidget *)
108 {
109     updateTileCalculations();
110 
111     // General painter settings.
112     painter->setRenderHint(QPainter::Antialiasing);
113 
114     // Paint the background.
115     painter->setOpacity(0.5);
116     QPainterPath path;
117     path.addRoundedRect(QRectF(0, 0, m_width, m_height), 10, 10);
118     painter->fillPath(path, Qt::black);
119 
120     // Paint the title text.
121     painter->setPen(Qt::white);
122     QFont font(painter->font());
123     font.setPointSize(m_titleHeightPixel * 0.15);
124     painter->setFont(font);
125     painter->drawText(
126         QRectF(m_borderWidthPixel, m_borderWidthPixel, m_width, m_titleHeightPixel),
127         i18n("Removed tiles")
128     );
129 
130     // Exit if no tileset has been set to this object.
131     if (m_tiles == nullptr || m_itemFaces->isEmpty()) {
132         return;
133     }
134 
135     // Paint all the tiles.
136     painter->setPen(QPen(Qt::white, 10));
137 
138     unsigned int row = 0;
139     unsigned int col = 0;
140     int start = m_itemFaces->size() - (m_maxTilesCol * m_maxTilesRow * 2);
141     if (start < 0) {
142         start *= 0;
143     }
144     for (int pos = start; pos < m_itemFaces->size() - 1; pos+=2) {
145         if (col >= m_maxTilesRow) {
146             row++;
147             col = 0;
148         }
149 
150         // Get the pixmap of the face.
151         QPixmap face;
152         face = m_tiles->tileface(m_itemFaces->at(pos));
153         face = face.scaledToHeight(
154             m_tileFaceHeightScaled, Qt::SmoothTransformation
155         );
156 
157         // Paint the background of the face.
158         QPainterPath pixPath;
159         pixPath.addRoundedRect(
160             QRectF(
161                 m_borderWidthPixel + col * m_tileSpaceRow + col * m_tileFaceWidth,
162                 m_titleHeightPixel + row * m_tileSpaceCol + row * m_tileFaceHeight,
163                 m_tileFaceWidth, m_tileFaceHeight
164             ), 10, 10
165         );
166         painter->setOpacity(1.0 - (m_itemFaces->size() - pos) / 100.0);
167         painter->fillPath(pixPath, Qt::white);
168 
169         // Paint the pixmap of the face.
170         painter->setOpacity(1.0 - (m_itemFaces->size() - pos) / 100.0);
171         painter->drawPixmap(
172             QPointF(
173                 m_borderWidthPixel + col * m_tileSpaceRow + col * m_tileFaceWidth,
174                 m_titleHeightPixel + row * m_tileSpaceCol + row * m_tileFaceHeight
175             ), face
176         );
177 
178         col++;
179     }
180 }
181 
undo()182 void GameRemovedTiles::undo()
183 {
184     if (m_itemFaces->size() >= 2) {
185         m_itemFaces->removeLast();
186         m_itemFaces->removeLast();
187     }
188 }
189 
reset()190 void GameRemovedTiles::reset()
191 {
192     m_itemFaces->clear();
193 }
194 
boundingRect() const195 QRectF GameRemovedTiles::boundingRect() const
196 {
197     return QRectF(QPointF(0.0, 0.0), QSizeF(m_width, m_height));
198 }
199 
rect() const200 QRectF GameRemovedTiles::rect() const
201 {
202     return boundingRect();
203 }
204 
addItem(const POSITION & itemPos)205 void GameRemovedTiles::addItem(const POSITION & itemPos)
206 {
207     m_itemFaces->append(itemPos.f);
208 }
209 
removeLastItem()210 void GameRemovedTiles::removeLastItem()
211 {
212     m_itemFaces->removeLast();
213 }
214