diff --git a/src/khangman.cpp b/src/khangman.cpp index 1a9f01e..a69ce56 100644 --- a/src/khangman.cpp +++ b/src/khangman.cpp @@ -1,637 +1,636 @@ /*************************************************************************** * Copyright 2001-2009 Anne-Marie Mahfouf * * Copyright 2014 Rahul Chowdhury * * * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "khangman.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "langutils.h" #include "prefs.h" KHangMan::KHangMan() : QMainWindow(), m_currentCategory(0), m_currentLanguage(0), m_winCount(0), m_lossCount(0), m_randomInt(0), m_scoreMultiplyingFactor(1), m_netScore(0), m_doc(nullptr), m_helpMenu(new KHelpMenu(NULL)) { setObjectName(QStringLiteral("KHangMan")); m_view = new QQuickWidget(this); m_view->rootContext()->setContextProperty(QStringLiteral("khangman"), this); KDeclarative::KDeclarative kdeclarative; kdeclarative.setDeclarativeEngine(m_view->engine()); kdeclarative.setupContext(); KConfigGroup windowConfig = config(QStringLiteral("Window")); if (windowConfig.hasKey("geometry")) { setGeometry(windowConfig.readEntry("geometry", QRect())); setWindowState(Qt::WindowState(windowConfig.readEntry("windowState").toInt())); } setMinimumSize(800, 600); m_view->setResizeMode(QQuickWidget::SizeRootObjectToView); setCentralWidget(m_view); scanLanguages(); setLevel(); //find the themes m_themeFactory.addTheme(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("khangman/themes/standardthemes.xml"))); loadLanguageSpecialCharacters(); } KHangMan::~KHangMan() { KConfigGroup windowConfig = config(QStringLiteral("Window")); windowConfig.writeEntry("geometry", geometry()); windowConfig.writeEntry("windowState", int(windowState())); delete m_view; m_view = NULL; } void KHangMan::showAboutKHangMan() { m_helpMenu->aboutApplication(); } void KHangMan::showAboutKDE() { m_helpMenu->aboutKDE(); } void KHangMan::showHandbook() { m_helpMenu->appHelpActivated(); } KConfigGroup KHangMan::config(const QString &group) { return KConfigGroup(KSharedConfig::openConfig(qApp->applicationName() + "rc"), group); } // ---------------------------------------------------------------- // Slots void KHangMan::setCurrentCategory(int index) { QMap::const_iterator currentLevel = m_titleLevels.constBegin() + index; Prefs::setCurrentLevel(index); Prefs::setLevelFile(currentLevel.value()); Prefs::self()->save(); m_currentCategory = index; emit currentCategoryChanged(); } void KHangMan::setCurrentLanguage(int index) { if (index >= 0 && index < m_languages.size()) { Prefs::setSelectedLanguage(m_languages[index]); m_currentLanguage = index; Prefs::self()->save(); loadLevels(); loadLanguageSpecialCharacters(); setLevel(); emit currentLanguageChanged(); } } void KHangMan::setCurrentTheme(int index) { KHMTheme *theme = m_themeFactory.buildTheme(index); Prefs::setTheme(theme->name()); Prefs::self()->save(); emit currentThemeChanged(); } void KHangMan::readFile() { // Check if the data files are installed in the correct dir. QFile myFile; myFile.setFileName(Prefs::levelFile()); if (!myFile.exists()) { QString mString = i18n("File $KDEDIR/share/apps/kvtml/%1/%2 not found.\n" "Please check your installation.", Prefs::selectedLanguage(), Prefs::levelFile()); KMessageBox::sorry (this, mString, i18n("Error")); } // Detects if file is a kvtml file so that it's a hint enable file slotSetWordsSequence(); } void KHangMan::nextWord() { if (m_randomList.count() == 0) { m_originalWord = m_randomList[0].first; m_hint = m_randomList[0].second; return; } else { m_originalWord = m_randomList[m_randomInt%m_randomList.count()].first; m_originalWord = m_originalWord.toUpper(); m_hint = m_randomList[m_randomInt%m_randomList.count()].second; emit currentHintChanged(); } if (m_originalWord.isEmpty()) { ++m_randomInt; nextWord(); } m_currentWord.clear(); int originalWordSize = m_originalWord.size(); while (m_currentWord.size() < originalWordSize) m_currentWord.append("_"); // Find dashes, spaces, middot and apostrophe QString search = QStringLiteral("- ยท'"); Q_FOREACH(const QChar &key, search) { int pos = m_originalWord.indexOf( key ); while (pos > 0) { m_currentWord.replace(pos, 1, key); pos = m_originalWord.indexOf( key ); } } emit currentWordChanged(); ++m_randomInt; } void KHangMan::slotSetWordsSequence() { delete m_doc; m_doc = new KEduVocDocument(this); ///@todo open returns KEduVocDocument::ErrorCode m_doc->open (QUrl::fromLocalFile (Prefs::levelFile()), KEduVocDocument::FileIgnoreLock); //how many words in the file int wordCount = m_doc->lesson()->entryCount(KEduVocLesson::Recursive); //get the words+hints KRandomSequence randomSequence; m_randomList.clear(); for (int j = 0; j < wordCount; ++j) { QString hint = m_doc->lesson()->entries (KEduVocLesson::Recursive).at(j)->translation(0)->comment(); if (hint.isEmpty() && m_doc->identifierCount() > 0) { // if there is no comment or it's empty, use the first translation if there is one hint = m_doc->lesson()->entries(KEduVocLesson::Recursive).at(j)->translation(1)->text(); } if (!m_doc->lesson()->entries(KEduVocLesson::Recursive).at(j)->translation(0)->text().isEmpty()) { m_randomList.append(qMakePair(m_doc->lesson()->entries(KEduVocLesson::Recursive).at(j)->translation(0)->text(), hint)); } } //shuffle the list randomSequence.randomize(m_randomList); } QString KHangMan::stripAccents(const QString & original) { QString noAccents; QString decomposed = original.normalized(QString::NormalizationForm_D); for (int i = 0; i < decomposed.length(); ++i) { if ( decomposed[i].category() != QChar::Mark_NonSpacing ) { noAccents.append(decomposed[i]); } } return noAccents; } void KHangMan::replaceLetters(const QString& charString) { QChar ch = charString.at(0); bool oneLetter = Prefs::oneLetter(); for (int i = 0; i < m_originalWord.size(); ++i) { if (m_originalWord.at(i) == ch) { m_currentWord[i] = ch; if (oneLetter) break; } } emit currentWordChanged(); } bool KHangMan::isResolved() const { return m_currentWord == m_originalWord; } void KHangMan::revealCurrentWord() { m_currentWord = m_originalWord; emit currentWordChanged(); } void KHangMan::calculateNetScore() { m_netScore = ( m_winCount - m_lossCount ) * m_scoreMultiplyingFactor; - qDebug() << "Net Score = " << m_netScore; emit netScoreChanged(); } bool KHangMan::containsChar(const QString &sChar) { return m_originalWord.contains(sChar) || stripAccents(m_originalWord).contains(sChar); } int KHangMan::resolveTime() { return Prefs::resolveTime(); } void KHangMan::setResolveTime(int resolveTime) { Prefs::setResolveTime(resolveTime); emit resolveTimeChanged(); } bool KHangMan::soundEnabled() { return Prefs::sound(); } void KHangMan::setSoundEnabled(bool sound) { Prefs::setSound(sound); emit soundEnabledChanged(); } QStringList KHangMan::languages() { return m_languageNames; } int KHangMan::winCount() const { return m_winCount; } void KHangMan::setWinCount(int count) { m_winCount = count; calculateNetScore(); emit winCountChanged(); } int KHangMan::lossCount() const { return m_lossCount; } void KHangMan::setLossCount(int count) { m_lossCount = count; calculateNetScore(); emit lossCountChanged(); } int KHangMan::scoreMultiplyingFactor() const { return m_scoreMultiplyingFactor; } void KHangMan::setScoreMultiplyingFactor( int factor ) { m_scoreMultiplyingFactor = factor; calculateNetScore(); emit scoreMultiplyingFactorChanged(); } int KHangMan::netScore() const { return m_netScore; } int KHangMan::currentLanguage() { return m_currentLanguage; } QStringList KHangMan::themes() { return m_themeFactory.themeList(); } int KHangMan::currentTheme() { QStringList themes = m_themeFactory.getNames(); return themes.indexOf(Prefs::theme()); } QString KHangMan::backgroundUrl() { QStringList themes = m_themeFactory.getNames(); int index = themes.indexOf(Prefs::theme()); KHMTheme *theme = m_themeFactory.buildTheme(index); if (theme) { QString filename = QStandardPaths::locate(QStandardPaths::DataLocation, "themes/" + theme->svgFileName()); return filename; } return QString(); } QColor KHangMan::currentThemeLetterColor() { // Default to white letters QColor color = "white"; QStringList themes = m_themeFactory.getNames(); int index = themes.indexOf(Prefs::theme()); KHMTheme *theme = m_themeFactory.buildTheme(index); if (theme) { color = theme->letterColor(); } return color; } QStringList KHangMan::categories() { return m_titleLevels.keys(); } int KHangMan::currentCategory() { return m_currentCategory; } QStringList KHangMan::currentWord() const { QStringList currentWordLetters; foreach (const QChar& currentWordLetter, m_currentWord) { currentWordLetters.append(currentWordLetter); } return currentWordLetters; } QString KHangMan::getCurrentHint() const { return m_hint; } QQmlEngine* KHangMan::getEngine() { return m_view->engine(); } QStringList KHangMan::alphabet() const { QStringList letterList; char c = 'A'; while( c != 'Z') { letterList.append(QChar(c)); ++c; } letterList.append(QChar(c)); letterList.append(m_specialCharacters); return letterList; } QStringList KHangMan::languageNames() const { QStringList languageCodes = SharedKvtmlFiles::languages(); if (languageCodes.isEmpty()) { QApplication::instance()->quit(); } QStringList languageNames; foreach (const QString& languageCode, languageCodes) { QLocale locale(languageCode); QString languageName = locale.nativeLanguageName(); languageNames.append(languageName); } return languageNames; } // ---------------------------------------------------------------- void KHangMan::scanLanguages() { m_languageNames.clear(); //the program scans in khangman/data/ to see what languages data is found m_languages = SharedKvtmlFiles::languages(); if (m_languages.isEmpty()) { qApp->closeAllWindows(); } //find duplicated entries in KDEDIR and KDEHOME // Write the present languages in config so they cannot be downloaded. // FIXME: use pre-seeding here KConfigGroup cg( KSharedConfig::openConfig() ,"KNewStuff2"); for (int i=0; isync(); for (int i = 0; i < m_languages.size(); ++i) { QLocale locale(m_languages[i]); QString languageName = locale.nativeLanguageName(); if (languageName.isEmpty()) { languageName = i18nc("@item:inlistbox no language for that locale","None"); } m_languageNames.append(languageName); if (m_languages[i] == Prefs::selectedLanguage()) m_currentLanguage = i; } emit languagesChanged(); } void KHangMan::setLevel() { m_currentCategory = Prefs::currentLevel(); if (m_currentCategory > m_titleLevels.count()) { m_currentCategory = 0; } emit currentCategoryChanged(); } void KHangMan::show() { if (loadLevels()) { // kvtml files have been found if (m_themeFactory.getQty() > 0) { // themes present QMainWindow::show(); // add the qml view as the main widget QString location = QStandardPaths::locate(QStandardPaths::DataLocation, QStringLiteral("qml/main.qml")); QUrl url = QUrl::fromLocalFile(location); m_view->setSource(url); } else { // themes not present QMessageBox::information(this, i18n("Error"), i18n("No theme files found.")); exit(EXIT_FAILURE); } } else { // no kvtml files present QMessageBox::information(this, i18n("Error"), i18n("No kvtml files found.")); exit(EXIT_FAILURE); } } bool KHangMan::loadLevels() { //build the Level combobox menu dynamically depending of the data for each language m_titleLevels.clear(); QStringList levelFilenames = SharedKvtmlFiles::fileNames(Prefs::selectedLanguage()); QStringList titles = SharedKvtmlFiles::titles(Prefs::selectedLanguage()); if (levelFilenames.size() == 0) { Prefs::setSelectedLanguage(QStringLiteral("en")); Prefs::self()->save(); levelFilenames = SharedKvtmlFiles::fileNames(Prefs::selectedLanguage()); titles = SharedKvtmlFiles::titles(Prefs::selectedLanguage()); } if (levelFilenames.isEmpty()){ // no kvtml files found return false; } Q_ASSERT(levelFilenames.count() == titles.count()); for(int i = 0; i < levelFilenames.count(); ++i) { m_titleLevels.insert(titles.at(i), levelFilenames.at(i)); } emit categoriesChanged(); if (!levelFilenames.contains(Prefs::levelFile())) { Prefs::setLevelFile(m_titleLevels.constBegin().value()); Prefs::setCurrentLevel(0); m_currentCategory = 0; emit currentCategoryChanged(); Prefs::self()->save(); } // don't run off the end of the list if (m_currentCategory!=-1 && m_currentCategory > m_titleLevels.count()) { m_currentCategory = m_titleLevels.count(); emit currentCategoryChanged(); } setLevel(); return true; } void KHangMan::slotDownloadNewStuff() { QPointer dialog = new KNS3::DownloadDialog(QStringLiteral("khangman.knsrc"), this); dialog->exec(); if (!dialog->changedEntries().isEmpty()) { SharedKvtmlFiles::sortDownloadedFiles(); //look for languages dirs installed scanLanguages(); //refresh Languages menu setCurrentLanguage(m_languages.indexOf(Prefs::selectedLanguage())); } delete dialog; } void KHangMan::loadLanguageSpecialCharacters() { QString lang = Prefs::selectedLanguage(); if (lang.isEmpty()) return; bool hasSpecialChars = LangUtils::hasSpecialChars(lang); m_specialCharacters.clear(); if (hasSpecialChars) { QString langFileName=QStringLiteral("khangman/%1.txt").arg(lang); QFile langFile; langFile.setFileName(QStandardPaths::locate(QStandardPaths::GenericDataLocation, langFileName)); // Let's look in local KDEHOME dir then KNS installs each .txt // in kvtml/ as it installs everything at the same place if (!langFile.exists()) { langFileName = QStringLiteral("apps/kvtml/%1/%1.txt").arg(lang); langFile.setFileName(QStandardPaths::locate(QStandardPaths::GenericDataLocation, langFileName)); } if (!langFile.exists()) { return; } update(); // We open the file and store info into the stream... QFile openFileStream(langFile.fileName()); openFileStream.open(QIODevice::ReadOnly); QTextStream readFileStr(&openFileStream); readFileStr.setCodec("UTF-8"); // m_specialCharacters contains all the words from the file // FIXME: Better name m_specialCharacters = readFileStr.readAll().split('\n'); openFileStream.close(); } } // kate: space-indent on; tab-width 4; indent-width 4; mixed-indent off; replace-tabs on; // vim: set et sw=4 ts=4 cino=l1,cs,U1: diff --git a/src/qml/GamePage.qml b/src/qml/GamePage.qml index a9b02ef..69ce609 100644 --- a/src/qml/GamePage.qml +++ b/src/qml/GamePage.qml @@ -1,678 +1,671 @@ /*********************************************************************************** * This file is part of the KHangMan project * * Copyright (C) 2012 Laszlo Papp * * Copyright (C) 2014 Rahul Chowdhury * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with this library; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***********************************************************************************/ import QtQuick 2.3 import QtQuick.Controls 1.2 import QtQuick.Layouts 1.1 import QtQuick.Controls.Styles 1.2 import QtQuick.Window 2.2 import QtMultimedia 5.0 import QtQml 2.2 import QtGraphicalEffects 1.0 Item { id: gamePage focus: true property variant alphabet: khangman.alphabet property color currentWordLetterRectangleColor: Qt.rgba(0, 0, 0, 0) property int countDownTimerValue: khangman.resolveTime property int gallowsSeriesCounter: 0 property bool initialized: false property alias isPlaying: secondTimer.running property string missedLetters: "" anchors.fill: parent function nextWord() { khangman.nextWord(); countDownTimerValue = khangman.resolveTime; // Re enable all alphabet buttons for (var i = 0; i < alphabetLetterRepeater.count; ++i) { alphabetLetterRepeater.itemAt(i).enabled = true; alphabetLetterRepeater.itemAt(i).buttonColor = "black"; } // Reset variables for the new word. gallowsSeriesCounter = 0; successImage.visible = false; missedLetters = ""; hintLabel.visible = false; if (khangman.soundEnabled) { nextWordSoundEffect.play(); } } function startTimer() { secondTimer.repeat = true; secondTimer.running = true; secondTimer.start(); } function disableLetterButton(letter) { for (var i = 0; i < alphabetLetterRepeater.count; ++i) { if (alphabetLetterRepeater.itemAt(i).upperCase == letter) { alphabetLetterRepeater.itemAt(i).enabled = false; break; } } } function guessLetter(letter) { letter = letter.toUpperCase() if (khangman.soundEnabled) { khangmanAlphabetButtonPressSoundEffect.play(); } disableLetterButton(letter); changeButtonColor(letter); if (khangman.containsChar(letter)) { khangman.replaceLetters(letter); if (khangman.isResolved()) { // the current puzzle is solved khangman.winCount++; successImage.visible = true; khangmanResultTimer.start(); if (khangman.soundEnabled) { ewDialogAppearSoundEffect.play(); } } } else { // Only add to missedLetters if it's not already there if (missedLetters.indexOf(letter) == -1) { if (gallowsSeriesCounter++ == 9) { // wrong solution given for current puzzle khangman.lossCount++; if (khangman.soundEnabled) { wrongSoundEffect.play(); } khangmanResultTimer.start(); } missedLetters += letter } } } function changeButtonColor(letter) { for (var i = 0; i < alphabetLetterRepeater.count; ++i) { if (alphabetLetterRepeater.itemAt(i).upperCase == letter) { alphabetLetterRepeater.itemAt(i).buttonColor = khangman.containsChar(letter) ? "green" : "red"; } } } MainSettingsDialog { id: mainSettingsDialog property bool wasPlaying: false onOkClicked: { - console.log("okCLicked() signal received") // close the settings dialog mainSettingsDialog.close() if (wasPlaying) { // game is going on, so load a new word and start with the saved settings nextWord() startTimer() } } onCancelClicked: { - console.log("cancelCLicked() signal received") // close the settings dialog mainSettingsDialog.close() if (wasPlaying) { // game was in progress, so resume the timer countdown startTimer() } } } // Create a selection dialog with the vocabulary titles to choose from. MySelectionDialog { id: categorySelectionDialog; title: i18n("Choose the word category"); model: khangman.categories Component.onCompleted: selectedIndex = khangman.currentCategory onSelectedIndexChanged: { if (khangman.soundEnabled) { if (!initialized) initialized = true; else nextWordSoundEffect.play(); } khangman.setCurrentCategory(selectedIndex); khangman.readFile(); nextWord(); } } // And another selection dialog with the languages to choose from. MySelectionDialog { id: languageSelectionDialog; title: i18n("Select a language"); model: khangman.languages Component.onCompleted: selectedIndex = khangman.currentLanguage onSelectedIndexChanged: { khangman.setCurrentLanguage(selectedIndex); khangman.readFile(); nextWord(); } } // And another selection dialog for choosing the theme. MySelectionDialog { id: themeSelectionDialog; title: i18n("Select a theme"); model: khangman.themes Component.onCompleted: selectedIndex = khangman.currentTheme onSelectedIndexChanged: { khangman.setCurrentTheme(selectedIndex); } } Timer { id: secondTimer; interval: 1000; repeat: true; running: false; triggeredOnStart: false; onTriggered: { if (khangman.resolveTime != 0 && --countDownTimerValue == 0) { stop(); khangmanResultTimer.start(); if (khangman.soundEnabled) { wrongSoundEffect.play(); } } } } Timer { id: khangmanResultTimer; interval: 1000; repeat: false; running: false; triggeredOnStart: false; onTriggered: { nextWord(); startTimer(); } } ToolBar { id: homePageTools anchors { top: parent.top left: parent.left right: parent.right } RowLayout { anchors.fill: parent ToolButton { id: playPauseButton iconSource: gamePage.isPlaying ? "Images/pause.png" : "Images/play.png" tooltip: gamePage.isPlaying ? i18n("Pause") : i18n("Play") onClicked: { if( gamePage.isPlaying ) { // game is currently going on, so pause it secondTimer.repeat = false secondTimer.running = false hintLabel.visible = false secondTimer.stop(); } else { // the game is paused or not yet started, so resume or start it // if the game is not yet started, play nextWordSoundeffect // denotes the game is not yet started, should return false if game is paused instead if (khangman.soundEnabled) { nextWordSoundEffect.play() } startTimer() } } } ToolButton { id: themeSelectionButton Layout.fillWidth: false text: themeSelectionDialog.model[themeSelectionDialog.selectedIndex] tooltip: i18n("Change the theme.") onClicked: { themeSelectionDialog.open() } } ToolButton { id: settingsButton Layout.fillWidth: true iconSource: "Images/settings_icon.png"; tooltip: i18n("Settings") onClicked: { // if game is currently going on then pause it mainSettingsDialog.wasPlaying = isPlaying if( gamePage.isPlaying ) { secondTimer.repeat = false secondTimer.running = false hintLabel.visible = false secondTimer.stop(); } mainSettingsDialog.open() } } ToolButton { id: aboutKhangmanButton Layout.fillWidth: true iconSource: "Images/dialog-information.png" tooltip: i18n("About KHangMan") onClicked: { khangman.showAboutKHangMan() } } ToolButton { id: aboutKDEButton Layout.fillWidth: true iconSource: "Images/about-kde.png" tooltip: i18n("About KDE") onClicked: { khangman.showAboutKDE() } } ToolButton { id: showHandbookButton Layout.fillWidth: true iconSource: "Images/handbook.png" tooltip: i18n("View the KHangMan Handbook") onClicked: { khangman.showHandbook() } } ToolButton { id: ghnsButton Layout.fillWidth: true iconSource: "Images/get-hot-new-stuff.png" tooltip: i18n("Download new language files") onClicked: { khangman.slotDownloadNewStuff() } } ToolButton { id: quitButton iconSource: "Images/quit.png" tooltip: i18n("Quit") onClicked: Qt.quit() } } } // display the remaining number of wrong guesses Row { id: misses spacing: 5 visible: isPlaying anchors { top: homePageTools.bottom topMargin: 5 right: parent.right rightMargin: 5 } Label { id: missesLabel text: i18n("Remaining guesses: ") font.pixelSize: 40 font.bold: true color: khangman.letterColor } Text { id: remainingGuessesCount text: i18n(10 - gallowsSeriesCounter) color: gallowsSeriesCounter >= 7 ? "red" : "black" font.pixelSize: 40 font.bold: true } } Label { id: scoreLabel visible: isPlaying anchors { top: misses.top left: parent.left leftMargin: 5 } text: i18n("Score: ") font.pixelSize: 40 font.bold: true color: khangman.letterColor } Label { id: netScoreLabel visible: isPlaying anchors { left: scoreLabel.right top: scoreLabel.top } text: khangman.netScore color: khangman.netScore < 0 ? "red" : "black" font.pixelSize: 40 font.bold: true } Row { id: winCountRow spacing: 15 visible: isPlaying anchors { top: scoreLabel.bottom left: parent.left leftMargin: 5 } Label { id: winLabel text: i18n("Wins: ") font.pixelSize: 40 font.bold: true color: khangman.letterColor } Label { id: winCountLabel text: khangman.winCount font.pixelSize: 40 font.bold: true color: khangman.letterColor } } Row { id: lossCountRow spacing: 15 visible: isPlaying anchors { top: winCountRow.bottom left: parent.left leftMargin: 5 } Label { id: lossLabel text: i18n("Losses: ") font.pixelSize: 40 font.bold: true color: khangman.letterColor } Label { id: lossCountLabel text: khangman.lossCount font.pixelSize: 40 font.bold: true color: khangman.letterColor } } Image { id: successImage; source: "Images/action-success.png"; visible: false; anchors { horizontalCenter: parent.horizontalCenter; verticalCenter: parent.verticalCenter; verticalCenterOffset: -parent.height/4; } } Image { id: gallowsSeriesImage; source: gallowsSeriesCounter == 0 ? "" : "gallows/gallows" + gallowsSeriesCounter + ".png" visible: (isPlaying && gallowsSeriesCounter > 0) anchors { horizontalCenter: parent.horizontalCenter; verticalCenter: parent.verticalCenter; verticalCenterOffset: -parent.height/4; } } Grid { id: currentWordGrid; visible: gamePage.isPlaying anchors { centerIn: parent; } spacing: 5; columns: 13; Repeater { id: currentWordLetterRepeater; model: khangman.currentWord; LetterElement { id: currentWordLetterId; letterText: modelData; } } } Grid { id: alphabetGrid; visible: gamePage.isPlaying anchors { horizontalCenter: parent.horizontalCenter; bottom: mainPageTools.top; bottomMargin: 10; } spacing: gamePage.width/35; columns: 13; Repeater { id: alphabetLetterRepeater; model: alphabet; Button { id: alphabetButton; property string letter: modelData property string upperCase: modelData.toUpperCase() property string buttonColor: "black" style: ButtonStyle { id: alphabetLetterIdStyle background: Rectangle { id: alphabetLetterIdStyleRectangle implicitWidth: gamePage.width / 22 implicitHeight: gamePage.width / 22 color: buttonColor radius: 8 layer.enabled: true layer.effect: DropShadow { radius: 4 horizontalOffset: 3 verticalOffset: 3 spread: 0 samples: radius * 2 source: alphabetLetterIdStyleRectangle color: Qt.rgba(0, 0, 0, 0.5) transparentBorder: true } } label: Text { id: buttonLabel anchors.centerIn: parent text: letter font.family : "Arial" font.pixelSize: gamePage.width / 40 font.capitalization : Font.AllUppercase font.weight : Font.Bold horizontalAlignment : Text.AlignHCenter verticalAlignment : Text.AlignVCenter color: parent.enabled ? "white" : "grey" } } onClicked: { guessLetter(modelData); } } } } Label { id: hintLabel text: khangman.currentHint font.family: "serif-sans" color: "green" font.italic: true font.pixelSize: gamePage.width / 60 anchors.top: currentWordGrid.bottom anchors.bottom: alphabetGrid.top anchors.horizontalCenter: parent.horizontalCenter visible: false } ToolBar { id: mainPageTools anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom visible: isPlaying RowLayout { anchors.fill: parent ToolButton { id: helpHintButton iconSource: "Images/help-hint.png" tooltip: i18n("Display the hint.") enabled: hintLabel.text != "" onClicked: { // make the button toggle between display and hide the hint hintLabel.visible = hintLabel.visible ? false : true - //console.log("hintLabel.font.family = " + hintLabel.font.family) } } ToolButton { id: categorySelectionButton Layout.fillWidth: true text: categorySelectionDialog.model[categorySelectionDialog.selectedIndex]; tooltip: i18n("Change the category.") onClicked: { categorySelectionDialog.open(); } } ToolButton { id: languageSelectionButton Layout.fillWidth: true text: languageSelectionDialog.model[languageSelectionDialog.selectedIndex] tooltip: i18n("Change the language.") onClicked: { languageSelectionDialog.open() } } ToolButton { id: revealWordButton Layout.fillWidth: true text: i18n("Reveal Word") tooltip: i18n("Reveal the current word.") onClicked: { khangman.revealCurrentWord(); khangman.lossCount++; if (khangman.soundEnabled) { wrongSoundEffect.play(); } khangmanResultTimer.start(); } } Text { id: timerText visible: khangman.resolveTime == 0 ? false : true text: Math.floor(countDownTimerValue / 60) + ":" + Math.floor(countDownTimerValue % 60 / 10) + Math.floor(countDownTimerValue % 60 % 10) } ToolButton { id: nextWordButton Layout.fillWidth: true iconSource: "Images/go-next.png"; tooltip: i18n("Load the next word and start a new game.") onClicked: { if (khangman.soundEnabled) { - //console.log("kahngman.sound = true") - //console.log("checking sound effect loaded" + nextWordSoundeffect.isLoaded()); nextWordSoundEffect.play(); - } else { - //console.log("khangman.soundEnabled = false") } nextWord(); secondTimer.repeat = true; secondTimer.restart(); } } } } Keys.onPressed: { if (event.text.length > 0) { guessLetter(event.text); } } }