File indexing completed on 2024-04-21 03:40:43

0001 /*
0002     SPDX-FileCopyrightText: 2005-2006 Albert Astals Cid <aacid@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "highscoredialog.h"
0008 
0009 #include <QDialogButtonBox>
0010 #include <QPainter>
0011 #include <QPixmap>
0012 #include <QTabBar>
0013 #include <QTabWidget>
0014 #include <QVBoxLayout>
0015 
0016 #include <KConfig>
0017 #include <KFontUtils>
0018 #include <KLocalizedString>
0019 #include <KSharedConfig>
0020 
0021 #include "counter.h"
0022 #include "settings.h"
0023 
0024 static const int margin = 15;
0025 static const int smallMargin = 5;
0026 static const int namesFontSize = 25;
0027 
0028 static QSet<highScoreManager *> s_allHSM;
0029 
0030 /* scoresWidget */
0031 
0032 class scoresWidget : public QWidget
0033 {
0034     public:
0035         scoresWidget(QWidget *parent, const QList< QPair<int, QString> > &scores, QSvgRenderer *renderer);
0036         QSize calcSize();
0037 
0038     protected:
0039         void paintEvent(QPaintEvent *) override;
0040     
0041     private:
0042         const QList< QPair<int, QString> > m_scores;
0043         QSvgRenderer *m_renderer;
0044 };
0045 
0046 scoresWidget::scoresWidget(QWidget *parent, const QList< QPair<int, QString> > &scores, QSvgRenderer *renderer)
0047  : QWidget(parent), m_scores(scores), m_renderer(renderer)
0048 {
0049     setAttribute(Qt::WA_StaticContents);
0050 }
0051 
0052 void scoresWidget::paintEvent(QPaintEvent *)
0053 {
0054     int w = width();
0055     int h = height();
0056     QFont f;
0057     QPixmap buf(w, h);
0058     QPainter p(&buf);
0059     QRect r;
0060     QColor bg = palette().window().color();
0061  
0062     // bg color
0063     p.fillRect(0, 0, w, h, bg);
0064     
0065     p.setPen(Qt::black);
0066     
0067     if (blinkenSettings::customFont()) f = QFont(QStringLiteral("Steve"));
0068     p.setFont(f);
0069     f.setPointSize(KFontUtils::adaptFontSize(p, QStringLiteral("A"), 1000, namesFontSize, 28, 1, KFontUtils::DoNotAllowWordWrap));
0070     p.setFont(f);
0071     
0072     p.translate(margin, margin);
0073     
0074     QList< QPair<int, QString> >::const_iterator it;
0075     for (it = m_scores.begin(); it != m_scores.end(); ++it)
0076     {
0077         counter::paint(p, !(*it).second.isEmpty(), (*it).first, false, QColor(), QColor(), QColor(), m_renderer);
0078         p.setPen(Qt::black);
0079         p.drawText(counter::width(false) + 2 * smallMargin, 30, (*it).second);
0080         p.translate(0, counter::height() + smallMargin);
0081     }
0082     
0083     QPainter p2(this);
0084     p2.drawPixmap(0, 0, buf);
0085 }
0086 
0087 
0088 QSize scoresWidget::calcSize()
0089 {
0090     int mw, mh, lt;
0091     QRect r;
0092     QPixmap dummyPixmap(2000, 2000);
0093     QPainter p(&dummyPixmap);
0094     QFont f;
0095     
0096     if (blinkenSettings::customFont()) f = QFont(QStringLiteral("Steve"));
0097     p.setFont(f);
0098     f.setPointSize(KFontUtils::adaptFontSize(p, QStringLiteral("A"), 1000, namesFontSize, 28, 1, KFontUtils::DoNotAllowWordWrap));
0099     p.setFont(f);
0100     for (int i = 0; i < 3; i++)
0101     {
0102         lt = 0;
0103         QList< QPair<int, QString> >::const_iterator it;
0104         for (it = m_scores.begin(); it != m_scores.end(); ++it)
0105         {
0106             r = p.boundingRect(QRect(), Qt::AlignLeft, (*it).second);
0107             lt = qMax(lt, r.width());
0108         }
0109     }
0110     
0111     mw = margin + counter::width(false) + 2 * smallMargin + lt + margin;
0112     mh = margin * 2 + counter::height() * 5 + smallMargin * 4;
0113     
0114     QSize size(mw, mh);
0115     setMinimumSize(size);
0116     resize(size);
0117     
0118     return size;
0119 }
0120 
0121 /* myTabWidget */
0122 
0123 class myTabWidget : public QTabWidget
0124 {
0125     public:
0126         myTabWidget(QWidget *parent) : QTabWidget(parent) {}
0127         
0128         QSize tabBarSizeHint() const
0129         {
0130             return tabBar() -> sizeHint();
0131         }
0132 };
0133 
0134 /* highScoreDialog */
0135 
0136 highScoreDialog::highScoreDialog(QWidget *parent, QSvgRenderer *renderer) : QDialog(parent)
0137 {
0138     setWindowTitle(i18nc("@title:window the highest scores for each level are shown", "Highscores"));
0139 
0140     setLayout(new QVBoxLayout(this));
0141     m_tw = new myTabWidget(this);
0142     layout()->addWidget(m_tw);
0143     QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
0144     connect(buttonBox, &QDialogButtonBox::rejected, this, &highScoreDialog::close);
0145     layout()->addWidget(buttonBox);
0146 
0147     highScoreManager hsm;
0148     
0149     m_tw -> addTab(new scoresWidget(nullptr, hsm.scores(0), renderer), i18nc("@title:group High scores Level 1 tab title", "Level 1"));
0150     m_tw -> addTab(new scoresWidget(nullptr, hsm.scores(1), renderer), i18nc("@title:group High scores Level 2 tab title", "Level 2"));
0151     m_tw -> addTab(new scoresWidget(nullptr, hsm.scores(2), renderer), i18nc("@title:group High scores Level ? tab tible", "Level ?"));
0152 }
0153 
0154 void highScoreDialog::showLevel(int level)
0155 {
0156     QSize max, aux;
0157     m_tw -> setCurrentIndex(level -1);
0158     
0159     for (int i = 0; i < 3; i++)
0160     {
0161         aux = static_cast<scoresWidget*>(m_tw -> widget(i)) -> calcSize();
0162         max = max.expandedTo(aux);
0163     }
0164     if (max.width() < m_tw -> tabBarSizeHint().width() + 5) m_tw -> setMinimumSize(m_tw -> tabBarSizeHint().width() + 5, max.height() + m_tw -> tabBarSizeHint().height() + 5);
0165     
0166     exec();
0167 }
0168 
0169 /* highScoreManager */
0170 
0171 highScoreManager::highScoreManager()
0172 {
0173     s_allHSM << this;
0174     update();
0175 }
0176 
0177 highScoreManager::~highScoreManager()
0178 {
0179     s_allHSM.remove(this);
0180 }
0181 
0182 bool highScoreManager::scoreGoodEnough(int level, int score)
0183 {
0184     level--;
0185     QList< QPair<int, QString> >::iterator it, itEnd;
0186     it = m_scores[level].begin();
0187     itEnd = m_scores[level].end();
0188     while (it != itEnd && (*it).first >= score) ++it;
0189     
0190     return (it != itEnd);
0191 }
0192 
0193 void highScoreManager::addScore(int level, int score, const QString &name)
0194 {
0195     level--;
0196     QList< QPair<int, QString> >::iterator it, itEnd;
0197     it = m_scores[level].begin();
0198     itEnd = m_scores[level].end();
0199     while (it != itEnd && (*it).first >= score) ++it;
0200     
0201     if (it != itEnd)
0202     {
0203         m_scores[level].insert(it, qMakePair(score, name));
0204         m_scores[level].erase(--m_scores[level].end());
0205         
0206         KConfigGroup cfg(KSharedConfig::openConfig(), QStringLiteral("Level%1").arg(level + 1));
0207         int j;
0208         for (it = m_scores[level].begin(), j = 1; it != m_scores[level].end(); ++it, j++)
0209         {
0210             cfg.writeEntry(QStringLiteral("Score%1").arg(j), (*it).first);
0211             cfg.writeEntry(QStringLiteral("Name%1").arg(j), (*it).second);
0212         }
0213         cfg.sync();
0214 
0215         for (highScoreManager *hsm : std::as_const(s_allHSM))
0216         {
0217             if (hsm != this)
0218             {
0219                 hsm->update();
0220             }
0221         }
0222     }
0223 }
0224 
0225 void highScoreManager::update()
0226 {
0227     for (int i = 0; i < 3; ++i)
0228     {
0229         m_scores[i].clear();
0230     }
0231     for (int i = 1; i <= 3; i++)
0232     {
0233         KConfigGroup cfg(KSharedConfig::openConfig(), QStringLiteral("Level%1").arg(i));
0234         for (int j = 1; j <= 5; j++)
0235         {
0236             m_scores[i-1].append(qMakePair(cfg.readEntry(QStringLiteral("Score%1").arg(j),QVariant(0)).toInt(),cfg.readEntry(QStringLiteral("Name%1").arg(j),QString())));
0237         }
0238     }
0239 }
0240 
0241 QList< QPair<int, QString> > highScoreManager::scores(int level) const
0242 {
0243     return m_scores[level];
0244 }
0245 
0246 int highScoreManager::score(int level, int position) const
0247 {
0248     return m_scores[level][position].first;
0249 }
0250 
0251 QString highScoreManager::name(int level, int position) const
0252 {
0253     return m_scores[level][position].second;
0254 }
0255 
0256 #include "moc_highscoredialog.cpp"