File indexing completed on 2024-04-07 07:33:20

0001 /*
0002     SPDX-FileCopyrightText: 2007 Paolo Capriotti <p.capriotti@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "seaview.h"
0008 
0009 #include <QMouseEvent>
0010 #include <QObject>
0011 
0012 #include <QIcon>
0013 
0014 #include "battlefieldview.h"
0015 #include "button.h"
0016 #include "delegate.h"
0017 #include "kbsrenderer.h"
0018 #include "playerlabel.h"
0019 #include "statswidget.h"
0020 #include "welcomescreen.h"
0021 
0022 
0023 SeaView::SeaView(QWidget* parent)
0024 : QWidget(parent)
0025 , m_delegate(nullptr)
0026 , m_last_f(-1)
0027 {/*
0028     setAttribute(Qt::WA_OpaquePaintEvent);
0029     setAttribute(Qt::WA_NoSystemBackground);*/
0030 
0031     // create renderer
0032     m_renderer = new KBSRenderer();
0033    
0034     // create labels
0035     m_labels[0] = new PlayerLabel(
0036         m_renderer->spritePixmap(QStringLiteral("score_mouse"), QSize(32, 32)),
0037         QStringLiteral("Player"),
0038         this);
0039     m_labels[0]->show();
0040     m_labels[1] = new PlayerLabel(
0041         m_renderer->spritePixmap(QStringLiteral("score_ai"), QSize(32, 32)),
0042         QStringLiteral("Computer"), 
0043         this);
0044     m_labels[1]->show();
0045  
0046     // create fields
0047     m_fields[0] = new BattleFieldView(this, m_renderer, QStringLiteral("background"), GRID_SIZE);
0048     m_fields[0]->setPlayer(Sea::Player(0));
0049     m_fields[0]->show();
0050     m_fields[1] = new BattleFieldView(this, m_renderer, QStringLiteral("background2"), GRID_SIZE);
0051     m_fields[1]->setPlayer(Sea::Player(1));
0052     m_fields[1]->show();
0053     
0054     // create stats widgets
0055     m_stats[0] = new StatsWidget(m_renderer, this);
0056     m_stats[0]->show();
0057     
0058     m_stats[1] = new StatsWidget(m_renderer, this);
0059     m_stats[1]->show();
0060     
0061     Animator::instance()->start();
0062     refresh();
0063     
0064     connect(screen(Sea::Player(0)), &WelcomeScreen::hidden, this, &SeaView::refresh);
0065     connect(screen(Sea::Player(0)), &WelcomeScreen::shown, this, &SeaView::refresh);
0066 }
0067 
0068 SeaView::~SeaView() {
0069     delete m_renderer;
0070 }
0071 
0072 void SeaView::refresh()
0073 {
0074     QSize ts = tileSize();
0075     m_renderer->resize(ts);
0076 
0077     m_fields[0]->refresh();
0078     m_fields[1]->refresh();
0079 
0080     int actual_width = 
0081         m_fields[0]->size().width() +
0082         m_fields[1]->size().width() +
0083         GAP;
0084  
0085     m_fields[0]->move((width() - actual_width) / 2, 
0086                       m_labels[0]->height() + LABEL_SPACING * 2);
0087 
0088     if (!screen(Sea::Player(0))->isVisible()) {
0089         m_labels[0]->show();
0090         m_labels[0]->move(m_fields[0]->pos().x(), LABEL_SPACING);
0091         m_labels[0]->update();
0092     }
0093     else {
0094         m_labels[0]->hide();
0095     }
0096     m_stats[0]->move(m_fields[0]->pos().x(), 
0097                      m_fields[0]->pos().y() + m_fields[0]->height() + 2);
0098     m_stats[0]->setWidth(m_fields[0]->size().width());
0099     m_stats[0]->refresh();
0100  
0101     m_fields[1]->move(
0102         m_fields[0]->pos().x() + m_fields[0]->size().width() + GAP, 
0103         m_fields[0]->pos().y());
0104     if (!screen(Sea::Player(0))->isVisible()) {
0105         m_labels[1]->show();
0106         m_labels[1]->move(m_fields[1]->pos().x(), LABEL_SPACING);
0107         m_labels[1]->update();
0108     }
0109     else {
0110         m_labels[1]->hide();
0111     }
0112     m_stats[1]->move(m_fields[1]->pos().x(), 
0113                      m_fields[1]->pos().y() + m_fields[1]->height() + 2);
0114     m_stats[1]->setWidth(m_fields[0]->size().width());
0115     m_stats[1]->refresh();
0116 }
0117 
0118 void SeaView::resizeEvent(QResizeEvent*)
0119 {
0120     refresh();
0121 }
0122 
0123 int SeaView::fieldAt(const QPoint& p)
0124 {
0125     if (m_fields[0]->rect().contains(p)) {
0126         return 0;
0127     }
0128     else if (m_fields[1]->rect().contains(p)) {
0129         return 1;
0130     }
0131     else {
0132         return -1;
0133     }
0134 }
0135 
0136 bool SeaView::updatePreview(const QPoint& pos)
0137 {
0138     QWidget* item = childAt(pos);
0139     if (static_cast<QGraphicsView*>(m_fields[0]) == item) {
0140         m_fields[1]->cancelPreview();
0141         if (setPreview(Sea::Player(0), pos)) {
0142             m_last_preview = pos;
0143         }
0144         return true;
0145     }
0146     else if (static_cast<QGraphicsView*>(m_fields[1]) == item) {
0147         m_fields[0]->cancelPreview();
0148         if (setPreview(Sea::Player(1), pos)) {
0149             m_last_preview = pos;
0150         }
0151         return true;
0152     }
0153     else {
0154         return false;
0155     }
0156 }
0157 
0158 bool SeaView::setPreview(Sea::Player player, const QPoint& pos)
0159 {
0160     QPoint p = pos - m_fields[player]->pos();
0161     Coord c = m_renderer->toLogical(p);
0162 
0163     m_fields[player]->setPreview(p);
0164     return m_delegate->canAddShip(player, c);
0165 }
0166 
0167 void SeaView::cancelPreview()
0168 {
0169     m_fields[0]->cancelPreview();
0170     m_fields[1]->cancelPreview();
0171     updatePreview(m_last_preview);
0172 }
0173 
0174 void SeaView::add(Sea::Player p, Ship* ship)
0175 {
0176     m_fields[p]->add(ship);
0177 }
0178 
0179 void SeaView::hit(Sea::Player p, const Coord& c)
0180 {
0181     m_fields[p]->hit(c);
0182 }
0183 
0184 void SeaView::miss(Sea::Player p, const Coord& c)
0185 {
0186     m_fields[p]->miss(c);
0187 }
0188 
0189 void SeaView::sink(Sea::Player p, Ship* ship)
0190 {
0191     m_fields[p]->sink(ship);
0192 }
0193 
0194 void SeaView::setStatus(Sea::Status status)
0195 {
0196     m_fields[0]->setStatus(status);
0197     m_fields[1]->setStatus(status);
0198 }
0199 
0200 void SeaView::clear()
0201 {
0202     m_fields[0]->clear();
0203     m_fields[1]->clear();
0204 }
0205 
0206 BattleFieldView* SeaView::otherField(BattleFieldView* field)
0207 {
0208     return field == m_fields[0] ? m_fields[1] : m_fields[0];
0209 }
0210 
0211 QSize SeaView::tileSize() const
0212 {
0213     int h = (height() -
0214         m_labels[0]->height() -
0215         LABEL_SPACING * 2 -
0216         m_stats[0]->height() -
0217         MARGIN * 2) / GRID_SIZE;
0218     int w = (width() - GAP - MARGIN * 2) / (GRID_SIZE * 2);
0219     return w < h ? QSize(w, w) : QSize(h, h);
0220 }
0221 
0222 void SeaView::setDelegate(Delegate* c)
0223 {
0224     m_fields[0]->setDelegate(c);
0225     m_fields[1]->setDelegate(c);
0226 }
0227 
0228 WelcomeScreen* SeaView::globalScreen() const
0229 {
0230     return m_screen;
0231 }
0232 
0233 WelcomeScreen* SeaView::screen(Sea::Player player) const
0234 {
0235     return m_fields[player]->screen();
0236 }
0237 
0238 void SeaView::toggleLeftGrid(bool show)
0239 {
0240     m_fields[0]->toggleGrid(show);
0241 }
0242 
0243 void SeaView::toggleRightGrid(bool show)
0244 {
0245     m_fields[1]->toggleGrid(show);
0246 }
0247 
0248 void SeaView::setStats(Sea::Player p, const QString& icon, 
0249                        const QString& text, Stats* stats)
0250 {
0251     m_labels[p]->setData(m_renderer->spritePixmap(icon, QSize(32, 32)), text);
0252     m_stats[p]->setData(stats);
0253     
0254 }
0255 
0256 void SeaView::setNick(Sea::Player p, const QString& nick)
0257 {
0258     m_labels[p]->setText(nick);
0259 }
0260 
0261 #include "moc_seaview.cpp"