File indexing completed on 2024-09-01 07:09:24
0001 /* 0002 SPDX-FileCopyrightText: 2003 Russell Steffen <rsteffen@bayarea.net> 0003 SPDX-FileCopyrightText: 2003 Stephan Zehetner <s.zehetner@nevox.org> 0004 SPDX-FileCopyrightText: 2008-2009 Dmitry Suzdalev <dimsuz@gmail.com> 0005 SPDX-FileCopyrightText: 2006 Inge Wallin <inge@lysator.liu.se> 0006 SPDX-FileCopyrightText: 2006 Pierre Ducroquet <pinaraf@gmail.com> 0007 SPDX-FileCopyrightText: 2011 Jeffrey Kelling <overlordapophis@gmail.com> 0008 0009 SPDX-License-Identifier: GPL-2.0-or-later 0010 */ 0011 0012 #include "mapitems.h" 0013 0014 #include <QAbstractTextDocumentLayout> 0015 #include <QBrush> 0016 #include <QGraphicsScene> 0017 #include <QPainter> 0018 #include <QTimer> 0019 0020 #include <KLocalizedString> 0021 #include <KColorScheme> 0022 0023 #include "mapscene.h" 0024 #include "map.h" 0025 #include "../planet.h" 0026 0027 /******************************** 0028 PlanetItem 0029 *******************************/ 0030 0031 PlanetItem::PlanetItem (MapScene *scene, Sector *sector, Game *game) 0032 : QGraphicsObject(), 0033 m_scene(scene), 0034 m_sector(sector), 0035 m_game(game), 0036 m_hovered(false), 0037 m_selected(false), 0038 m_blinkState(false) 0039 { 0040 if (m_sector->planet() != nullptr) { 0041 m_lookName = QStringLiteral("planet_%1").arg(m_sector->planet()->planetLook() + 1); 0042 } 0043 setAcceptHoverEvents(true); 0044 0045 m_blinkTimer = new QTimer(this); 0046 connect(m_blinkTimer, &QTimer::timeout, this, &PlanetItem::blinkPlanet); 0047 connect(m_sector, &Sector::update, this, &PlanetItem::updatePlanet); 0048 } 0049 0050 0051 void PlanetItem::updatePlanet() 0052 { 0053 Planet *planet = m_sector->planet(); 0054 if (planet != nullptr) { 0055 m_lookName = QStringLiteral("planet_%1").arg(planet->planetLook() + 1); 0056 update(); 0057 } 0058 } 0059 0060 0061 QRectF PlanetItem::boundingRect() const 0062 { 0063 qreal size = m_scene->getSectorSize(); 0064 return QRectF(m_sector->coord().y() * size + m_scene->itemsHorizontalOffset(), 0065 m_sector->coord().x() * size + m_scene->itemsVerticalOffset(), 0066 size, 0067 size); 0068 } 0069 0070 void PlanetItem::paint(QPainter *p, const QStyleOptionGraphicsItem * /*option*/, 0071 QWidget * /*widget*/) 0072 { 0073 if(!m_sector->planet()) 0074 return; 0075 // Display a frame around the planet 0076 if (!m_sector->planet()->player()->isNeutral()) { 0077 QBrush backBrush = p->brush(); 0078 0079 backBrush.setColor(m_sector->planet()->player()->color()); 0080 backBrush.setStyle(Qt::SolidPattern); 0081 0082 p->setOpacity(0.5); 0083 p->fillRect(boundingRect(), backBrush ); 0084 p->setOpacity(1); 0085 } 0086 0087 // Display the planet 0088 qreal sectorSize = m_scene->getSectorSize(); 0089 QPointF sectorTopLeft(m_sector->coord().y() * sectorSize + m_scene->itemsHorizontalOffset(), 0090 m_sector->coord().x() * sectorSize + m_scene->itemsVerticalOffset()); 0091 0092 QPixmap planetPix = renderPixmap(m_lookName, sectorSize, sectorSize); 0093 p->drawPixmap(sectorTopLeft, planetPix); 0094 0095 if ( m_hovered || (m_selected && m_blinkState) ) { 0096 QBrush backBrush = p->brush(); 0097 0098 backBrush.setColor(KColorScheme(QPalette::Active).background().color()); 0099 backBrush.setStyle(Qt::SolidPattern); 0100 0101 p->setOpacity(0.3); 0102 p->fillRect(boundingRect(), backBrush ); 0103 p->setOpacity(1); 0104 } 0105 0106 // Show the name of the planet (on top of bkgnd) 0107 0108 QRectF TextRect(sectorTopLeft.x(), sectorTopLeft.y(), sectorSize, sectorSize); 0109 0110 QPixmap nameBackgroundPix = renderPixmap(QStringLiteral("planet_name_background"), sectorSize, sectorSize); 0111 p->drawPixmap(TextRect.topLeft(), nameBackgroundPix); 0112 p->setFont(QFont(QStringLiteral("Times"), 16)); 0113 p->drawText(TextRect, m_sector->planet()->name()); 0114 0115 // Show the number of ships on the planet. 0116 if((m_game->options().NeutralsShowShips || !m_sector->planet()->player()->isNeutral()) 0117 && ((!m_game->options().BlindMap || m_game->currentPlayer() == m_sector->planet()->player()) 0118 || (m_game->options().NeutralsShowShips && m_sector->planet()->player()->isNeutral()))) 0119 { 0120 QString shipCount = QString::number(m_sector->planet()->ships()); 0121 0122 QPixmap shipsBackgroundPix = renderPixmap(QStringLiteral("planet_ship_count_background"), 0123 sectorSize, sectorSize); 0124 p->drawPixmap(TextRect.topLeft(), shipsBackgroundPix); 0125 p->setFont(QFont(QStringLiteral("Times"), 16)); 0126 p->drawText(TextRect, Qt::AlignRight | Qt::AlignBottom, shipCount); 0127 } 0128 } 0129 0130 QPixmap PlanetItem::renderPixmap( const QString& svgId, int width, int height ) const 0131 { 0132 QPixmap pix; 0133 QString cacheKey = QStringLiteral("%1%2x%3").arg(svgId).arg(width).arg(height); 0134 if (!m_scene->imageCache()->findPixmap(cacheKey, &pix)) { 0135 pix = QPixmap(width, height); 0136 pix.fill(Qt::transparent); 0137 QPainter pixPainter(&pix); 0138 m_scene->renderer()->render(&pixPainter, svgId, QRect(0, 0, width, height)); 0139 m_scene->imageCache()->insertPixmap(cacheKey, pix); 0140 } 0141 0142 return pix; 0143 } 0144 0145 0146 void PlanetItem::hoverEnterEvent( QGraphicsSceneHoverEvent * /*event*/ ) 0147 { 0148 m_hovered = true; 0149 0150 Planet *planet = m_sector->planet(); 0151 m_scene->displayPlanetInfo(planet); 0152 0153 update(); 0154 } 0155 0156 void PlanetItem::hoverLeaveEvent( QGraphicsSceneHoverEvent * /*event*/ ) 0157 { 0158 m_hovered = false; 0159 m_scene->displayPlanetInfo(nullptr); 0160 0161 update(); 0162 } 0163 0164 0165 void PlanetItem::mousePressEvent( QGraphicsSceneMouseEvent * /*event*/ ) 0166 { 0167 m_selected = true; 0168 m_blinkTimer->start(500); 0169 update(); 0170 0171 Q_EMIT planetItemSelected(this); 0172 } 0173 0174 void PlanetItem::select( ) 0175 { 0176 m_selected = true; 0177 m_blinkTimer->start(500); 0178 update(); 0179 } 0180 0181 void PlanetItem::unselect() { 0182 m_blinkTimer->stop(); 0183 m_blinkState = false; 0184 m_selected = false; 0185 0186 update(); 0187 } 0188 0189 void PlanetItem::blinkPlanet() 0190 { 0191 m_blinkState = !m_blinkState; 0192 0193 update(); 0194 } 0195 0196 0197 /******************************** 0198 PlanetInfoItem 0199 *******************************/ 0200 0201 0202 PlanetInfoItem::PlanetInfoItem (Game *game) 0203 : QGraphicsItem(), 0204 m_game(game), 0205 m_textDoc(), 0206 m_planet(nullptr) 0207 { 0208 } 0209 0210 void PlanetInfoItem::setPlanet (Planet *planet) 0211 { 0212 m_planet = planet; 0213 0214 QString text = i18n("Planet name: %1", planet->name()); 0215 if((m_game->options().NeutralsShowStats || !planet->player()->isNeutral()) 0216 && ((!m_game->options().BlindMap || m_game->currentPlayer() == planet->player()) 0217 || (m_game->options().NeutralsShowStats && planet->player()->isNeutral()))) 0218 { 0219 text += QLatin1String("<br />") + i18n("Owner: %1", planet->player()->coloredName() 0220 + (m_game->options().NeutralsShowShips || !planet->player()->isNeutral() ? 0221 QLatin1String("<br />") 0222 + i18n("Ships: %1", planet->ships() ) : 0223 QString())); 0224 if( m_game->currentPlayer() == planet->player() ) 0225 { 0226 int shipsNeeded = 0; // determine how many ships will be needed by standing orders 0227 for (AttackFleet* fleet : planet->player()->standingOrders()) { 0228 if(fleet->source == planet) 0229 shipsNeeded += fleet->shipCount(); 0230 } 0231 if(shipsNeeded) 0232 text += QLatin1String("<br />") + i18nc("regarding standing orders", "Ships due: %1", shipsNeeded); 0233 } 0234 text += QLatin1String("<br />") 0235 + i18n("Production: %1", planet->production()) 0236 + QLatin1String("<br />") 0237 + i18n("Kill percent: %1", planet->killPercentage() ); 0238 } 0239 m_textDoc.setHtml(text); 0240 } 0241 0242 0243 QRectF PlanetInfoItem::boundingRect() const 0244 { 0245 return QRectF(0, 0, m_textDoc.idealWidth(), m_textDoc.size().height()); 0246 } 0247 0248 void PlanetInfoItem::paint(QPainter *p, 0249 const QStyleOptionGraphicsItem * /*option*/, 0250 QWidget * /*widget*/) 0251 { 0252 QBrush brush = p->brush(); 0253 0254 const KColorScheme colorScheme(QPalette::Active); 0255 0256 brush.setColor(colorScheme.background().color()); 0257 brush.setStyle(Qt::SolidPattern); 0258 0259 p->setOpacity(0.7); 0260 p->fillRect(QRectF(0, 0, 0261 m_textDoc.idealWidth() + 1, 0262 m_textDoc.size().height() + 1), 0263 brush); 0264 p->setOpacity(1.0); 0265 0266 p->save(); 0267 QAbstractTextDocumentLayout::PaintContext ctx; 0268 ctx.palette.setColor(QPalette::Text, colorScheme.foreground().color()); 0269 m_textDoc.documentLayout()->draw(p, ctx); 0270 p->restore(); 0271 } 0272 0273 #include "moc_mapitems.cpp"