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

0001 /* GCompris - SolarSystem.qml
0002  *
0003  * SPDX-FileCopyrightText: 2018 Aman Kumar Gupta <gupta2140@gmail.com>
0004  *
0005  * Authors:
0006  *    Aman Kumar Gupta <gupta2140@gmail.com>
0007  *    Timothée Giet <animtim@gmail.com> (graphics, layout and keyboard controls)
0008  *
0009  *   SPDX-License-Identifier: GPL-3.0-or-later
0010  */
0011 import QtQuick 2.12
0012 import GCompris 1.0
0013 import "../../core"
0014 import "solar_system.js" as Activity
0015 
0016 ActivityBase {
0017     id: activity
0018 
0019     onStart: {
0020         focus = true;
0021     }
0022     onStop: {}
0023 
0024     pageComponent: Rectangle {
0025         id: background
0026         anchors.fill: parent
0027         property bool horizontalLayout: background.width >= background.height
0028 
0029         Image {
0030             id: stars
0031             fillMode: Image.PreserveAspectCrop
0032             source: "qrc:/gcompris/src/activities/solar_system/resource/background.svg"
0033             width: horizontalLayout ? parent.width * 2.5 : parent.height * 2.5
0034             height: stars.width
0035             sourceSize.width: stars.width
0036             sourceSize.height: stars.width
0037 
0038             transform: Rotation {
0039                 origin.x: stars.width / 2; origin.y: stars.height / 2; angle: 0;
0040                     NumberAnimation on angle{
0041                     loops: Animation.Infinite
0042                     from: 0
0043                     to: 360
0044                     duration: 108000
0045                 }
0046             }
0047         }
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 int currentLevel: activity.currentLevel
0064             property alias bar: bar
0065             property alias bonus: bonus
0066             property alias planetsModel: planetsModel
0067             property alias mainQuizScreen: mainQuizScreen
0068             property alias dialogActivityConfig: dialogActivityConfig
0069             property string mode: "learning"
0070             property bool assessmentMode: mode === "assessment" ? true : false
0071             property bool solarSystemVisible: true
0072             property bool quizScreenVisible: false
0073             property string temperatureHint
0074             property string lengthOfYearHint
0075             property bool hintProvided: true
0076             property bool restartAssessmentMessage: false
0077         }
0078 
0079         onStart: Activity.start(items)
0080         onStop: Activity.stop()
0081 
0082         property bool keyboardMode: false
0083 
0084         // Needed to get keyboard focus on IntroMessage
0085         Keys.forwardTo: message
0086 
0087         Keys.onPressed: {
0088             if(!mainQuizScreen.visible) {
0089                 if(event.key === Qt.Key_Down) {
0090                     planetView.moveCurrentIndexDown();
0091                 } else if(event.key === Qt.Key_Right) {
0092                     planetView.moveCurrentIndexRight();
0093                 } else if(event.key === Qt.Key_Up) {
0094                     planetView.moveCurrentIndexUp();
0095                 } else if(event.key === Qt.Key_Left) {
0096                     planetView.moveCurrentIndexLeft();
0097                 } else if((event.key === Qt.Key_Enter || event.key === Qt.Key_Space || event.key === Qt.Key_Return) && planetView.currentIndex !== -1) {
0098                     Activity.showQuizScreen(planetView.currentIndex);
0099                 }
0100             } else {
0101                 if(mainQuizScreen.blockAnswerButtons) {
0102                     return;
0103                 }
0104                 if(event.key === Qt.Key_Down || event.key === Qt.Key_Right) {
0105                     if(mainQuizScreen.optionListView.currentIndex <
0106                         mainQuizScreen.optionListView.count - 1) {
0107                          mainQuizScreen.optionListView.currentIndex += 1;
0108                     } else {
0109                         mainQuizScreen.optionListView.currentIndex = 0;
0110                     }
0111                 } else if(event.key === Qt.Key_Up || event.key === Qt.Key_Left) {
0112                     if(mainQuizScreen.optionListView.currentIndex > 0) {
0113                          mainQuizScreen.optionListView.currentIndex -= 1;
0114                     } else {
0115                         mainQuizScreen.optionListView.currentIndex =
0116                         mainQuizScreen.optionListView.count - 1;
0117                     }
0118                 } else if((event.key === Qt.Key_Enter || event.key === Qt.Key_Space || event.key === Qt.Key_Return) && mainQuizScreen.optionListView.currentIndex !== -1) {
0119                     mainQuizScreen.optionListView.currentItem.pressed();
0120                 }
0121             }
0122         }
0123 
0124         Keys.onTabPressed: {
0125             if(items.hintProvided) {
0126                 if(items.assessmentMode)
0127                     solarSystemImageHint.visible = true;
0128                 else
0129                     displayDialog(hintDialog);
0130             }
0131         }
0132 
0133 
0134         Keys.onEscapePressed: {
0135             mainQuizScreen.closenessMeter.stopAnimations();
0136             if(items.solarSystemVisible || (items.assessmentMode && !solarSystemImageHint.visible))
0137                 activity.home();
0138             else if(solarSystemImageHint.visible)
0139                 solarSystemImageHint.visible = false
0140             else
0141                 Activity.showSolarModel();
0142         }
0143 
0144         Keys.onReleased: {
0145             keyboardMode = true
0146         }
0147 
0148         IntroMessage {
0149             id: message
0150             anchors {
0151                 top: parent.top
0152                 topMargin: 10
0153                 right: parent.right
0154                 rightMargin: 5
0155                 left: parent.left
0156                 leftMargin: 5
0157             }
0158             z: 10
0159 
0160             readonly property string commonInstruction: qsTr("Mode: <font color=\"#3bb0de\">%1</font><br><br>There are two modes in the activity which you can switch from the configuration window:<br><b>1. Learning mode</b> - In this mode you can play and learn about the Solar System.<br><b>2. Assessment mode</b> - In this mode you can test your knowledge about the Solar System.").arg(items.assessmentMode ? qsTr("Assessment") : qsTr("Learning"))
0161 
0162             readonly property var learningModeInstructions: [
0163                 commonInstruction,
0164                 qsTr("Click on the Sun or any planet to reveal questions. Each question has 4 options, out of which one is correct."),
0165                 qsTr("After a planet is clicked, the Closeness meter at the bottom-right corner of the screen represents the degree of correctness of your selected answer. The least correct answer is represented by 1%. Try again until you reach a 100% closeness by following the closeness meter. If the hint button is visible, you can click on it to get a hint to find the answer.")
0166             ]
0167 
0168             readonly property var assessmentModeInstructions: [
0169                 commonInstruction,
0170                 qsTr("There are 20 questions initially with 4 options each. The progress bar at the bottom right of the screen shows your percentage score."),
0171                 qsTr("If your answer is correct, your score increases.<br>If your answer is wrong, your score decreases and one more question will be asked in the end along with the incorrectly answered question.<br>A maximum of 25 questions will be asked after which no more question will be added."),
0172                 qsTr("You should score above 90% to pass the assessment and become a Solar System expert!")
0173             ]
0174 
0175             intro: items.assessmentMode ? assessmentModeInstructions : learningModeInstructions
0176 
0177             onIntroChanged: index = 0
0178         }
0179 
0180         ListModel {
0181             id: planetsModel
0182         }
0183 
0184         readonly property int itemWidth: horizontalLayout ? background.width * 0.11 : (background.height - bar.height * 1.5) * 0.11
0185 
0186         // Arrangement of all the planets in the solar system
0187         GridView {
0188             id: planetView
0189             layoutDirection: Qt.LeftToRight
0190             verticalLayoutDirection: GridView.BottomToTop
0191             clip: false
0192             interactive: false
0193             visible: items.solarSystemVisible
0194             cellWidth: background.itemWidth
0195             cellHeight: cellWidth
0196             model: planetsModel
0197             keyNavigationWraps: true
0198             currentIndex: -1
0199             highlight: Rectangle {
0200                 scale: 1.2
0201                 color:  "#80FFFFFF"
0202                 visible: background.keyboardMode
0203                 radius: 10 * ApplicationInfo.ratio
0204                 Behavior on x { SpringAnimation { spring: 2; damping: 0.2 } }
0205                 Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } }
0206             }
0207 
0208             delegate: PlanetInSolarModel {
0209                 planetImageSource: realImg
0210                 planetName: bodyName
0211                 planetSize: bodySize
0212             }
0213         }
0214         states: [
0215             State {
0216                 name: "hGrid"
0217                 when: background.horizontalLayout
0218                 AnchorChanges {
0219                     target: planetView
0220                     anchors.horizontalCenter: background.horizontalCenter
0221                     anchors.verticalCenter: background.verticalCenter
0222                     anchors.top: undefined
0223                 }
0224                 PropertyChanges {
0225                     target: planetView
0226                     width: background.width
0227                     height: cellHeight
0228 
0229                 }
0230                 PropertyChanges {
0231                     target: stars
0232                     x: -stars.width * 0.48
0233                     y: -stars.height * 0.5 + background.height * 0.5
0234                 }
0235             },
0236             State {
0237                 name: "vGrid"
0238                 when: !background.horizontalLayout
0239                 AnchorChanges {
0240                     target: planetView
0241                     anchors.horizontalCenter: background.horizontalCenter
0242                     anchors.verticalCenter: undefined
0243                     anchors.top: background.top
0244                 }
0245                 PropertyChanges {
0246                     target: planetView
0247                     width: cellWidth
0248                     height: background.height - bar.height * 1.5
0249                 }
0250                 PropertyChanges {
0251                     target: stars
0252                     x: -stars.width * 0.5 + background.width * 0.5
0253                     y: -stars.height * 0.5 + background.height * 0.9
0254                 }
0255             }
0256         ]
0257 
0258         QuizScreen {
0259             id: mainQuizScreen
0260             visible: items.quizScreenVisible
0261         }
0262 
0263         Rectangle {
0264             id: solarSystemImageHint
0265             radius: 30
0266             border.width: 5
0267             border.color: "black"
0268             width: parent.width
0269             height: parent.height
0270             visible: false
0271             z: 2000
0272             parent: items.assessmentMode ? background : hintDialog
0273 
0274             onVisibleChanged: {
0275                 if(visible) {
0276                     hintCloseAnimation.stop()
0277                     hintAppearAnimation.start()
0278                 }
0279                 else {
0280                     solarSystemImageHint.x = 0
0281                     solarSystemImageHint.y = 0
0282                 }
0283             }
0284 
0285             Image {
0286                 id: solarSystemImage
0287                 fillMode: Image.PreserveAspectCrop
0288                 source: "qrc:/gcompris/src/activities/solar_system/resource/background.svg"
0289                 width: horizontalLayout ? parent.width * 2.5 : parent.height * 2.5
0290                 height: stars.width
0291                 sourceSize.width: stars.width
0292                 sourceSize.height: stars.width
0293                 x: horizontalLayout ? -stars.width * 0.48 : -stars.width * 0.5 + parent.width * 0.5
0294                 y: horizontalLayout ? -stars.height * 0.5 + parent.height * 0.5 : -stars.height * 0.5 + parent.height * 0.9
0295             }
0296 
0297             GridView {
0298                 id: planetViewHint
0299                 y: horizontalLayout ? (parent.height - bar.height) / 2 - cellHeight/2 : 0
0300                 x: horizontalLayout ? 0 : parent.width / 2 - cellHeight / 2
0301                 layoutDirection: Qt.LeftToRight
0302                 verticalLayoutDirection: GridView.BottomToTop
0303                 width: horizontalLayout ? parent.width : cellWidth
0304                 height: horizontalLayout ? cellHeight : parent.height - bar.height
0305                 clip: false
0306                 interactive: false
0307                 cellWidth: background.itemWidth
0308                 cellHeight: cellWidth
0309                 model: items.planetsModel
0310 
0311                 delegate: PlanetInSolarModel {
0312                     hintMode: true
0313                     planetImageSource: realImg
0314                     planetName: bodyName
0315                     planetSize: bodySize
0316                 }
0317             }
0318 
0319             NumberAnimation {
0320                 id: hintAppearAnimation
0321                 target: solarSystemImageHint
0322                 property: horizontalLayout ? "x" : "y"
0323                 from: horizontalLayout ? -width : -height
0324                 to: 0
0325                 duration: 1200
0326                 easing.type: Easing.OutBack
0327             }
0328 
0329             GCButtonCancel {
0330                 id: cancelButton
0331                 onClose: hintCloseAnimation.start()
0332             }
0333 
0334             SequentialAnimation {
0335                 id: hintCloseAnimation
0336 
0337                 NumberAnimation {
0338                     target: solarSystemImageHint
0339                     property: horizontalLayout ? "x" : "y"
0340                     to: horizontalLayout ? -width : -height
0341                     duration: 1200
0342                     easing.type: Easing.InSine
0343                 }
0344 
0345                 onStopped: solarSystemImageHint.visible = false
0346             }
0347         }
0348 
0349         // Hint dialog while playing the quiz
0350         DialogBackground {
0351             id: hintDialog
0352             visible: false
0353 
0354             readonly property string hint1: qsTr("1. The <b>farther</b> a planet from the Sun, the <b>lower</b> is its temperature.<br><font color=\"#3bb0de\">%1</font>").arg(items.temperatureHint)
0355             readonly property string hint2: qsTr("2. The duration of a year on a planet <b>increases as we go away from the Sun</b>.<br><font color=\"#3bb0de\">%1</font>").arg(items.lengthOfYearHint)
0356             //: find an equivalent rhyme in your language where the first letter of each word corresponds to the first letter of the planet in proper sequence
0357             //~ try to make the rhyme as simple as possible
0358             readonly property string hint3: qsTr("3. Always remember this rhyme to learn the position of planets, examine the first letter in each word - <b>M</b>y <b>V</b>ery <b>E</b>xcellent <b>M</b>other <b>J</b>ust <b>S</b>erved <b>U</b>s <b>N</b>oodles.<br>")
0359 
0360             title: qsTr("Hint")
0361             content: "%1<br>%2<br>%3".arg(hint1).arg(hint2).arg(hint3)
0362             onClose: {
0363                 solarSystemImageHint.visible = false
0364                 home()
0365                 activity.forceActiveFocus()
0366             }
0367 
0368             button0Text: qsTr("View the solar system")
0369 
0370             onButton0Hit: solarSystemImageHint.visible = true
0371         }
0372 
0373         DialogChooseLevel {
0374             id: dialogActivityConfig
0375             currentActivity: activity.activityInfo
0376             onClose: {
0377                 if(items.assessmentMode) {
0378                     Activity.startAssessmentMode()
0379                 }
0380                 else {
0381                     Activity.showSolarModel()
0382                 }
0383                 home();
0384             }
0385             onLoadData: {
0386                 if(activityData && activityData["mode"]) {
0387                     items.mode = activityData["mode"];
0388                 }
0389                 Activity.numberOfLevel = items.assessmentMode ? 1 : 2
0390             }
0391         }
0392 
0393         DialogHelp {
0394             id: dialogHelp
0395             onClose: home()
0396         }
0397 
0398         Bar {
0399             id: bar
0400             level: items.currentLevel + 1
0401             content: items.mainQuizScreen.restartAssessmentMessage.visible ? withConfigWithRestart :
0402                      items.solarSystemVisible ? withConfig :
0403                      items.assessmentMode ? withConfigWithHint :
0404                      Activity.indexOfSelectedPlanet == 0 ? withoutConfigWithoutHint :
0405                      items.hintProvided ? withoutConfigWithHint :
0406                      withoutConfigWithoutHint
0407 
0408             property BarEnumContent withConfig: BarEnumContent { value: help | home | activityConfig }
0409             property BarEnumContent withoutConfigWithHint: BarEnumContent { value: help | home | level | hint }
0410             property BarEnumContent withoutConfigWithoutHint: BarEnumContent { value: help | home | level }
0411             property BarEnumContent withConfigWithRestart: BarEnumContent { value: help | home | activityConfig | reload }
0412             property BarEnumContent withConfigWithHint: BarEnumContent { value: help | home | activityConfig | hint }
0413 
0414             onHelpClicked: {
0415                 displayDialog(dialogHelp)
0416             }
0417             onPreviousLevelClicked: Activity.previousLevel()
0418             onNextLevelClicked: Activity.nextLevel()
0419             onHomeClicked: {
0420                 mainQuizScreen.closenessMeter.stopAnimations();
0421                 if(items.solarSystemVisible || items.assessmentMode) {
0422                     home();
0423                 }
0424                 else
0425                     Activity.showSolarModel();
0426             }
0427             onHintClicked: {
0428                 if(items.assessmentMode)
0429                     solarSystemImageHint.visible = true
0430                 else
0431                     displayDialog(hintDialog)
0432             }
0433             onActivityConfigClicked: {
0434                 displayDialog(dialogActivityConfig)
0435             }
0436             onReloadClicked: Activity.startAssessmentMode()
0437         }
0438 
0439         Bonus {
0440             id: bonus
0441             Component.onCompleted: win.connect(Activity.nextLevel)
0442         }
0443     }
0444 }