Warning, /education/gcompris/src/activities/readingh/Readingh.qml is written in an unsupported language. File is not indexed.

0001 /* GCompris - readingh.qml
0002  *
0003  * SPDX-FileCopyrightText: 2015 Johnny Jazeix <jazeix@gmail.com>
0004  *
0005  * Authors:
0006  *   Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
0007  *   Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
0008  *   Timothée Giet <animtim@gmail.com> (graphics and improvements)
0009  *
0010  *   SPDX-License-Identifier: GPL-3.0-or-later
0011  */
0012 import QtQuick 2.12
0013 import GCompris 1.0
0014 
0015 import "../../core"
0016 import "readingh.js" as Activity
0017 import "qrc:/gcompris/src/core/core.js" as Core
0018 
0019 ActivityBase {
0020     id: activity
0021 
0022     onStart: focus = true
0023     onStop: {}
0024 
0025     property int speedSetting: 5
0026     /* mode of the activity, "readingh" (horizontal) or "readingv" (vertical):*/
0027     property string mode: "readingh"
0028 
0029     pageComponent: Image {
0030         id: background
0031         anchors.fill: parent
0032         source: Activity.url + "reading-bg.svg"
0033         signal start
0034         signal stop
0035         sourceSize.width: parent.width
0036         fillMode: Image.Stretch
0037 
0038         Component.onCompleted: {
0039             dialogActivityConfig.initialize()
0040             activity.start.connect(start)
0041             activity.stop.connect(stop)
0042         }
0043 
0044         // system locale by default
0045         property string locale: "system"
0046 
0047         property int baseMargins: 10 * ApplicationInfo.ratio
0048         property bool isHorizontalLayout: background.width >= background.height
0049 
0050         // Add here the QML items you need to access in javascript
0051         QtObject {
0052             id: items
0053             property Item main: activity.main
0054             property alias background: background
0055             property int currentLevel: activity.currentLevel
0056             property alias bonus: bonus
0057             property alias wordlist: wordlist
0058             property alias score: score
0059             property alias wordDropTimer: wordDropTimer
0060             property alias locale: background.locale
0061             property alias iAmReady: iAmReady
0062             property alias answerButtonFound: answerButtonFound
0063             property alias answerButtonNotFound: answerButtonNotFound
0064             property alias answerButtonsFlow: answerButtonsFlow
0065             property alias wordDisplayRepeater: wordDisplayRepeater
0066             property string textToFind
0067             property int currentIndex
0068             property bool buttonsBlocked: false
0069         }
0070 
0071         onStart: { Activity.start(items, mode) }
0072         onStop: { Activity.stop() }
0073 
0074         DialogChooseLevel {
0075             id: dialogActivityConfig
0076             currentActivity: activity.activityInfo
0077             onClose: {
0078                 home()
0079             }
0080             onSaveData: {
0081                 levelFolder = dialogActivityConfig.chosenLevels
0082                 currentActivity.currentLevels = dialogActivityConfig.chosenLevels
0083                 ApplicationSettings.setCurrentLevels(currentActivity.name, dialogActivityConfig.chosenLevels)
0084             }
0085             onLoadData: {
0086                 if(activityData && activityData["locale"]) {
0087                     background.locale = Core.resolveLocale(activityData["locale"]);
0088                 }
0089                 else {
0090                     background.locale = Core.resolveLocale(background.locale);
0091                 }
0092                 if(activityData && activityData["speedSetting"]) {
0093                     activity.speedSetting = activityData["speedSetting"];
0094                 }
0095             }
0096             onStartActivity: {
0097                 background.stop()
0098                 background.start()
0099             }
0100         }
0101 
0102         DialogHelp {
0103             id: dialogHelp
0104             onClose: home()
0105         }
0106 
0107         Bar {
0108             id: bar
0109             level: items.currentLevel + 1
0110             content: BarEnumContent { value: help | home | level | activityConfig }
0111             onHelpClicked: {
0112                 displayDialog(dialogHelp)
0113             }
0114             onPreviousLevelClicked: Activity.previousLevel()
0115             onNextLevelClicked: Activity.nextLevel()
0116             onHomeClicked: activity.home()
0117             onActivityConfigClicked: {
0118                 displayDialog(dialogActivityConfig)
0119             }
0120         }
0121 
0122         Bonus {
0123             id: bonus
0124             Component.onCompleted: {
0125                 win.connect(Activity.nextLevel)
0126             }
0127         }
0128 
0129         Item {
0130             id: mainArea
0131             anchors.fill: background
0132             anchors.bottomMargin: bar.height * 1.2
0133             anchors.topMargin: background.baseMargins
0134             anchors.leftMargin: background.baseMargins
0135             anchors.rightMargin: background.baseMargins
0136         }
0137 
0138         states: [
0139             State {
0140                 id: horizontalLayout
0141                 when: background.isHorizontalLayout
0142                 PropertyChanges {
0143                     target: wordDisplayListBg
0144                     anchors.margins: background.baseMargins
0145                     width: 0.45 * mainArea.width
0146                 }
0147                 AnchorChanges {
0148                     target: wordDisplayListBg
0149                     anchors.top: mainArea.top
0150                     anchors.bottom: mainArea.bottom
0151                 }
0152                 PropertyChanges {
0153                     target: wordToFindBoxBg
0154                     anchors.margins: background.baseMargins
0155                     width: mainArea.width * 0.45
0156                     height: mainArea.height * 0.3
0157                 }
0158                 AnchorChanges {
0159                     target: wordToFindBoxBg
0160                     anchors.horizontalCenter: buttonsArea.horizontalCenter
0161                     anchors.top: mainArea.top
0162                 }
0163                 PropertyChanges {
0164                     target: buttonsArea
0165                     height: wordDisplayListBg.height * 0.5
0166                 }
0167                 AnchorChanges {
0168                     target: buttonsArea
0169                     anchors.top: wordToFindBoxBg.bottom
0170                     anchors.left: wordDisplayListBg.right
0171                     anchors.right: background.right
0172                     anchors.bottom: score.top
0173                     anchors.verticalCenter: undefined
0174                 }
0175             },
0176             State {
0177                 id: verticalLayout
0178                 when: !background.isHorizontalLayout
0179                 PropertyChanges {
0180                     target: wordDisplayListBg
0181                     anchors.margins: background.baseMargins
0182                 }
0183                 AnchorChanges {
0184                     target: wordDisplayListBg
0185                     anchors.top: wordToFindBoxBg.bottom
0186                     anchors.bottom: score.top
0187                     anchors.left: mainArea.left
0188                     anchors.right: mainArea.right
0189                 }
0190                 PropertyChanges {
0191                     target: wordToFindBoxBg
0192                     anchors.margins: 0
0193                     width: mainArea.width - 4 * background.baseMargins
0194                     height: mainArea.height * 0.2
0195                 }
0196                 AnchorChanges {
0197                     target: wordToFindBoxBg
0198                     anchors.horizontalCenter: mainArea.horizontalCenter
0199                     anchors.top: mainArea.top
0200                 }
0201                 PropertyChanges {
0202                     target: buttonsArea
0203                     height: wordDisplayListBg.height * 0.5
0204                 }
0205                 AnchorChanges {
0206                     target: buttonsArea
0207                     anchors.top: undefined
0208                     anchors.bottom: undefined
0209                     anchors.left: wordDisplayListBg.left
0210                     anchors.right: wordDisplayListBg.right
0211                     anchors.verticalCenter: wordDisplayListBg.verticalCenter
0212                 }
0213             }
0214         ]
0215 
0216         Rectangle {
0217             id: wordDisplayListBgShadow
0218             color: "#50000000"
0219             width: wordDisplayListBg.width
0220             height: wordDisplayListBg.height
0221             x: wordDisplayListBg.x + 2 * ApplicationInfo.ratio
0222             y: wordDisplayListBg.y + 2 * ApplicationInfo.ratio
0223         }
0224 
0225         Rectangle {
0226             id: wordDisplayListBg
0227             color: "#F2F2F2"
0228             anchors.top: mainArea.top
0229             anchors.left: mainArea.left
0230             anchors.margins: background.baseMargins
0231             width: 0.45 * mainArea.width
0232             height: mainArea.height
0233         }
0234 
0235         Flow {
0236             id: wordDisplayList
0237             spacing: 20
0238             anchors.fill: wordDisplayListBg
0239             anchors.margins: background.baseMargins
0240             flow: mode == "readingh" ? Flow.LeftToRight : Flow.TopToBottom
0241             layoutDirection: Core.isLeftToRightLocale(locale) ? Qt.LeftToRight : Qt.RightToLeft
0242 
0243             Repeater {
0244                 id: wordDisplayRepeater
0245                 model: Activity.words
0246                 property int idToHideBecauseOverflow: 0
0247                 delegate: GCText {
0248                     text: modelData
0249                     color: "#373737"
0250                     opacity: iAmReady.visible ? false : (index == items.currentIndex ? 1 : 0)
0251 
0252                     onOpacityChanged: {
0253                     /* Handle case where we go over the image
0254                     On these cases, we hide all above items to restart to 0
0255                     As we don't replay the same level and always replace the model,
0256                     we do not care about restoring visible to true */
0257                         if((x+width > wordDisplayList.width) ||
0258                            (y+height > wordDisplayList.height)) {
0259                             var i = wordDisplayRepeater.idToHideBecauseOverflow;
0260                             for(; i < index; ++i) {
0261                                 wordDisplayRepeater.itemAt(i).visible=false
0262                             }
0263                             wordDisplayRepeater.idToHideBecauseOverflow = i
0264                         }
0265                     }
0266                 }
0267             }
0268         }
0269 
0270         Rectangle {
0271             color: "#50000000"
0272             width: wordToFindBoxBg.width
0273             height: wordToFindBoxBg.height
0274             x: wordToFindBoxBg.x + 2 * ApplicationInfo.ratio
0275             y: wordToFindBoxBg.y + 2 * ApplicationInfo.ratio
0276             radius: background.baseMargins
0277         }
0278         Rectangle {
0279             id: wordToFindBoxBg
0280             color: "#E8E8E8"
0281             anchors.horizontalCenter: buttonsArea.horizontalCenter
0282             anchors.top: mainArea.top
0283             anchors.margins: background.baseMargins
0284             width: mainArea.width * 0.45
0285             height: mainArea.height * 0.3
0286             radius: background.baseMargins
0287         }
0288         Rectangle {
0289             color: "transparent"
0290             anchors.fill: wordToFindBoxBg
0291             anchors.margins: background.baseMargins
0292             border.width: 2 * ApplicationInfo.ratio
0293             border.color: "#87A6DD"
0294             radius: background.baseMargins
0295         }
0296 
0297         GCText {
0298             id: wordToFindBox
0299             text: qsTr("<font color=\"#373737\">Check if the word<br/></font><b><font color=\"#315AAA\">%1</font></b><br/><font color=\"#373737\">is displayed</font>").arg(items.textToFind)
0300             color: "#373737"
0301             horizontalAlignment: Text.AlignHCenter
0302             anchors.fill: wordToFindBoxBg
0303             anchors.topMargin: 1.2 * background.baseMargins
0304             anchors.bottomMargin: 1.2 * background.baseMargins
0305             anchors.leftMargin: 2 * background.baseMargins
0306             anchors.rightMargin: 2 * background.baseMargins
0307             fontSizeMode: Text.Fit
0308         }
0309 
0310         Score {
0311             id: score
0312             anchors.right: mainArea.right
0313             anchors.bottom: mainArea.bottom
0314             anchors.margins: background.baseMargins
0315         }
0316 
0317         Item {
0318             id: buttonsArea
0319             anchors.top: wordToFindBoxBg.bottom
0320             anchors.left: wordDisplayListBg.right
0321             anchors.right: background.right
0322             anchors.bottom: score.top
0323             anchors.margins: 10 * ApplicationInfo.ratio
0324         }
0325 
0326         ReadyButton {
0327             id: iAmReady
0328             onClicked: Activity.run()
0329             anchors.centerIn: buttonsArea
0330             theme: "light"
0331         }
0332 
0333         Rectangle {
0334             color: "#313131"
0335             width: answerButtonsFlow.width + background.baseMargins * 2
0336             height: answerButtonsFlow.height + background.baseMargins * 2
0337             anchors.centerIn: answerButtonsFlow
0338             visible: !background.isHorizontalLayout && answerButtonsFlow.visible
0339         }
0340 
0341         Flow {
0342             id: answerButtonsFlow
0343             width: Math.min(250 * ApplicationInfo.ratio, buttonsArea.width)
0344             height: Math.min(120 * ApplicationInfo.ratio, buttonsArea.height * 0.5)
0345             anchors.centerIn: buttonsArea
0346             visible: false
0347             AnswerButton {
0348                 id : answerButtonFound
0349                 width: parent.width
0350                 height: parent.height * 0.5
0351                 textLabel: qsTr("Yes, I saw it!")
0352                 isCorrectAnswer: Activity.words ? Activity.words.indexOf(items.textToFind) != -1 : false
0353                 onCorrectlyPressed: Activity.nextSubLevel()
0354                 onIncorrectlyPressed: Activity.retrySubLevel()
0355                 blockAllButtonClicks: items.buttonsBlocked
0356                 onPressed: {
0357                     items.buttonsBlocked = true
0358                     if(isCorrectAnswer) {
0359                         activity.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/completetask.wav");
0360                         score.currentSubLevel += 1;
0361                         score.playWinAnimation();
0362                     } else {
0363                         activity.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/crash.wav");
0364                     }
0365                 }
0366             }
0367 
0368             AnswerButton {
0369                 id : answerButtonNotFound
0370                 width: parent.width
0371                 height: answerButtonFound.height
0372                 textLabel: qsTr("No, it was not there!")
0373                 isCorrectAnswer: !answerButtonFound.isCorrectAnswer
0374                 onCorrectlyPressed: Activity.nextSubLevel()
0375                 onIncorrectlyPressed: Activity.retrySubLevel()
0376                 blockAllButtonClicks: items.buttonsBlocked
0377                 onPressed: {
0378                     items.buttonsBlocked = true
0379                     if(isCorrectAnswer) {
0380                         activity.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/completetask.wav");
0381                         score.currentSubLevel += 1;
0382                         score.playWinAnimation();
0383                     } else {
0384                         activity.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/crash.wav");
0385                     }
0386                 }
0387             }
0388         }
0389 
0390         Wordlist {
0391             id: wordlist
0392             defaultFilename: Activity.dataSetUrl + "default-en.json"
0393             // To switch between locales: xx_XX stored in configuration and
0394             // possibly correct xx if available (ie fr_FR for french but dataset is fr.)
0395             useDefault: false
0396             filename: ""
0397 
0398             onError: console.log("Reading: Wordlist error: " + msg);
0399         }
0400 
0401         Timer {
0402             id: wordDropTimer
0403             repeat: true
0404             interval: items.currentIndex == -1 ? 100 : 5000 / speedSetting;
0405             onTriggered: Activity.dropWord();
0406         }
0407 
0408     }
0409 
0410 }