1 // This file is part of Dust Racing 2D.
2 // Copyright (C) 2011 Jussi Lind <jussi.lind@iki.fi>
3 //
4 // Dust Racing 2D is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 // Dust Racing 2D is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with Dust Racing 2D. If not, see <http://www.gnu.org/licenses/>.
15
16 #include "tracktile.hpp"
17 #include "mainwindow.hpp"
18 #include "tileanimator.hpp"
19
20 #include "../common/config.hpp"
21
22 #include <QAction>
23 #include <QGraphicsLineItem>
24 #include <QGraphicsScene>
25 #include <QGraphicsView>
26 #include <QPainter>
27
28 TrackTile * TrackTile::m_activeTile = nullptr;
29
TrackTile(QPointF location,QPoint matrixLocation,const QString & type)30 TrackTile::TrackTile(QPointF location, QPoint matrixLocation, const QString & type)
31 : TrackTileBase(location, matrixLocation, type)
32 , m_size(QSizeF(width(), height()))
33 , m_active(false)
34 , m_animator(new TileAnimator(this))
35 , m_added(false)
36 {
37 setPos(location);
38 }
39
TrackTile(const TrackTile & other)40 TrackTile::TrackTile(const TrackTile & other)
41 : QGraphicsItem()
42 , TrackTileBase(other.location(), other.matrixLocation(), other.tileType())
43 , m_size(other.m_size)
44 , m_active(false)
45 , m_animator(new TileAnimator(this))
46 , m_added(false)
47 {
48 setPos(other.location());
49 setRotation(other.rotation());
50 setComputerHint(other.computerHint());
51 setExcludeFromMinimap(other.excludeFromMinimap());
52 }
53
boundingRect() const54 QRectF TrackTile::boundingRect() const
55 {
56 return QRectF(-m_size.width() / 2, -m_size.height() / 2, m_size.width(), m_size.height());
57 }
58
paint(QPainter * painter,const QStyleOptionGraphicsItem * option,QWidget * widget)59 void TrackTile::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget)
60 {
61 Q_UNUSED(widget)
62 Q_UNUSED(option)
63
64 painter->save();
65
66 QPen pen;
67 pen.setJoinStyle(Qt::MiterJoin);
68
69 // Render the tile pixmap if tile is not cleared.
70 if (tileType() != "clear")
71 {
72 painter->drawPixmap(static_cast<int>(boundingRect().x()), static_cast<int>(boundingRect().y()),
73 static_cast<int>(boundingRect().width()), static_cast<int>(boundingRect().height()),
74 m_pixmap);
75
76 // Mark the tile if it has computer hints set
77 if (computerHint() == TrackTile::ComputerHint::BrakeHard)
78 {
79 painter->fillRect(boundingRect(), QBrush(QColor(255, 0, 0, 128)));
80 }
81 else if (computerHint() == TrackTile::ComputerHint::Brake)
82 {
83 painter->fillRect(boundingRect(), QBrush(QColor(128, 0, 0, 128)));
84 }
85 }
86 else
87 {
88 painter->drawPixmap(static_cast<int>(boundingRect().x()), static_cast<int>(boundingRect().y()),
89 static_cast<int>(boundingRect().width()), static_cast<int>(boundingRect().height()),
90 QPixmap(Config::Editor::CLEAR_ICON_PATH));
91
92 pen.setColor(QColor(0, 0, 0));
93 painter->setPen(pen);
94 painter->drawRect(boundingRect());
95 }
96
97 // Render highlight
98 if (m_active)
99 {
100 painter->fillRect(boundingRect(), QBrush(QColor(0, 0, 0, 64)));
101 }
102
103 painter->restore();
104 }
105
setActive(bool active)106 void TrackTile::setActive(bool active)
107 {
108 m_active = active;
109
110 if (active && TrackTile::m_activeTile != this)
111 {
112 if (TrackTile::m_activeTile)
113 {
114 TrackTile::m_activeTile->setActive(false);
115 }
116
117 TrackTile::m_activeTile = this;
118 }
119
120 update();
121 }
122
setActiveTile(TrackTile * tile)123 void TrackTile::setActiveTile(TrackTile * tile)
124 {
125 if (tile)
126 {
127 tile->setActive(true);
128 }
129 else
130 {
131 if (activeTile())
132 {
133 activeTile()->setActive(false);
134 }
135
136 TrackTile::m_activeTile = nullptr;
137 }
138 }
139
activeTile()140 TrackTile * TrackTile::activeTile()
141 {
142 return TrackTile::m_activeTile;
143 }
144
rotate90CW()145 bool TrackTile::rotate90CW()
146 {
147 return m_animator->rotate90CW();
148 }
149
rotate90CCW()150 bool TrackTile::rotate90CCW()
151 {
152 return m_animator->rotate90CCW();
153 }
154
setTileType(const QString & type)155 void TrackTile::setTileType(const QString & type)
156 {
157 TrackTileBase::setTileType(type);
158 update();
159 }
160
setComputerHint(ComputerHint hint)161 void TrackTile::setComputerHint(ComputerHint hint)
162 {
163 TrackTileBase::setComputerHint(hint);
164 update();
165 }
166
setLocation(QPointF location)167 void TrackTile::setLocation(QPointF location)
168 {
169 TrackTileBase::setLocation(location);
170
171 setPos(location);
172 update();
173 }
174
pixmap() const175 QPixmap TrackTile::pixmap() const
176 {
177 return m_pixmap;
178 }
179
setPixmap(const QPixmap & pixmap)180 void TrackTile::setPixmap(const QPixmap & pixmap)
181 {
182 m_pixmap = pixmap;
183 update();
184 }
185
swap(TrackTile & other)186 void TrackTile::swap(TrackTile & other)
187 {
188 // Swap tile types
189 const auto sourceType = tileType();
190 setTileType(other.tileType());
191 other.setTileType(sourceType);
192
193 // Swap tile pixmaps
194 const auto sourcePixmap = pixmap();
195 setPixmap(other.pixmap());
196 other.setPixmap(sourcePixmap);
197
198 // Swap tile rotations
199 const auto sourceAngle = rotation();
200 setRotation(other.rotation());
201 other.setRotation(sourceAngle);
202
203 // Swap computer hints
204 const auto sourceHint = computerHint();
205 setComputerHint(other.computerHint());
206 other.setComputerHint(sourceHint);
207 }
208
setAdded(bool state)209 void TrackTile::setAdded(bool state)
210 {
211 m_added = state;
212 }
213
added() const214 bool TrackTile::added() const
215 {
216 return m_added;
217 }
218
~TrackTile()219 TrackTile::~TrackTile()
220 {
221 delete m_animator;
222 }
223