File indexing completed on 2023-09-24 03:50:40
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"