Warning, /education/gcompris/src/activities/hangman/Hangman.qml is written in an unsupported language. File is not indexed.
0001 /* GCompris - hangman.qml
0002 *
0003 * SPDX-FileCopyrightText: 2015 Rajdeep Kaur <rajdeep51994@gmail.com>
0004 *
0005 * Authors:
0006 * Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
0007 * Rajdeep kaur<rajdeep51994@gmail.com> (Qt Quick port)
0008 *
0009 * SPDX-License-Identifier: GPL-3.0-or-later
0010 */
0011 import QtQuick 2.12
0012 import GCompris 1.0
0013 import QtGraphicalEffects 1.0
0014
0015 import "../../core"
0016 import "hangman.js" as Activity
0017 import "qrc:/gcompris/src/core/core.js" as Core
0018
0019 ActivityBase {
0020 id: activity
0021
0022 // Overload this in your activity to change it
0023 // Put you default-<locale>.json files in it
0024 property string dataSetUrl: "qrc:/gcompris/src/activities/hangman/resource/"
0025
0026 onStart: focus = true
0027 onStop: { }
0028 // When going on configuration, it steals the focus and re set it to the activity.
0029 // We need to set it back to the textinput item in order to have key events.
0030 onFocusChanged: {
0031 if(focus) {
0032 Activity.focusTextInput();
0033 }
0034 }
0035
0036 pageComponent: Image {
0037 id: background
0038 source: activity.dataSetUrl + "background.svg"
0039 fillMode: Image.PreserveAspectCrop
0040 anchors.fill: parent
0041 sourceSize.width: width
0042 sourceSize.height: height
0043
0044 // system locale by default
0045 property string locale: "system"
0046
0047 property bool englishFallback: false
0048
0049 signal start
0050 signal stop
0051
0052 Component.onCompleted: {
0053 dialogActivityConfig.initialize()
0054 activity.start.connect(start)
0055 activity.stop.connect(stop)
0056 }
0057
0058 // Add here the QML items you need to access in javascript
0059 QtObject {
0060 id: items
0061 property Item main: activity.main
0062 property alias background: background
0063 property Item ourActivity: activity
0064 property int currentLevel: activity.currentLevel
0065 property alias bonus: bonus
0066 property alias keyboard: keyboard
0067 property alias hidden: hidden
0068 property alias guessedText: guessedText
0069 property alias textinput: textinput
0070 property alias wordImage: wordImage
0071 property alias score: score
0072 property alias parser: parser
0073 property alias locale: background.locale
0074 property alias ok: ok
0075 property int remainingLife
0076 property double maskThreshold
0077 property var goodWord
0078 property int goodWordIndex
0079 property bool easyModeImage: true
0080 property bool easyModeAudio: true
0081 property alias englishFallbackDialog: englishFallbackDialog
0082 property alias winTimer: winTimer
0083 property alias goodIcon: goodIcon
0084
0085 function playWord() {
0086 var locale = ApplicationInfo.getVoicesLocale(items.locale)
0087 if(activity.audioVoices.append(
0088 ApplicationInfo.getAudioFilePathForLocale(goodWord.voice, locale)))
0089 bonus.interval = 2500
0090 else
0091 bonus.interval = 500
0092 }
0093 onRemainingLifeChanged: {
0094 maskThreshold = 0.15 * remainingLife
0095 if(easyModeAudio && (remainingLife == 3)) {
0096 playWord();
0097 }
0098 }
0099 }
0100
0101 onStart: {
0102 focus = true;
0103 Activity.start(items);
0104 if(!background.englishFallback)
0105 Activity.focusTextInput();
0106 }
0107
0108 onStop: {
0109 Activity.stop();
0110 }
0111
0112 Image {
0113 id: goodIcon
0114 source: "qrc:/gcompris/src/core/resource/apply.svg"
0115 anchors.top: score.bottom
0116 anchors.horizontalCenter: score.horizontalCenter
0117 anchors.topMargin: ok.anchors.bottomMargin
0118 sourceSize.height: ok.width
0119 sourceSize.width: ok.width
0120 visible: false
0121 }
0122
0123 GCText {
0124 id: hidden
0125 fontSize: largeSize
0126 color: "#4d4d4d"
0127 font.letterSpacing: 0.5
0128 width: parent.width * 0.90 - score.width
0129 fontSizeMode: Text.Fit
0130 horizontalAlignment: Text.AlignHCenter
0131 anchors {
0132 right: score.left
0133 bottom: bar.top
0134 bottomMargin: 10 * ApplicationInfo.ratio
0135 }
0136 z: 11
0137 }
0138
0139 GCText {
0140 id: guessedText
0141 fontSize: smallSize
0142 color: "#FFFFFF"
0143 wrapMode: Text.WordWrap
0144 width: guessedTextBg.width
0145 horizontalAlignment: Text.AlignHCenter
0146 anchors {
0147 horizontalCenter: parent.horizontalCenter
0148 }
0149 z: 12
0150 }
0151
0152 Rectangle {
0153 id: guessedTextBg
0154 width: parent.width * 0.7
0155 height: guessedText.height
0156 radius: 10
0157 border.color: "#121212"
0158 border.width: 1
0159 color: "#373737"
0160 anchors {
0161 horizontalCenter: parent.horizontalCenter
0162 }
0163 z: 11
0164 }
0165
0166 TextInput {
0167 // Helper element to capture composed key events like french รด which
0168 // are not available via Keys.onPressed() on linux. Must be
0169 // disabled on mobile!
0170 id: textinput
0171 enabled: !ApplicationInfo.isMobile
0172 visible: false
0173 focus: true
0174 onTextChanged: {
0175 if (text != "") {
0176 Activity.processKeyPress(text);
0177 text = "";
0178 }
0179 }
0180 onAccepted: if(items.remainingLife === 0) Activity.nextSubLevel()
0181 }
0182
0183 Item {
0184 id: imageframe
0185 width: Math.min(300 * ApplicationInfo.ratio,
0186 background.width * 0.8,
0187 hidden.y) - guessedText.height
0188 height: width
0189 anchors.horizontalCenter: parent.horizontalCenter
0190 anchors.top: guessedText.bottom
0191 y: 5 * ApplicationInfo.ratio
0192 z: 10
0193 opacity: items.easyModeImage ? 1 : 0
0194 Image {
0195 id: wordImage
0196 smooth: true
0197 visible: false
0198
0199 anchors.fill: parent
0200 property string nextSource
0201 function changeSource(nextSource_) {
0202 nextSource = nextSource_
0203 animImage.start()
0204 }
0205
0206 SequentialAnimation {
0207 id: animImage
0208 PropertyAnimation {
0209 target: wordImage
0210 property: "opacity"
0211 to: 0
0212 duration: 100
0213 }
0214 PropertyAction {
0215 target: wordImage
0216 property: "source"
0217 value: wordImage.nextSource
0218 }
0219 PropertyAnimation {
0220 target: wordImage
0221 property: "opacity"
0222 to: 1
0223 duration: 100
0224 }
0225 }
0226 }
0227
0228 Image {
0229 id: threshmask
0230 smooth: true
0231 visible: false
0232 width: 1.3*parent.width
0233 height: 1.2*parent.height
0234 source: dataSetUrl + "fog.png"
0235 }
0236
0237 ThresholdMask {
0238 id: thresh
0239 anchors.fill: wordImage
0240 source: wordImage
0241 maskSource: threshmask
0242 spread: 0.4
0243 // remainingLife between 0 and 6 => threshold between 0 and 0.9
0244 threshold: items.maskThreshold
0245 }
0246 }
0247
0248 DialogChooseLevel {
0249 id: dialogActivityConfig
0250 currentActivity: activity.activityInfo
0251 onClose: {
0252 home()
0253 }
0254 onSaveData: {
0255 levelFolder = dialogActivityConfig.chosenLevels
0256 currentActivity.currentLevels = dialogActivityConfig.chosenLevels
0257 ApplicationSettings.setCurrentLevels(currentActivity.name, dialogActivityConfig.chosenLevels)
0258 }
0259 onLoadData: {
0260 if(activityData && activityData["locale"]) {
0261 background.locale = Core.resolveLocale(activityData["locale"]);
0262 }
0263 else {
0264 background.locale = Core.resolveLocale(background.locale);
0265 }
0266 if(activityData) {
0267 if(activityData["easyModeImage"])
0268 items.easyModeImage = (activityData["easyModeImage"] === "true");
0269 else if(activityData["easyMode"])
0270 items.easyModeImage = (activityData["easyMode"] === "true");
0271 }
0272 if(activityData && activityData["easyModeAudio"]) {
0273 items.easyModeAudio = (activityData["easyModeAudio"] === "true");
0274 }
0275
0276 }
0277 onStartActivity: {
0278 background.stop()
0279 background.start()
0280 }
0281 }
0282
0283 DialogHelp {
0284 id: dialogHelp
0285 onClose: home()
0286 }
0287
0288 Bar {
0289 id: bar
0290 level: items.currentLevel + 1
0291 anchors.bottom: keyboard.top
0292 content: BarEnumContent { value: help | home | level | activityConfig }
0293 onHelpClicked: {
0294 displayDialog(dialogHelp)
0295 }
0296 onPreviousLevelClicked: Activity.previousLevel()
0297 onNextLevelClicked: Activity.nextLevel()
0298 onHomeClicked: activity.home()
0299 onActivityConfigClicked: {
0300 displayDialog(dialogActivityConfig)
0301 }
0302 }
0303
0304 Score {
0305 id: score
0306 height: 1.2 * internalTextComponent.height
0307 width: 1.3 * internalTextComponent.width
0308 isScoreCounter: false
0309 anchors {
0310 top: guessedTextBg.bottom
0311 bottom: undefined
0312 right: parent.right
0313 margins: 0.025 * parent.width
0314 }
0315 }
0316
0317 BarButton {
0318 id: ok
0319 source: "qrc:/gcompris/src/core/resource/bar_ok.svg";
0320 sourceSize.width: Math.min(score.width, clock.width)
0321 visible: false
0322 anchors {
0323 top: score.bottom
0324 horizontalCenter: score.horizontalCenter
0325 topMargin: 5 * ApplicationInfo.ratio
0326 }
0327 onClicked: Activity.nextSubLevel()
0328 }
0329
0330 JsonParser {
0331 id: parser
0332 onError: console.error("Hangman: Error parsing json: " + msg);
0333 }
0334
0335 Image {
0336 id: clock
0337 anchors {
0338 left: parent.left
0339 top: guessedTextBg.bottom
0340 margins: 0.025 * parent.width
0341 }
0342 sourceSize.width: 66 * bar.barZoom
0343 property int remainingLife: items.remainingLife
0344 onRemainingLifeChanged: if(remainingLife >= 0) clockAnim.restart()
0345
0346 SequentialAnimation {
0347 id: clockAnim
0348 alwaysRunToEnd: true
0349 ParallelAnimation {
0350 NumberAnimation {
0351 target: clock; properties: "opacity";
0352 to: 0; duration: 800; easing.type: Easing.OutCubic
0353 }
0354 NumberAnimation {
0355 target: clock; properties: "rotation"; from: 0; to: 180;
0356 duration: 800; easing.type: Easing.OutCubic
0357 }
0358 }
0359 PropertyAction {
0360 target: clock; property: 'source';
0361 value: "qrc:/gcompris/src/activities/reversecount/resource/" +
0362 "flower" + items.remainingLife + ".svg"
0363 }
0364 ParallelAnimation {
0365 NumberAnimation {
0366 target: clock; properties: "opacity";
0367 to: 1; duration: 800; easing.type: Easing.OutCubic
0368 }
0369 NumberAnimation {
0370 target: clock; properties: "rotation"; from: 180; to: 0;
0371 duration: 800; easing.type: Easing.OutCubic
0372 }
0373 }
0374 }
0375 }
0376
0377 VirtualKeyboard {
0378 id: keyboard
0379 anchors.bottom: parent.bottom
0380 anchors.horizontalCenter: parent.horizontalCenter
0381 width: parent.width
0382 onKeypress: {
0383 Activity.processKeyPress(text);
0384 // Set the focus back to the InputText for keyboard input
0385 Activity.focusTextInput();
0386 }
0387 onError: console.log("VirtualKeyboard error: " + msg);
0388 }
0389
0390 Bonus {
0391 id: bonus
0392 interval: 2000
0393 onLoose: ok.visible = true
0394 onWin: Activity.nextSubLevel()
0395 }
0396
0397 Loader {
0398 id: englishFallbackDialog
0399 sourceComponent: GCDialog {
0400 parent: activity
0401 isDestructible: false
0402 message: qsTr("We are sorry, we don't have yet a translation for your language.") + " " +
0403 qsTr("GCompris is developed by the KDE community, you can translate GCompris by joining a translation team on <a href=\"%2\">%2</a>").arg("https://l10n.kde.org/") +
0404 "<br /> <br />" +
0405 qsTr("We switched to English for this activity but you can select another language in the configuration dialog.")
0406 onClose: {
0407 background.englishFallback = false;
0408 Activity.focusTextInput;
0409 }
0410 }
0411 anchors.fill: parent
0412 focus: true
0413 active: background.englishFallback
0414 onStatusChanged: if (status == Loader.Ready) item.start()
0415 }
0416
0417 Timer {
0418 id: winTimer
0419 interval: 2000
0420 onTriggered: bonus.good("lion")
0421 }
0422 }
0423 }