File indexing completed on 2024-04-21 14:43:30
0001 /* GCompris - categorization.js 0002 * 0003 * SPDX-FileCopyrightText: 2016 Divyam Madaan <divyam3897@gmail.com> 0004 * 0005 * Authors: 0006 * Divyam Madaan <divyam3897@gmail.com> 0007 * 0008 * SPDX-License-Identifier: GPL-3.0-or-later 0009 */ 0010 .pragma library 0011 .import QtQuick 2.12 as Quick 0012 .import GCompris 1.0 as GCompris 0013 .import "qrc:/gcompris/src/core/core.js" as Core 0014 0015 var categoryModelIndex = 0; 0016 var currentSubLevel = 0; 0017 var items 0018 var lessons 0019 var categories 0020 var images 0021 var numberOfLevel 0022 var index 0023 var imagesData = [] 0024 var categoriesData = [] 0025 var expertCategories = [] 0026 var answerTable = {} 0027 var totalImages 0028 var fileName = ":/gcompris/data/words-webp/animals/camel.webp" 0029 0030 function init(items_) { 0031 items = items_ 0032 items.menuModel.clear() 0033 currentSubLevel = 0 0034 } 0035 0036 function start() { 0037 categoriesData = [] 0038 items.categoryReview.stop() 0039 0040 var isEmbeddedMode = items.file.exists(fileName) ? true : false 0041 0042 items.categoriesFallback = !isEmbeddedMode 0043 0044 var categoriesFilename; 0045 var categoryDataset = items.categoryReview.categoryDataset 0046 var categoryLists = items.categories 0047 for(var i = 0; i < categoryLists.length; i++) { 0048 categoriesFilename = categoryLists[i][0] 0049 categoryDataset.source = categoriesFilename 0050 if(isEmbeddedMode || categoryDataset.item.isEmbedded) { 0051 categoriesData.push(categoryDataset.item) 0052 } 0053 } 0054 lessons = getAllLessons(categoriesData) 0055 categories = getCategoryModel(categoriesData) 0056 addPropertiesToCategories(categories) 0057 items.menuModel.append(categories) 0058 savedPropertiesToCategories(items.dialogActivityConfig.activityData) 0059 sortByFavorites() 0060 items.menuScreen.start() 0061 } 0062 0063 // Inserts specific properties to the categories 0064 function addPropertiesToCategories(categories) { 0065 for (var i = 0; i < categories.length; i++) { 0066 categories[i]['name'] = categories[i].name 0067 categories[i]['image'] = categories[i].image 0068 categories[i]['favorite'] = false 0069 categories[i]['categoryIndex'] = i 0070 } 0071 } 0072 0073 // Return all the properties we have to save 0074 function categoriesToSavedProperties() { 0075 if(!items) 0076 return; 0077 var props = {} 0078 for(var i = 0; i < items.menuModel.count; i++) { 0079 var category = items.menuModel.get(i) 0080 props[category.name] = { 0081 'favorite': category['favorite'] 0082 } 0083 } 0084 return props 0085 } 0086 0087 // Update the categories based on a previous saving 0088 function savedPropertiesToCategories(dataToSave) { 0089 var props = dataToSave["data"] 0090 for(var i = 0; i < items.menuModel.count; i++) { 0091 var category = items.menuModel.get(i) 0092 var categoryname = category.name 0093 if(props && props[category.name]) { 0094 category['favorite'] = props[category.name].favorite 0095 } 0096 else { 0097 category['favorite'] = false 0098 } 0099 } 0100 } 0101 0102 function sortByFavorites() { 0103 for(var i = 0; i < items.menuModel.count; i++) { 0104 if(items.menuModel.get(i)['favorite']) { 0105 items.menuModel.move(i, 0, 1); 0106 } 0107 } 0108 } 0109 0110 function launchMenuScreen() { 0111 items.categoryReview.stop() 0112 items.menuScreen.start() 0113 } 0114 0115 function startCategory() { 0116 items.categoryReview.start() 0117 items.menuScreen.stop() 0118 items.currentLevel = 0 0119 initLevel() 0120 } 0121 0122 function storeCategoriesLevels(index_) { 0123 index = index_ 0124 items.currentLevel = 0 0125 numberOfLevel = 0 0126 initLevel() 0127 } 0128 0129 function initLevel() { 0130 items.categoryReview.score.currentSubLevel = 0 0131 items.instructionsVisible = true 0132 getCategoryLevels(index); 0133 numberOfLevel = items.details.length; 0134 items.categoryReview.leftZone.clear(); 0135 items.categoryReview.rightZone.clear(); 0136 items.categoryReview.start(); 0137 items.menuScreen.stop() 0138 } 0139 0140 function nextLevel() { 0141 items.currentLevel = Core.getNextLevel(items.currentLevel, numberOfLevel); 0142 items.categoryReview.score.currentSubLevel = 0 0143 initLevel(index); 0144 getCategoryLevels(); 0145 } 0146 0147 function previousLevel() { 0148 items.currentLevel = Core.getPreviousLevel(items.currentLevel, numberOfLevel); 0149 initLevel(index); 0150 getCategoryLevels(); 0151 } 0152 0153 // Checks if all the items are dragged and dropped in the correct or incorrect area. 0154 function allPlaced() { 0155 items.categoryReview.score.currentSubLevel = 0; 0156 for(var i = 0 ; i < items.categoryReview.leftZone.count; ++i) { 0157 for(var answer in answerTable) { 0158 var droppedZoneItem = items.categoryReview.leftZone.get(i) 0159 if(answer === droppedZoneItem.name && 0160 ((droppedZoneItem.droppedZone === "right" && answerTable[answer]) 0161 || (droppedZoneItem.droppedZone === "left" && !answerTable[answer]))) 0162 items.categoryReview.score.currentSubLevel ++ 0163 } 0164 } 0165 for(var i = 0 ; i < items.categoryReview.rightZone.count; ++i) { 0166 for(var answer in answerTable) { 0167 var droppedZoneItem = items.categoryReview.rightZone.get(i) 0168 if(answer === droppedZoneItem.name && 0169 ((droppedZoneItem.droppedZone === "right" && answerTable[answer]) 0170 || (droppedZoneItem.droppedZone === "left" && !answerTable[answer]))) 0171 items.categoryReview.score.currentSubLevel ++ 0172 } 0173 } 0174 if(items.categoryReview.score.currentSubLevel === totalImages) 0175 items.bonus.good("flower") 0176 else 0177 items.bonus.bad("flower", items.bonus.checkAnswer) 0178 } 0179 0180 // Save properties to lessons 0181 function getCategoryLevels() { 0182 var randomGood = 0; 0183 var randomBad = 0; 0184 items.categoryReview.middleZone.clear() 0185 /* If easy or medium mode is selected, store the details of levels of category of that respective index in items.details. */ 0186 if(items.mode !== "expert") { 0187 items.details = lessons[index].map(function(ele) { 0188 return { "instructions": ele.instructions, "image": ele.image, 0189 "numberOfGood": ele.maxNumberOfGood, "numberofBad": ele.maxNumberOfBad, 0190 "categoryImages": ele.levelImages ,"good": ele.good, 0191 "bad": ele.bad ,"prefix": ele.prefix } 0192 }); 0193 } 0194 // If expert mode is selected, select a random level (selectedLevel) from a random category (selectedCategory) 0195 else if(items.mode === "expert") { 0196 var selectedCategory = Math.floor(Math.random() * expertCategories.length) 0197 var selectedLevel = [] 0198 selectedLevel[0] = expertCategories[selectedCategory][Math.floor(Math.random() * expertCategories[selectedCategory].length)] 0199 items.details = selectedLevel.map(function(ele) { 0200 return { "instructions": ele.instructions, "image": ele.image, 0201 "numberOfGood": ele.maxNumberOfGood, "numberofBad": ele.maxNumberOfBad, 0202 "categoryImages": ele.levelImages ,"good": ele.good, 0203 "bad": ele.bad, "prefix": ele.prefix } 0204 }); 0205 } 0206 0207 var imagesPrefix = items.details[items.currentLevel].prefix 0208 // Good set of images 0209 var goodImages = items.details[items.currentLevel].good 0210 var numberOfGood = Math.min(goodImages.length,items.details[items.currentLevel].numberOfGood); 0211 var goodZoneImages = goodImages.map(function(obj) { 0212 obj = imagesPrefix + obj 0213 return { "name": obj, "isRight": true } 0214 }); 0215 goodZoneImages = goodZoneImages.splice(0, numberOfGood); 0216 0217 // Bad set of images 0218 var badImages = items.details[items.currentLevel].bad 0219 var badZoneImages = badImages.map(function(obj) { 0220 obj = imagesPrefix + obj 0221 return { "name": obj, "isRight": false } 0222 }); 0223 var numberOfBad = Math.min(badImages.length,items.details[items.currentLevel].numberofBad); 0224 badZoneImages = badZoneImages.splice(0, numberOfBad); 0225 0226 // Concat both set of images(good and bad) in allImages and store in middleZone model 0227 var allImages = goodZoneImages.concat(badZoneImages); 0228 Core.shuffle(allImages); 0229 for(var i = 0; i < allImages.length; i++) { 0230 answerTable[allImages[i].name] = allImages[i].isRight 0231 items.categoryReview.middleZone.append({"isRight": allImages[i].isRight,"name": allImages[i].name}) 0232 } 0233 totalImages = allImages.length 0234 items.categoryReview.score.numberOfSubLevels = totalImages 0235 } 0236 0237 // get categories details from the complete dataset 0238 function getCategoryModel(dataset) { 0239 var categories = [] 0240 for (var c = 0; c < dataset.length; c++) { 0241 categories.push({ 0242 'name': dataset[c].levels[0].name, 0243 'image': dataset[c].levels[0].image, 0244 'index': c 0245 }) 0246 } 0247 return categories 0248 } 0249 0250 // get all the content (levels) from the category in dataset 0251 function getAllLessons(dataset) { 0252 var lessons = [] 0253 for(var c = 0; c < dataset.length; c++) { 0254 lessons.push(dataset[c].levels[0].content) 0255 if(dataset[c].allowExpertMode) { 0256 expertCategories.push(dataset[c].levels[0].content) 0257 } 0258 } 0259 return lessons 0260 } 0261 0262 function setValues() { 0263 items.categoryReview.leftAreaContainsDrag = false 0264 items.categoryReview.rightAreaContainsDrag = false 0265 } 0266 0267 function isDragInLeftArea(leftAreaRightBorderPos, elementRightPos) { 0268 if(elementRightPos <= leftAreaRightBorderPos) 0269 return true; 0270 else 0271 return false; 0272 } 0273 function isDragInRightArea(rightAreaLeftBorderPos, elementLeftPos) { 0274 if((rightAreaLeftBorderPos <= elementLeftPos)) 0275 return true; 0276 else 0277 return false; 0278 } 0279 0280 function dropControl(sourcePosition, destinationPosition, image, index) { 0281 var destinationZone = destinationPosition === "left" ? items.categoryReview.leftZone : destinationPosition === "right" ? items.categoryReview.rightZone : items.categoryReview.middleZone 0282 var sourceZone = sourcePosition === "left" ? items.categoryReview.leftZone : sourcePosition === "right" ? items.categoryReview.rightZone : items.categoryReview.middleZone 0283 destinationZone.append({"name": image, "droppedZone": destinationPosition}) 0284 sourceZone.remove(index) 0285 }