File indexing completed on 2024-05-05 15:53:02

0001 /* GCompris - click_on_letter.js
0002  *
0003  * SPDX-FileCopyrightText: 2014 Holger Kaelberer
0004  * 
0005  * Authors:
0006  *   Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
0007  *   Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ Mostly full rewrite)
0008  *   Holger Kaelberer <holger.k@elberer.de> (Qt Quick port)
0009  *
0010  *   SPDX-License-Identifier: GPL-3.0-or-later
0011  */
0012 
0013 .pragma library
0014 .import QtQuick 2.12 as Quick
0015 .import GCompris 1.0 as GCompris //for ApplicationInfo
0016 .import "qrc:/gcompris/src/core/core.js" as Core
0017 
0018 var url = "qrc:/gcompris/src/activities/click_on_letter/resource/"
0019 var defaultLevelsFile = ":/gcompris/src/activities/click_on_letter/resource/levels-en.json";
0020 var maxLettersPerLine = 6;
0021 
0022 var levels;
0023 var numberOfLevel;
0024 var currentLetter;
0025 var level;
0026 var questions;
0027 var answers;
0028 var items;
0029 var mode;
0030 
0031 function start(_items, _mode)
0032 {
0033     Core.checkForVoices(_items.activityPage);
0034 
0035     items = _items;
0036     mode = _mode;
0037 
0038     // register the voices for the locale
0039     var locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale)
0040     GCompris.DownloadManager.updateResource(GCompris.GCompris.VOICES, {"locale": locale})
0041 
0042     loadLevels();
0043     items.score.currentSubLevel = 0;
0044     numberOfLevel = levels.length;
0045     items.currentLevel = Core.getInitialLevel(numberOfLevel);
0046     initLevel();
0047 }
0048 
0049 function validateLevels(levels)
0050 {
0051     var i;
0052     for (i = 0; i < levels.length; i++) {
0053         if (undefined === levels[i].questions
0054             || typeof levels[i].questions != "string"
0055             || levels[i].questions.length < 1
0056             || typeof levels[i].answers != "string"
0057             || levels[i].answers.length < 1)
0058             return false;
0059     }
0060     if (i < 1)
0061         return false;
0062     return true;
0063 }
0064 
0065 function loadLevels()
0066 {
0067     var ret;
0068     var locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale)
0069     var filename = GCompris.ApplicationInfo.getLocaleFilePath(url + "levels-" + locale + ".json");
0070     levels = items.parser.parseFromUrl(filename);
0071     if (levels == null) {
0072         console.warn("Click_on_letter: Invalid levels file " + filename);
0073         // fallback to default Latin (levels-en.json) file:
0074         levels = items.parser.parseFromUrl(defaultLevelsFile);
0075         if (levels == null) {
0076             console.error("Click_on_letter: Invalid default levels file "
0077                 + defaultLevelsFile + ". Can't continue!");
0078             // any way to error-exit here?
0079             return;
0080         }
0081     }
0082     // at this point we have valid levels
0083     for (var i = 0; i < levels.length; i++) {
0084         if (mode === "lowercase") {
0085             levels[i].questions = levels[i].questions.toLocaleLowerCase();
0086             levels[i].answers = levels[i].answers.toLocaleLowerCase();
0087         } else {
0088             levels[i].questions = levels[i].questions.toLocaleUpperCase();
0089             levels[i].answers = levels[i].answers.toLocaleUpperCase();
0090         }
0091     }
0092 }
0093 
0094 function stop()
0095 {
0096 }
0097 
0098 function shuffleString(s)
0099 {
0100     var a = s.split("|");
0101     var n = a.length;
0102 
0103     for(var i = n-1; i>0; i--) {
0104         var j = Math.floor(Math.random() * (i + 1));
0105         var tmp = a[i];
0106         a[i] = a[j];
0107         a[j] = tmp;
0108     }
0109     return a.join("|");
0110 }
0111 
0112 function initLevel() {
0113     items.errorRectangle.resetState();
0114     if (items.score.currentSubLevel == 0) {
0115         level = levels[items.currentLevel];
0116         items.score.numberOfSubLevels = level.questions.split("|").length;
0117         questions = shuffleString(level.questions);
0118         answers = shuffleString(level.answers);
0119 
0120         var answerArr = answers.split("|");
0121         items.trainModel.clear();
0122         for (var i = 0; i < answerArr.length; i++) {                
0123             items.trainModel.append({
0124                 "letter": answerArr[i],
0125             });
0126         }
0127     }
0128 
0129     var locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale);
0130     currentLetter = questions.split("|")[items.score.currentSubLevel];
0131     if (GCompris.ApplicationSettings.isAudioVoicesEnabled &&
0132             GCompris.DownloadManager.haveLocalResource(
0133                 GCompris.DownloadManager.getVoicesResourceForLocale(locale))) {
0134         items.audioVoices.append(GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/"+locale+"/misc/click_on_letter.$CA"))
0135         items.audioVoices.silence(100)
0136         playLetter(currentLetter)
0137         items.questionItem.visible = false
0138         items.repeatItem.visible = true
0139     } else {
0140         // no sound -> show question
0141         items.questionItem.visible = true;
0142         items.repeatItem.visible = false
0143     }
0144     // Maybe we will display it if sound fails
0145     items.questionItem.text = currentLetter;
0146 
0147     items.buttonsBlocked = false;
0148 }
0149 
0150 function playLetter(letter) {
0151     var locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale)
0152     items.audioVoices.append(GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/"+locale+"/alphabet/"
0153                                                                        + Core.getSoundFilenamForChar(letter)))
0154 }
0155 
0156 function nextLevel() {
0157     items.score.stopWinAnimation();
0158     items.audioVoices.clearQueue();
0159     items.currentLevel = Core.getNextLevel(items.currentLevel, numberOfLevel);
0160     items.score.currentSubLevel = 0;
0161     initLevel();
0162 }
0163 
0164 function previousLevel() {
0165     items.score.stopWinAnimation();
0166     items.audioVoices.clearQueue();
0167     items.currentLevel = Core.getPreviousLevel(items.currentLevel, numberOfLevel);
0168     items.score.currentSubLevel = 0;
0169     initLevel();
0170 }
0171 
0172 function nextSubLevel() {
0173     items.audioVoices.clearQueue()
0174     if(items.score.currentSubLevel >= items.score.numberOfSubLevels) {
0175         items.bonus.good("flower")
0176     } else {
0177         initLevel();
0178     }
0179 }
0180 
0181 function checkAnswer(index) {
0182     var modelEntry = items.trainModel.get(index);
0183     if (modelEntry.letter === currentLetter) {
0184         items.score.currentSubLevel++;
0185         items.score.playWinAnimation();
0186         items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/completetask.wav");
0187         return true
0188     } else {
0189         return false
0190     }
0191 }
0192 
0193 function focusEventHandler() {
0194     if (items && items.eventHandler)
0195         items.eventHandler.forceActiveFocus();
0196 }