File indexing completed on 2024-05-12 04:06:06
0001 /* 0002 SPDX-FileCopyrightText: 1998 Sandro Sigala <ssigala@globalnet.it> 0003 SPDX-FileCopyrightText: 2001 Waldo Bastian <bastian@kde.org> 0004 SPDX-FileCopyrightText: 2007 Matt Williams <matt@milliams.com> 0005 0006 SPDX-License-Identifier: ICS 0007 */ 0008 0009 #ifndef KGAMEHIGHSCOREDIALOG_H 0010 #define KGAMEHIGHSCOREDIALOG_H 0011 0012 // own 0013 #include <kdegames_export.h> 0014 // Qt 0015 #include <QDialog> 0016 #include <QMap> 0017 // Std 0018 #include <memory> 0019 0020 class KGameDifficulty; 0021 0022 /** 0023 * \class KGameHighScoreDialog kgamehighscoredialog.h <KGameHighScoreDialog> 0024 * 0025 * @short A simple high score implementation 0026 * 0027 * This class can be used both for displaying the current high scores 0028 * and also for adding new highscores. It is the recommended way of 0029 * implementing a simple highscore table. 0030 * 0031 * To display the current highscores it is simply a case of creating 0032 * a KGameHighScoreDialog object and calling exec(). This example code will 0033 * display the Name and Score (the score is always added automatically 0034 * unless hidden @ref hideField since it is used for sorting) of the 0035 * top 10 players: 0036 * \code 0037 * KGameHighScoreDialog ksdialog(this); 0038 * ksdialog.exec(); 0039 * \endcode 0040 * 0041 * To add a new highscore, e.g. at the end of a game you simply create an 0042 * object with the @ref Fields you want to write (i.e. KGameHighScoreDialog::Name | 0043 * KGameHighScoreDialog::Score), call addScore and then (optionally) display 0044 * the dialog. 0045 * This code will allow you to add a highscore with a Name and Score 0046 * field. If it's the first time a player has a score on the table, they 0047 * will be prompted for their name but subsequent times they will have 0048 * their name filled in automatically. 0049 * \code 0050 * KGameHighScoreDialog ksdialog(this); 0051 * ksdialog.addScore(playersScore); 0052 * ksdialog.exec(); 0053 * \endcode 0054 * 0055 * Or if you want to fill the name in from the code you can pass a default 0056 * name by doing 0057 * \code 0058 * KGameHighScoreDialog::FieldInfo scoreInfo; 0059 * scoreInfo[KGameHighScoreDialog::Name] = "Matt"; 0060 * scoreInfo[KGameHighScoreDialog::Score].setNum(playersScore); 0061 * ksdialog.addScore(scoreInfo); 0062 * \endcode 0063 * 0064 * If you want to add an extra field (e.g. the number of moves taken) then 0065 * do 0066 * \code 0067 * KGameHighScoreDialog::FieldInfo scoreInfo; 0068 * scoreInfo[KGameHighScoreDialog::Name] = "Matt"; 0069 * scoreInfo[KGameHighScoreDialog::Score].setNum(playersScore); 0070 * 0071 * ksdialog.addField(KGameHighScoreDialog::Custom1, "Num of Moves", "moves"); 0072 * scoreInfo[KGameHighScoreDialog::Custom1].setNum(42); 0073 * 0074 * ksdialog.addScore(scoreInfo); 0075 * \endcode 0076 * You can define up to 5 Custom fields. 0077 * @author Matt Williams <matt@milliams.com> 0078 */ 0079 class KDEGAMES_EXPORT KGameHighScoreDialog : public QDialog 0080 { 0081 Q_OBJECT 0082 0083 public: 0084 /// Highscore fields 0085 enum Fields { 0086 Name = 1 << 0, 0087 Level = 1 << 1, 0088 Date = 1 << 2, 0089 Time = 1 << 3, 0090 Score = 1 << 4, 0091 0092 Custom1 = 1 << 10, ///< Field for custom information 0093 Custom2 = 1 << 11, 0094 Custom3 = 1 << 12, 0095 Custom4 = 1 << 13, 0096 Custom5 = 1 << 14, 0097 0098 Max = 1 << 30 ///< Only for setting a maximum 0099 }; 0100 0101 /// Flags for setting preferences for adding scores 0102 enum AddScoreFlag { 0103 AskName = 0x1, /**< Promt the player for their name */ 0104 LessIsMore = 0x2 /**< A lower numerical score means higher placing on the table */ 0105 }; 0106 /** 0107 * Stores a combination of #AddScoreFlag values. 0108 */ 0109 Q_DECLARE_FLAGS(AddScoreFlags, AddScoreFlag) 0110 0111 typedef QMap<int, QString> FieldInfo; 0112 0113 /** 0114 * @param fields Bitwise OR of the @ref Fields that should be listed (Score is always present) 0115 * @param parent passed to parent QWidget constructor. 0116 */ 0117 explicit KGameHighScoreDialog(int fields = Name, QWidget *parent = nullptr); 0118 0119 ~KGameHighScoreDialog() override; 0120 0121 /** 0122 * The group name must be passed though i18n() in order for the 0123 * group name to be translated. i.e. 0124 * \code ksdialog.setConfigGroup(qMakePair(QByteArrayLiteral("Easy"), i18n("Easy"))); \endcode 0125 * If you set a group, it will be prefixed in the config file by 0126 * 'KHighscore_' otherwise the group will simply be 'KHighscore'. 0127 * 0128 * @param group to use for reading/writing highscores from/to. 0129 */ 0130 void setConfigGroup(const QPair<QByteArray, QString> &group); 0131 0132 /** 0133 * You must add the translations of all group names to the dialog. This 0134 * is best done by passing the name through i18n(). 0135 * The group set through setConfigGroup(const QPair<QByteArray, QString>& group) 0136 * will be added automatically 0137 * 0138 * @param group the translated group name 0139 */ 0140 void addLocalizedConfigGroupName(const QPair<QByteArray, QString> &group); 0141 0142 /** 0143 * You must add the translations of all group names to the dialog. This 0144 * is best done by passing the name through i18n(). 0145 * The group set through setConfigGroup(const QPair<QByteArray, QString>& group) 0146 * will be added automatically. 0147 * 0148 * This function can be used directly with KGameDifficulty::localizedLevelStrings(). 0149 * 0150 * @param groups the list of translated group names 0151 */ 0152 void addLocalizedConfigGroupNames(const QMap<QByteArray, QString> &groups); 0153 0154 /** 0155 * Hide some config groups so that they are not shown on the dialog 0156 * (but are still stored in the configuration file). 0157 * \code 0158 * ksdialog.setHiddenConfigGroups(QList<QByteArray>{QByteArrayLiteral("Very Easy"), QByteArrayLiteral("Easy")}); 0159 * \endcode 0160 * 0161 * @param hiddenGroups the list of group names you want to hide 0162 * 0163 * @since KDE 4.6 0164 */ 0165 void setHiddenConfigGroups(const QList<QByteArray> &hiddenGroups); 0166 0167 /** 0168 * It is a good idea giving config group weights, otherwise tabs 0169 * get ordered by their tab name that is not probably what you want. 0170 * 0171 * This function can be used directly with KGameDifficulty::levelWeights(). 0172 * 0173 * @param weights the list of untranslated group weights 0174 * 0175 * @since KDE 4.2 0176 */ 0177 void setConfigGroupWeights(const QMap<int, QByteArray> &weights); 0178 0179 /** 0180 * @param comment to add when showing high-scores. 0181 * The comment is only used once. 0182 */ 0183 void setComment(const QString &comment); 0184 0185 /** 0186 * Define an extra FieldInfo entry. 0187 * @param field id of this field @ref Fields e.g. KGameHighScoreDialog::Custom1 0188 * @param header text shown in the header in the dialog for this field. e.g. "Number of Moves" 0189 * @param key unique key used to store this field. e.g. "moves" 0190 */ 0191 void addField(int field, const QString &header, const QString &key); 0192 0193 /** 0194 * Hide a field so that it is not shown on the table (but is still stored in the configuration file). 0195 * @param field id of this field @ref Fields e.g. KGameHighScoreDialog::Score 0196 */ 0197 void hideField(int field); 0198 0199 /** 0200 * Adds a new score to the list. 0201 * 0202 * @param newInfo info about the score. 0203 * @param flags set whether the user should be prompted for their name and how the scores should be sorted 0204 * 0205 * @returns The highscore position if the score was good enough to 0206 * make it into the list (1 being topscore) or 0 otherwise. 0207 */ 0208 int addScore(const FieldInfo &newInfo = FieldInfo(), AddScoreFlags flags = {}); 0209 0210 /** 0211 * Convenience function for ease of use. 0212 * 0213 * @param newScore the score of the player. 0214 * @param flags set whether the user should be prompted for their name and how the scores should be sorted 0215 * 0216 * @returns The highscore position if the score was good enough to 0217 * make it into the list (1 being topscore) or 0 otherwise. 0218 */ 0219 int addScore(int newScore, AddScoreFlags flags = {}); 0220 0221 /** 0222 * @returns the current best score in the group 0223 */ 0224 int highScore(); 0225 0226 /** 0227 * Assume that config groups (incl. current selection) are equal to 0228 * difficulty levels, and initialize them. This is usually equal to the 0229 * following code using KGameDifficulty: 0230 * @code 0231 * addLocalizedConfigGroupNames(KGameDifficulty::localizedLevelStrings()); 0232 * setConfigGroupWeights(KGameDifficulty::levelWeights()); 0233 * setConfigGroup(KGameDifficulty::localizedLevelString()); 0234 * @endcode 0235 */ 0236 void initFromDifficulty(const KGameDifficulty *difficulty, bool setConfigGroup = true); 0237 0238 /// Display the dialog as non-modal 0239 virtual void show(); 0240 /// Display the dialog as modal 0241 int exec() override; 0242 0243 private Q_SLOTS: 0244 void slotGotReturn(); 0245 void slotGotName(); 0246 void slotForgetScore(); 0247 0248 private: 0249 void keyPressEvent(QKeyEvent *ev) override; 0250 0251 private: 0252 friend class KGameHighScoreDialogPrivate; 0253 std::unique_ptr<class KGameHighScoreDialogPrivate> const d_ptr; 0254 Q_DECLARE_PRIVATE(KGameHighScoreDialog) 0255 }; 0256 0257 Q_DECLARE_OPERATORS_FOR_FLAGS(KGameHighScoreDialog::AddScoreFlags) 0258 0259 #endif // KGAMEHIGHSCOREDIALOG_H