Warning, /education/gcompris/src/activities/colors/FindIt.qml is written in an unsupported language. File is not indexed.
0001 /* GCompris - FindIt.qml 0002 * 0003 * SPDX-FileCopyrightText: 2015 Bruno Coudoin <bruno.coudoin@gcompris.net> 0004 * 0005 * Authors: 0006 * Pascal Georges <pascal.georges1@free.fr> (GTK+ version) 0007 * Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port) 0008 * Timothée Giet <animtim@gmail.com> (refactoring and various improvements) 0009 * 0010 * SPDX-License-Identifier: GPL-3.0-or-later 0011 */ 0012 0013 import QtQuick 2.12 0014 import QtGraphicalEffects 1.0 0015 import GCompris 1.0 0016 0017 import "../../core" 0018 import "findit.js" as Activity 0019 import "qrc:/gcompris/src/core/core.js" as Core 0020 0021 ActivityBase { 0022 id: activity 0023 focus: true 0024 0025 property var dataset 0026 property string backgroundImg 0027 0028 property string mode: "" 0029 0030 onStart: { 0031 focus = true; 0032 } 0033 0034 pageComponent: Image { 0035 id: background 0036 focus: true 0037 fillMode: Image.PreserveAspectCrop 0038 sourceSize.width: width 0039 sourceSize.height: height 0040 source: backgroundImg 0041 0042 property bool keyboardMode: false 0043 // if audio is disabled, we display a dialog to tell users this activity requires audio anyway 0044 property bool audioDisabled: false 0045 0046 signal start 0047 signal stop 0048 0049 Component.onCompleted: { 0050 activity.start.connect(start) 0051 activity.stop.connect(stop) 0052 } 0053 QtObject { 0054 id: items 0055 property Item activityPage: activity 0056 property alias background: background 0057 property int currentLevel: activity.currentLevel 0058 property alias bonus: bonus 0059 property alias containerModel: containerModel 0060 property alias initAnim: initAnim 0061 property alias nextAnim: nextAnim 0062 property alias fadeOutAnim: fadeOutAnim 0063 // On startup we want to queue the first sound but not after 0064 property bool firstQuestion: true 0065 property bool audioOk: false 0066 property alias score: score 0067 property bool objectSelected: true 0068 // we need to know the number of objects to calculate itemWidth before populating the container 0069 property int objectCount: 1 0070 // we need to copy tempModel to containerModel only once and only after all the rest is initialized 0071 property bool modelCopied: false 0072 } 0073 onStart: { 0074 if((!ApplicationSettings.isAudioVoicesEnabled || !ApplicationSettings.isAudioEffectsEnabled) && activity.isMusicalActivity) { 0075 background.audioDisabled = true; 0076 } else { 0077 Activity.start(items, dataset, mode); 0078 } 0079 } 0080 onStop: Activity.stop() 0081 0082 Keys.onPressed: { 0083 if(event.key === Qt.Key_Space) { 0084 container.currentItem.select() 0085 } 0086 } 0087 Keys.onReleased: { 0088 keyboardMode = true 0089 event.accepted = false 0090 } 0091 Keys.onEnterPressed: container.currentItem.select(); 0092 Keys.onReturnPressed: container.currentItem.select(); 0093 Keys.onRightPressed: container.moveCurrentIndexRight(); 0094 Keys.onLeftPressed: container.moveCurrentIndexLeft(); 0095 Keys.onDownPressed: container.moveCurrentIndexDown(); 0096 Keys.onUpPressed: container.moveCurrentIndexUp(); 0097 Keys.onTabPressed: if(repeatItem.visible) repeatItem.clicked(); 0098 0099 ListModel { 0100 id: containerModel 0101 } 0102 0103 Rectangle { 0104 id: questionItem 0105 anchors.top: parent.top 0106 anchors.topMargin: 5 * ApplicationInfo.ratio 0107 anchors.horizontalCenter: parent.horizontalCenter 0108 width: questionText.contentWidth + 20 * ApplicationInfo.ratio 0109 height: Math.max(10 * ApplicationInfo.ratio, questionText.contentHeight + 5 * ApplicationInfo.ratio) 0110 radius: 5 * ApplicationInfo.ratio 0111 color: "#E2E2E2" 0112 border.color: "#373737" 0113 border.width: 2 * ApplicationInfo.ratio 0114 opacity: 0.01 0115 0116 function initQuestion() { 0117 questionText.text = Activity.getCurrentTextQuestion() 0118 if(Activity.getCurrentAudioQuestion()) { 0119 if(items.firstQuestion) 0120 items.audioOk = activity.audioVoices.append(Activity.getCurrentAudioQuestion()) 0121 else { 0122 activity.audioVoices.clearQueue() 0123 items.audioOk = activity.audioVoices.play(Activity.getCurrentAudioQuestion()) 0124 } 0125 items.firstQuestion = false 0126 } 0127 } 0128 0129 // initialization sequence for first question of first level 0130 SequentialAnimation { 0131 id: initAnim 0132 ScriptAction { script: questionItem.initQuestion() } 0133 PauseAnimation { duration: 50 } 0134 ScriptAction { script: if(!items.modelCopied) 0135 Activity.tempModelToContainer() 0136 } 0137 NumberAnimation { target: questionItem; property: "opacity"; to: 1; duration: 300 } 0138 } 0139 0140 // fade-out anim only before bonus start 0141 NumberAnimation { id: fadeOutAnim; target: questionItem; property: "opacity"; to: 0.01; duration: 300 } 0142 0143 // fade-out + init sequence after first question of a level 0144 SequentialAnimation { 0145 id: nextAnim 0146 NumberAnimation { target: questionItem; property: "opacity"; to: 0.01; duration: 300 } 0147 ScriptAction { script: initAnim.restart() } 0148 } 0149 0150 GCText { 0151 id: questionText 0152 anchors.centerIn: parent 0153 fontSize: largeSize 0154 width: background.width * 0.9 0155 horizontalAlignment: Text.AlignHCenter 0156 wrapMode: Text.WordWrap 0157 font.weight: Font.DemiBold 0158 color: "#373737" 0159 } 0160 } 0161 0162 GridView { 0163 id: container 0164 model: containerModel 0165 anchors.top: questionItem.bottom 0166 anchors.topMargin: 10 * ApplicationInfo.ratio 0167 anchors.bottom: score.top 0168 anchors.horizontalCenter: background.horizontalCenter 0169 width: background.width - score.width * 2 0170 interactive: false 0171 cellWidth: itemWidth 0172 cellHeight: itemWidth 0173 keyNavigationWraps: true 0174 0175 property int itemWidth: Core.fitItems(container.width, container.height, items.objectCount) 0176 0177 delegate: ColorItem { 0178 audioVoices: activity.audioVoices 0179 source: model.image 0180 audioSrc: model.audio ? model.audio : "" 0181 question: model.text 0182 sourceSize.height: container.itemWidth * 0.9 0183 sourceSize.width: container.itemWidth * 0.9 0184 } 0185 add: Transition { 0186 PathAnimation { 0187 path: Path { 0188 PathCurve { x: background.width / 3} 0189 PathCurve { y: background.height / 3} 0190 PathCurve {} 0191 } 0192 easing.type: Easing.InOutQuad 0193 duration: 2000 0194 } 0195 } 0196 highlight: Rectangle { 0197 width: container.cellWidth 0198 height: container.cellHeight 0199 color: "#AAFFFFFF" 0200 border.width: 3 0201 border.color: "black" 0202 visible: background.keyboardMode 0203 Behavior on x { SpringAnimation { spring: 2; damping: 0.2 } } 0204 Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } } 0205 } 0206 } 0207 0208 DialogHelp { 0209 id: dialogHelp 0210 onClose: home() 0211 } 0212 0213 Bar { 0214 id: bar 0215 level: items.currentLevel + 1 0216 content: BarEnumContent { value: help | home | level } 0217 onHelpClicked: { 0218 displayDialog(dialogHelp) 0219 } 0220 onPreviousLevelClicked: Activity.previousLevel() 0221 onNextLevelClicked: Activity.nextLevel() 0222 onHomeClicked: activity.home() 0223 } 0224 0225 BarButton { 0226 id: repeatItem 0227 source: "qrc:/gcompris/src/core/resource/bar_repeat.svg"; 0228 sourceSize.height: visible ? 80 * ApplicationInfo.ratio : 1 0229 z: bar.z + 1 0230 visible: items.audioOk 0231 anchors { 0232 bottom: bar.top 0233 right: parent.right 0234 margins: 10 * ApplicationInfo.ratio 0235 } 0236 onClicked: if (!activity.audioVoices.isPlaying()) 0237 questionItem.initQuestion() 0238 } 0239 0240 Score { 0241 id: score 0242 anchors.bottom: bar.top 0243 anchors.right: bar.right 0244 anchors.left: parent.left 0245 anchors.bottomMargin: 10 * ApplicationInfo.ratio 0246 anchors.leftMargin: 10 * ApplicationInfo.ratio 0247 anchors.rightMargin: 0 0248 } 0249 0250 Bonus { 0251 id: bonus 0252 interval: 2000 0253 Component.onCompleted: win.connect(Activity.nextLevel) 0254 } 0255 0256 Loader { 0257 id: audioNeededDialog 0258 sourceComponent: GCDialog { 0259 parent: activity 0260 isDestructible: false 0261 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.") 0262 button1Text: qsTr("Quit") 0263 button2Text: qsTr("Continue") 0264 onButton1Hit: activity.home(); 0265 onClose: { 0266 background.audioDisabled = false; 0267 Activity.start(items, dataset, mode); 0268 } 0269 } 0270 anchors.fill: parent 0271 focus: true 0272 active: background.audioDisabled 0273 onStatusChanged: if (status == Loader.Ready) item.start() 0274 } 0275 } 0276 0277 }