Warning, /education/gcompris/src/activities/explore_farm_animals/ExploreLevels.qml is written in an unsupported language. File is not indexed.
0001 /* GCompris - ExploreLevels.qml
0002 *
0003 * SPDX-FileCopyrightText: 2015 Ayush Agrawal <ayushagrawal288@gmail.com>
0004 *
0005 * Authors:
0006 * Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
0007 * Ayush Agrawal <ayushagrawal288@gmail.com> (Qt Quick port)
0008 * Djalil MESLI <djalilmesli@gmail.com> (Qt Quick port)
0009 * Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
0010 *
0011 * SPDX-License-Identifier: GPL-3.0-or-later
0012 */
0013
0014 import QtQuick 2.12
0015 import GCompris 1.0
0016 import QtQuick.Controls 2.12
0017
0018 import "../../core"
0019 import "explore-level.js" as Activity
0020
0021 ActivityBase {
0022 id: activity
0023
0024 property int numberOfLevels
0025 property string url
0026 property bool hasAudioQuestions
0027 property bool needsVoices: false
0028
0029 onStart: focus = true
0030 onStop: {}
0031
0032 isMusicalActivity: needsVoices
0033
0034 pageComponent: Image {
0035 id: background
0036 source: "qrc:/gcompris/src/activities/chess/resource/background-wood.svg"
0037 width: parent.width
0038 height: parent.height
0039 sourceSize.width: width
0040 sourceSize.height: height
0041
0042 // if audio is disabled, we display a dialog to tell users this activity requires audio anyway
0043 property bool audioDisabled: false
0044
0045 /* In order to accept any screen ratio the play area is always a 1000x1000
0046 * square and is centered in a big background image that is 3000x3000
0047 */
0048
0049 Image {
0050 id: bg
0051 source: dataset.item.backgroundImage
0052 sourceSize.width: width
0053 sourceSize.height: width
0054 width: 3000 * background.playRatio
0055 height: width
0056 anchors.centerIn: parent
0057 }
0058
0059 property int playX: (activity.width - playWidth) / 2
0060 property int playY: (activity.height - playHeight) / 2
0061 property int playWidth: Math.min(activity.height - (bar.height * 2.2), activity.width)
0062 property int playHeight: playWidth
0063 property double playRatio: playWidth / 1000
0064
0065 focus: true
0066
0067 signal start
0068 signal stop
0069 signal voiceDone
0070
0071 Component.onCompleted: {
0072 activity.start.connect(start)
0073 activity.stop.connect(stop)
0074 }
0075
0076 // Add here the QML items you need to access in javascript
0077 QtObject {
0078 id: items
0079
0080 property GCAudio audioVoices: activity.audioVoices
0081 property GCSfx audioEffects: activity.audioEffects
0082 property Item main: activity.main
0083 property int currentLevel: activity.currentLevel
0084 property alias bonus: bonus
0085 property alias score: score
0086 property alias progressbar: progressbar
0087 property alias errorRectangle: errorRectangle
0088 property alias dataModel: dataModel
0089 property alias dataset: dataset
0090 property alias instruction: instruction
0091 property alias descriptionPanel: descriptionPanel
0092 property bool hasAudioQuestions: activity.hasAudioQuestions
0093 property var questionOrder
0094 property var currentQuestion: ""
0095 property alias okButton: okButton
0096 property bool bonusPlaying: false
0097 property bool buttonsBlocked: false
0098 property bool descriptionBonusDone: false
0099 }
0100
0101 Loader {
0102 id: dataset
0103 asynchronous: false
0104 onStatusChanged: {
0105 if (status == Loader.Ready) {
0106 // create table of size N filled with numbers from 0 to N
0107 items.questionOrder = Array.apply(null, {length: items.dataModel.count}).map(Number.call, Number)
0108 }
0109 }
0110 }
0111
0112 onStart: {
0113 activity.audioVoices.done.connect(voiceDone)
0114 activity.audioEffects.done.connect(voiceDone)
0115 Activity.start(items, url, numberOfLevels)
0116 if(activity.needsVoices === true) {
0117 if(!ApplicationSettings.isAudioVoicesEnabled || !ApplicationSettings.isAudioEffectsEnabled)
0118 background.audioDisabled = true
0119 }
0120 }
0121 onStop: { Activity.stop() }
0122
0123 Keys.onEscapePressed: {
0124 descriptionPanel.visible ? descriptionPanel.closeDescriptionPanel() : home()
0125 }
0126
0127 onVoiceDone: {
0128 if(items.bonusPlaying) {
0129 items.bonusPlaying = false;
0130 Activity.repeat();
0131 }
0132 }
0133
0134 Repeater {
0135 id: dataModel
0136 model: dataset && dataset.item && dataset.item.tab ? dataset.item.tab.length : 0
0137 AnimalLevels {
0138 questionId: index
0139 source: dataset.item.tab[index].image
0140 x: Math.round(background.playX + background.playWidth * dataset.item.tab[index].x - width / 2)
0141 y: Math.round(background.playY + background.playHeight * dataset.item.tab[index].y - height / 2)
0142 width: Math.round(background.playWidth * dataset.item.tab[index].width)
0143 height: Math.round(background.playHeight * dataset.item.tab[index].height)
0144 title: dataset.item.tab[index].title
0145 description: dataset.item.tab[index].text
0146 imageSource: dataset.item.tab[index].image2
0147 question: dataset.item.tab[index].text2
0148 audio: dataset.item.tab[index].audio !== undefined ? dataset.item.tab[index].audio : ""
0149 Component.onCompleted: {
0150 displayDescription.connect(displayDescriptionItem)
0151 }
0152 }
0153 }
0154
0155 function displayDescriptionItem(animal) {
0156 descriptionPanel.title = animal.title
0157 descriptionPanel.description = animal.description
0158 descriptionPanel.imageSource = animal.imageSource
0159 descriptionPanel.visible = true
0160 descriptionPanel.showDescriptionPanel()
0161 }
0162
0163 AnimalDescriptionLevels {
0164 id: descriptionPanel
0165 width: background.width
0166 height: background.height - bar.height * 1.2
0167 z: instruction.z + 1
0168 }
0169
0170 Column {
0171 id: progress
0172 visible: items.score.currentSubLevel != 1
0173 anchors.bottom: bar.top
0174 anchors.right: parent.right
0175 anchors.rightMargin: 10 * ApplicationInfo.ratio
0176 anchors.bottomMargin: progressbar.height
0177 Score {
0178 id: progressbar
0179 anchors {
0180 top: undefined
0181 bottom: undefined
0182 left: undefined
0183 right: undefined
0184 }
0185 onStop: Activity.nextSubSubLevel();
0186 }
0187 }
0188
0189 Image {
0190 id: okButton
0191 visible: false
0192 source:"qrc:/gcompris/src/core/resource/bar_ok.svg"
0193 sourceSize.width: questionText.height * 2
0194 fillMode: Image.PreserveAspectFit
0195 anchors.right: progress.right
0196 anchors.verticalCenter: progress.verticalCenter
0197 anchors.margins: 10 * ApplicationInfo.ratio
0198 MouseArea {
0199 anchors.fill: parent
0200 onClicked: Activity.nextLevel()
0201 }
0202 }
0203
0204 Row {
0205 id: row
0206 spacing: 10 * ApplicationInfo.ratio
0207 anchors.fill: parent
0208 anchors.margins: 10 * ApplicationInfo.ratio
0209 layoutDirection: leftCol.width === 0 ? Qt.RightToLeft : Qt.LeftToRight
0210 Column {
0211 id: leftCol
0212 spacing: 10 * ApplicationInfo.ratio
0213
0214 Rectangle {
0215 id: instruction
0216 width: row.width - rightCol.width - 10 * ApplicationInfo.ratio
0217 height: instructionText.height
0218 color: "#CCCCCCCC"
0219 radius: 10
0220 border.width: 3
0221 border.color: "black"
0222
0223 GCText {
0224 id: instructionText
0225 horizontalAlignment: Text.AlignHCenter
0226 verticalAlignment: Text.AlignVCenter
0227 anchors.centerIn: parent.Center
0228 color: "black"
0229 width: parent.width
0230 wrapMode: Text.Wrap
0231 text: (dataset.item && items.score.currentSubLevel - 1 != items.score.numberOfSubLevels && items.score.currentSubLevel != 0) ? dataset.item.instructions[items.score.currentSubLevel - 1].text : ""
0232 }
0233 MouseArea {
0234 anchors.fill: parent
0235 onClicked: instruction.visible = false
0236 enabled: instruction.visible
0237 }
0238 }
0239
0240 Rectangle {
0241 id: question
0242 width: row.width - rightCol.width - 10 * ApplicationInfo.ratio
0243 height: questionText.height
0244 color: '#CCCCCCCC'
0245 radius: 10
0246 border.width: 3
0247 border.color: "black"
0248 visible: items.score.currentSubLevel == 3 || (items.score.currentSubLevel == 2 && !items.hasAudioQuestions)
0249 GCText {
0250 id: questionText
0251 horizontalAlignment: Text.AlignHCenter
0252 verticalAlignment: Text.AlignVCenter
0253 anchors.centerIn: parent.Center
0254 color: "black"
0255 width: parent.width
0256 wrapMode: Text.Wrap
0257 text: items.currentQuestion ? items.currentQuestion.text2 : ""
0258 }
0259 }
0260 }
0261
0262 Column {
0263 id: rightCol
0264 spacing: 10 * ApplicationInfo.ratio
0265
0266 Score {
0267 id: score
0268 isScoreCounter: false
0269 anchors {
0270 bottom: undefined
0271 right: undefined
0272 }
0273 }
0274
0275 BarButton {
0276 id: repeatItem
0277 source: "qrc:/gcompris/src/core/resource/bar_repeat.svg";
0278 sourceSize.width: 60 * ApplicationInfo.ratio
0279 anchors.right: parent.right
0280 visible: items.score.currentSubLevel == 2 && activity.hasAudioQuestions //&& ApplicationSettings.isAudioVoicesEnabled
0281 onClicked: {
0282 if(!items.audioVoices.isPlaying()) {
0283 Activity.repeat();
0284 }
0285 }
0286 }
0287 }
0288 }
0289
0290 ErrorRectangle {
0291 id: errorRectangle
0292 anchors.centerIn: parent
0293 width: 0
0294 height: 0
0295 imageSize: 60 * ApplicationInfo.ratio
0296 function releaseControls() {
0297 items.buttonsBlocked = false;
0298 }
0299 }
0300
0301
0302 DialogHelp {
0303 id: dialogHelp
0304 onClose: home()
0305 }
0306
0307 Bar {
0308 id: bar
0309 level: items.currentLevel + 1
0310 content: BarEnumContent { value: help | home | level | reload }
0311 onHelpClicked: {
0312 displayDialog(dialogHelp)
0313 }
0314 onPreviousLevelClicked: Activity.previousLevel()
0315 onNextLevelClicked: Activity.nextLevel()
0316 onHomeClicked: activity.home()
0317 onReloadClicked: Activity.initLevel()
0318 }
0319 Bonus {
0320 id: bonus
0321 onWin: {
0322 if(progressbar.visible)
0323 Activity.nextLevel();
0324 else {
0325 okButton.visible = true;
0326 items.buttonsBlocked = false;
0327 }
0328 }
0329 }
0330
0331 Loader {
0332 id: audioNeededDialog
0333 sourceComponent: GCDialog {
0334 parent: activity
0335 isDestructible: false
0336 message: qsTr("This activity requires sound, so it will play some sounds even if the audio voices or effects are disabled in the main configuration.")
0337 button1Text: qsTr("Quit")
0338 button2Text: qsTr("Continue")
0339 onButton1Hit: activity.home();
0340 onClose: {
0341 background.audioDisabled = false;
0342 }
0343 }
0344 anchors.fill: parent
0345 focus: true
0346 active: background.audioDisabled
0347 onStatusChanged: if (status == Loader.Ready) item.start()
0348 }
0349 }
0350 }