Warning, /education/gcompris/src/core/ActivityBase.qml is written in an unsupported language. File is not indexed.
0001 /* GCompris - ActivityBase.qml 0002 * 0003 * SPDX-FileCopyrightText: 2014 Bruno Coudoin <bruno.coudoin@gcompris.net> 0004 * 0005 * Authors: 0006 * Bruno Coudoin <bruno.coudoin@gcompris.net> 0007 * 0008 * SPDX-License-Identifier: GPL-3.0-or-later 0009 */ 0010 import QtQuick 2.12 0011 import GCompris 1.0 0012 import "qrc:/gcompris/src/core/core.js" as Core 0013 0014 /** 0015 * The base QML component for activities in GCompris. 0016 * @ingroup components 0017 * 0018 * Each activity should be derived from this component. It is responsible for 0019 * 0020 * * Activity common key handling, 0021 * * unified audio handling, 0022 * * screen switching dynamics (from/to Menu/DialogHelp/etc.) 0023 * 0024 * The following common keys are handled so far: 0025 * 0026 * * @c Ctrl+w: Exit the current activity and return to the menu, 0027 * or close the application if on the menu page. 0028 * * @c Back: Same as above. 0029 * * @c Escape: Same as above. 0030 * 0031 * Cf. Template.qml for a sample skeleton activity. 0032 * 0033 * Cf. 0034 * [the wiki](https://gcompris.net/wiki/Qt_Quick_development_process#Adding_a_new_activity) 0035 * for further information about creating a new activity. 0036 * 0037 * @inherit QtQuick.Item 0038 */ 0039 Item { 0040 id: page 0041 0042 /** 0043 * type:Item 0044 * Parent object. 0045 */ 0046 property Item main: parent 0047 0048 /** 0049 * type:Component 0050 * The top-level component containing the visible viewport of an activity. 0051 * 0052 * Put all you want to present the user into this container. Mostly 0053 * implemented using a Rectangle or Image component, itself 0054 * containing further graphical elements. You are pretty free of doing 0055 * whatever you want inside this component. 0056 * 0057 * Also common elements as Bar, Score, DialogHelp, etc. should be placed 0058 * inside this element. 0059 */ 0060 property Component pageComponent 0061 0062 /** 0063 * type:QtObject 0064 * Reference to the menu activity. 0065 * 0066 * Populated automatically during activity-loading. 0067 */ 0068 property QtObject menu 0069 0070 /** 0071 * type:QtObject 0072 * Reference to the ActivityInfo object of the activity. 0073 * 0074 * Populated automatically during activity-loading. 0075 */ 0076 property QtObject activityInfo 0077 0078 /** 0079 * type:GCAudio 0080 * The global audio item for voices. 0081 * 0082 * Because of problems synchronizing multiple Audio objects between 0083 * global/menu/main and individual activities, activities should refrain 0084 * from implementing additional Audio elements. 0085 * 0086 * Instead append to this global object to play your voices after the 0087 * intro music. 0088 * @sa GCAudio audioVoices 0089 */ 0090 property GCAudio audioVoices 0091 0092 /** 0093 * type:GCSfx 0094 * The global audio item for audio effects. 0095 * 0096 * Use it to play your effects. 0097 * @sa GCSfx audioEffects 0098 */ 0099 property GCSfx audioEffects 0100 0101 /** 0102 * type:GCAudio 0103 * The global audio item for background music. 0104 * 0105 * @sa GCAudio backgroundMusic 0106 */ 0107 property GCAudio backgroundMusic 0108 0109 /** 0110 * type:string 0111 * The resource folder for the current activity. The resources 0112 * of each activity needs to be stored with the same pattern. 0113 * "qrc:/gcompris/src/activities/" + activity name + "/resource/" 0114 * 0115 */ 0116 property string resourceUrl: (activityInfo && activityInfo.name) ? "qrc:/gcompris/src/activities/" + activityInfo.name.split('/')[0] + "/resource/": "" 0117 0118 /** 0119 * type: bool 0120 * It tells whether the activity is a musical activity or not(if the activity contains it's own audio effects). 0121 * 0122 * If the activity is a musical activity, on starting it the background music pauses and when the activity is quit, background music resumes. 0123 * 0124 * Set it as true if the activity is musical. 0125 */ 0126 property bool isMusicalActivity: false 0127 0128 /** 0129 * type:int 0130 * The current level for this activity. 0131 */ 0132 property int currentLevel: 0 0133 0134 property alias datasetLoader: datasetLoader 0135 property var levelFolder 0136 0137 /** 0138 * type:Loading 0139 * The global loading object. 0140 * 0141 * Start it to signal heavy computation in case of GUI freezes. 0142 * @sa Loading 0143 */ 0144 property Loading loading 0145 0146 /** 0147 * type: bool 0148 * Check if the activity is the menu or not. 0149 * Set by default to false for all activities, 0150 * and only set to true inside Menu.qml 0151 */ 0152 property bool isMenu: false 0153 0154 /** 0155 * Emitted when the user wants to return to the Home/Menu screen. 0156 */ 0157 signal home 0158 0159 /** 0160 * Emitted when the user wants to return several views back in the 0161 * page stack. 0162 */ 0163 signal back(Item to) 0164 0165 /** 0166 * Emitted every time the activity has been started. 0167 * 0168 * Initialize your activity upon this signal. 0169 */ 0170 signal start 0171 0172 /** 0173 * Emitted when the activity is about to stop 0174 * 0175 * Shutdown whatever you need to upon this signal. 0176 */ 0177 signal stop 0178 0179 /** 0180 * Connected to stop signal 0181 * Used to stop all the voices and sounds from the activity 0182 */ 0183 signal stopSounds 0184 0185 /** 0186 * Emitted when dialog @p dialog should be shown 0187 * 0188 * Emit this signal when you want to show another dialog, e.g. on 0189 * Bar.onHelpClicked 0190 * 0191 * @param dialog Dialog to show. 0192 */ 0193 signal displayDialog(Item dialog) 0194 0195 /** 0196 * Emitted when multiple @p dialogs should be pushed on the page-stack 0197 * 0198 * Emit this signal when you want to stack >1 views. The last one will be 0199 * shown the intermediated ones will be kept on the page stack for later 0200 * pop() calls. 0201 * 0202 * @param dialogs Array of dialogs to push; 0203 */ 0204 signal displayDialogs(var dialogs) 0205 0206 //Initially hide it to avoid components appearing on the menu while the activity is loading. 0207 visible: false 0208 0209 Component.onCompleted: { 0210 page.stop.connect(stopSounds); 0211 } 0212 onStopSounds: { 0213 if(!isMenu) { 0214 audioEffects.stop(); 0215 audioVoices.clearQueue(); 0216 audioVoices.stop(); 0217 } 0218 } 0219 0220 onBack: menu ? menu.back(to) : "" 0221 onHome: menu ? menu.home() : "" 0222 onDisplayDialog: menu ? menu.displayDialog(dialog) : "" 0223 onDisplayDialogs: menu ? menu.displayDialogs(dialogs) : "" 0224 0225 Keys.forwardTo: activity.children 0226 Keys.onEscapePressed: home(); 0227 Keys.onPressed: { 0228 if (event.modifiers === Qt.ControlModifier && event.key === Qt.Key_W) { 0229 // Ctrl+W exit the current activity 0230 home(); 0231 } 0232 } 0233 Keys.onReleased: { 0234 if (event.key === Qt.Key_Back) { 0235 event.accepted = true; 0236 home(); 0237 } 0238 } 0239 0240 Loader { 0241 id: activity 0242 sourceComponent: pageComponent 0243 anchors.fill: parent 0244 } 0245 0246 onLevelFolderChanged: { 0247 if(levelFolder === undefined || levelFolder.length === 0) { 0248 return 0249 } 0250 0251 datasetLoader.data = [] 0252 var data = []; 0253 // sorting levelFolders in numeric manner 0254 levelFolder.sort(function(a, b) { return (parseInt(a) - parseInt(b)) }); 0255 for(var level in levelFolder /*todo maybe we don't need anymore levelFolder and we can use activityInfo.currentLevels*/) { 0256 var id = levelFolder[level]; 0257 var dataset = activityInfo.getDataset(id); 0258 if(dataset) { 0259 data = data.concat(dataset.data); 0260 } 0261 } 0262 datasetLoader.data = data 0263 //datasetLoader.start() 0264 } 0265 0266 // todo Maybe not needed anymore 0267 Loader { 0268 id: datasetLoader 0269 asynchronous: false 0270 0271 property var dataFiles: [] 0272 property var currentFile 0273 property var data: [] 0274 signal start 0275 signal stop 0276 0277 onStart: { 0278 var file = dataFiles.shift() 0279 currentFile = file 0280 source = file.file.toString() 0281 } 0282 0283 onLoaded: { 0284 data = data.concat(item.data) 0285 0286 if(dataFiles.length != 0) { 0287 start() 0288 } 0289 else { 0290 stop() 0291 } 0292 } 0293 onStop: { 0294 //print("stop", JSON.stringify(data)) 0295 source = "" 0296 // Core.shuffle(data) do we want to shuffle??? Should depend on the activity (if we want increasing levels) or teachers (random multiplication tables for example) 0297 } 0298 } 0299 }