Warning, /education/gcompris/src/activities/solar_system/QuizScreen.qml is written in an unsupported language. File is not indexed.
0001 /* GCompris - QuizScreen.qml 0002 * 0003 * SPDX-FileCopyrightText: 2018 Aman Kumar Gupta <gupta2140@gmail.com> 0004 * 0005 * Authors: 0006 * Aman Kumar Gupta <gupta2140@gmail.com> 0007 * 0008 * SPDX-License-Identifier: GPL-3.0-or-later 0009 */ 0010 import QtQuick 2.12 0011 import GCompris 1.0 0012 import QtGraphicalEffects 1.0 0013 import QtQuick.Controls 2.12 0014 0015 import "../../core" 0016 import "solar_system.js" as Activity 0017 0018 Item { 0019 id: mainQuizScreen 0020 width: parent.width 0021 height: parent.height 0022 0023 property alias score: score 0024 property alias optionListModel: optionListModel 0025 property alias optionListView: optionListView 0026 property alias restartAssessmentMessage: restartAssessmentMessage 0027 property alias blockAnswerButtons: optionListView.blockAnswerButtons 0028 property alias closenessMeter: closenessMeter 0029 property string planetRealImage 0030 property string question 0031 property string closenessMeterValue 0032 property int numberOfCorrectAnswers: 0 0033 0034 Rectangle { 0035 id: questionArea 0036 anchors.right: score.left 0037 anchors.top: parent.top 0038 anchors.left: parent.left 0039 anchors.margins: 10 * ApplicationInfo.ratio 0040 height: questionText.height + 10 * ApplicationInfo.ratio 0041 color: 'white' 0042 radius: 10 0043 border.width: 3 0044 opacity: 0.8 0045 border.color: "black" 0046 GCText { 0047 id: questionText 0048 horizontalAlignment: Text.AlignHCenter 0049 verticalAlignment: Text.AlignVCenter 0050 anchors.centerIn: parent.Center 0051 color: "black" 0052 width: parent.width 0053 wrapMode: Text.Wrap 0054 text: mainQuizScreen.question 0055 } 0056 } 0057 0058 // Model of options for a question 0059 ListModel { 0060 id: optionListModel 0061 } 0062 0063 // This grid has image of the planet in its first column/row (row in case of vertical screen) and the options on the 2nd column/row 0064 Grid { 0065 id: imageAndOptionGrid 0066 columns: (background.horizontalLayout && !items.assessmentMode && items.currentLevel != 1) ? 2 : 1 0067 spacing: 10 * ApplicationInfo.ratio 0068 anchors.top: (questionArea.y + questionArea.height) > (score.y + score.height) ? questionArea.bottom : score.bottom 0069 anchors.left: parent.left 0070 anchors.right: parent.right 0071 0072 // An item to hold image of the planet 0073 Item { 0074 width: background.horizontalLayout ? background.width * 0.40 0075 : background.width - imageAndOptionGrid.anchors.margins * 2 0076 height: background.horizontalLayout ? background.height - bar.height - questionArea.height - 10 * ApplicationInfo.ratio 0077 : (background.height - bar.height - questionArea.height - 10 * ApplicationInfo.ratio) * 0.37 0078 0079 visible: !items.assessmentMode && (items.currentLevel != 1) 0080 0081 Image { 0082 id: planetImageMain 0083 sourceSize.width: Math.min(parent.width, parent.height) * 0.9 0084 anchors.centerIn: parent 0085 source: mainQuizScreen.planetRealImage 0086 fillMode: Image.PreserveAspectCrop 0087 } 0088 } 0089 0090 // An item to hold the list view of options 0091 Item { 0092 width: ( items.assessmentMode || items.currentLevel == 1 ) ? mainQuizScreen.width 0093 : background.horizontalLayout ? background.width * 0.55 0094 : background.width - imageAndOptionGrid.anchors.margins * 2 0095 height: background.horizontalLayout ? itemHeightHorizontal 0096 : itemHeightVertical 0097 0098 readonly property real itemHeightHorizontal: background.height - bar.height - closenessMeter.height - questionArea.height - 10 * ApplicationInfo.ratio 0099 readonly property real itemHeightVertical: (items.bcurrentLevel != 1 && !items.assessmentMode) ? itemHeightHorizontal * 0.39 0100 : itemHeightHorizontal * 0.8 0101 0102 ListView { 0103 id: optionListView 0104 anchors.verticalCenter: parent.verticalCenter 0105 anchors.horizontalCenter: parent.horizontalCenter 0106 width: background.horizontalLayout ? background.width * 0.40 0107 : background.width - imageAndOptionGrid.anchors.margins * 2 0108 height: background.horizontalLayout ? background.height - bar.height - closenessMeter.height * 1.5 - questionArea.height - 50 * ApplicationInfo.ratio 0109 : parent.itemHeightVertical 0110 spacing: background.horizontalLayout ? 10 * ApplicationInfo.ratio : 7.5 * ApplicationInfo.ratio 0111 orientation: Qt.Vertical 0112 verticalLayoutDirection: ListView.TopToBottom 0113 interactive: false 0114 model: optionListModel 0115 currentIndex: -1 0116 0117 readonly property real buttonHeight: (height - 3 * spacing) / 4 0118 0119 add: Transition { 0120 NumberAnimation { properties: "y"; from: parent.y; duration: 500 } 0121 onRunningChanged: { 0122 optionListView.blockAnswerButtons = running 0123 } 0124 } 0125 0126 property bool blockAnswerButtons: false 0127 0128 highlight: Rectangle { 0129 scale: 1.2 0130 color: "#2881C3" 0131 visible: background.keyboardMode 0132 radius: 10 * ApplicationInfo.ratio 0133 Behavior on x { SpringAnimation { spring: 2; damping: 0.2 } } 0134 Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } } 0135 } 0136 0137 delegate: AnswerButton { 0138 id: optionButton 0139 width: optionListView.width 0140 height: optionListView.buttonHeight 0141 textLabel: optionValue 0142 blockAllButtonClicks: optionListView.blockAnswerButtons 0143 audioEffects: activity.audioEffects 0144 0145 isCorrectAnswer: closeness === 100 0146 0147 onPressed: optionListView.blockAnswerButtons = true 0148 onIncorrectlyPressed: { 0149 if(!items.assessmentMode) { 0150 closenessMeter.stopAnimations() 0151 closenessMeterIncorrectAnswerAnimation.start() 0152 mainQuizScreen.closenessMeterValue = closeness 0153 } 0154 else { 0155 optionListView.blockAnswerButtons = false 0156 Activity.appendAndAddQuestion() 0157 } 0158 } 0159 onCorrectlyPressed: { 0160 if(!items.assessmentMode) { 0161 closenessMeter.stopAnimations() 0162 Activity.currentSubLevel++ 0163 score.currentSubLevel = Activity.currentSubLevel 0164 score.playWinAnimation() 0165 particles.burst(30) 0166 closenessMeterCorrectAnswerAnimation.start() 0167 mainQuizScreen.closenessMeterValue = closeness 0168 } 0169 else { 0170 Activity.assessmentModeQuestions.shift() 0171 mainQuizScreen.numberOfCorrectAnswers++ 0172 Activity.nextSubLevel(true) 0173 } 0174 } 0175 } 0176 } 0177 } 0178 } 0179 0180 Rectangle { 0181 id: closenessMeter 0182 x: ((background.width - items.bar.barZoom * items.bar.fullButton * 5.6) < (width + 10 * ApplicationInfo.ratio) && background.horizontalLayout) ? background.width - width - 42 * ApplicationInfo.ratio : background.width - width - 10 * ApplicationInfo.ratio 0183 y: (background.width - items.bar.barZoom * items.bar.fullButton * 5.6) < (width + 10 * ApplicationInfo.ratio) ? background.height - bar.height - height - 10 * ApplicationInfo.ratio : background.height - height - 10 * ApplicationInfo.ratio 0184 height: 40 * ApplicationInfo.ratio 0185 width: 150 * ApplicationInfo.ratio 0186 radius: width * 0.06 0187 border.width: 2 0188 border.color: "black" 0189 opacity: 0.78 0190 visible: !items.assessmentMode 0191 Item { 0192 width: parent.width - 3 * ApplicationInfo.ratio 0193 height: parent.height 0194 anchors.centerIn: parent 0195 0196 GCText { 0197 id: closenessText 0198 color: "black" 0199 anchors.fill: parent 0200 fontSizeMode: Text.Fit 0201 horizontalAlignment: Text.AlignHCenter 0202 verticalAlignment: Text.AlignVCenter 0203 text: qsTr("Accuracy: %1%").arg(closenessMeterValue) 0204 } 0205 } 0206 0207 SequentialAnimation { 0208 id: closenessMeterIncorrectAnswerAnimation 0209 onStarted: optionListView.blockAnswerButtons = true 0210 NumberAnimation { target: closenessMeter; property: "scale"; to: 1.1; duration: 450 } 0211 NumberAnimation { target: closenessMeter; property: "scale"; to: 1.0; duration: 450 } 0212 onStopped: optionListView.blockAnswerButtons = false 0213 } 0214 0215 SequentialAnimation { 0216 id: closenessMeterCorrectAnswerAnimation 0217 onStarted: optionListView.blockAnswerButtons = true 0218 NumberAnimation { target: closenessMeter; property: "scale"; to: 1.1; duration: 450 } 0219 NumberAnimation { target: closenessMeter; property: "scale"; to: 1.0; duration: 450 } 0220 NumberAnimation { target: closenessMeter; property: "scale"; to: 1.1; duration: 450 } 0221 NumberAnimation { target: closenessMeter; property: "scale"; to: 1.0; duration: 450 } 0222 ScriptAction { script: { Activity.nextSubLevel() } } 0223 } 0224 0225 ParticleSystemStarLoader { 0226 id: particles 0227 clip: false 0228 } 0229 0230 function stopAnimations() { 0231 optionListView.blockAnswerButtons = false 0232 closenessMeterCorrectAnswerAnimation.stop() 0233 closenessMeterIncorrectAnswerAnimation.stop() 0234 } 0235 } 0236 0237 GCProgressBar { 0238 id: progressBar 0239 height: bar.height * 0.35 0240 width: parent.width * 0.35 0241 0242 readonly property real percentage: (mainQuizScreen.numberOfCorrectAnswers / score.numberOfSubLevels) * 100 0243 message: qsTr("%1%").arg(value) 0244 0245 value: Math.round(percentage * 10) / 10 0246 to: 100 0247 0248 visible: items.assessmentMode 0249 y: parent.height - bar.height - height - 10 * ApplicationInfo.ratio 0250 x: parent.width - width * 1.1 0251 0252 Rectangle { 0253 z: -1 0254 radius: 5 * ApplicationInfo.ratio 0255 anchors.centerIn: parent 0256 height: progressBar.height * 1.25 0257 width: parent.width 0258 color: "#80EEEEEE" 0259 } 0260 } 0261 0262 Rectangle { 0263 id: restartAssessmentMessage 0264 width: parent.width 0265 height: parent.height - bar.height * 1.25 0266 anchors.top: parent.top 0267 anchors.margins: 10 * ApplicationInfo.ratio 0268 anchors.horizontalCenter: parent.horizontalCenter 0269 radius: 4 * ApplicationInfo.ratio 0270 visible: items.assessmentMode && items.restartAssessmentMessage 0271 z: 4 0272 GCText { 0273 anchors.fill: parent 0274 horizontalAlignment: Text.AlignHCenter 0275 verticalAlignment: Text.AlignVCenter 0276 wrapMode: Text.WordWrap 0277 fontSizeMode: mediumSize 0278 text: qsTr("Your final score is: <font color=\"#3bb0de\">%1%</font>.<br><br>%2").arg(progressBar.value).arg(progressBar.value <= 90 ? qsTr("You should score above 90% to become a Solar System expert!<br>Retry to test your skills again or train in normal mode to learn more about the Solar System.") : qsTr("Great! You can replay the assessment to test your knowledge on more questions.")) 0279 } 0280 0281 // To prevent clicking on options under it 0282 MouseArea { 0283 anchors.fill: parent 0284 } 0285 0286 onVisibleChanged: scaleAnimation.start() 0287 0288 NumberAnimation { 0289 id: scaleAnimation 0290 target: restartAssessmentMessage 0291 properties: "scale" 0292 from: 0 0293 to: 1 0294 duration: 1500 0295 easing.type: Easing.OutBounce 0296 } 0297 } 0298 0299 Score { 0300 id: score 0301 anchors.bottom: undefined 0302 anchors.right: parent.right 0303 anchors.rightMargin: 10 * ApplicationInfo.ratio 0304 anchors.top: parent.top 0305 z: 0 0306 isScoreCounter: items.assessmentMode ? false : true 0307 } 0308 }