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 }