diff --git a/src/activities/enumerate/ActivityInfo.qml b/src/activities/enumerate/ActivityInfo.qml --- a/src/activities/enumerate/ActivityInfo.qml +++ b/src/activities/enumerate/ActivityInfo.qml @@ -37,4 +37,5 @@ credit: "" section: "math numeration" createdInVersion: 0 + levels: "1,2,3,4" } diff --git a/src/activities/enumerate/AnswerArea.qml b/src/activities/enumerate/AnswerArea.qml --- a/src/activities/enumerate/AnswerArea.qml +++ b/src/activities/enumerate/AnswerArea.qml @@ -37,8 +37,6 @@ } property string imgPath - // The backspace code coming from the virtual keyboard - property string backspaceCode // True when the value is entered correctly property bool valid: false @@ -78,7 +76,10 @@ MouseArea { id: mouseArea anchors.fill: parent - onClicked: Activity.registerAnswerItem(answerBackground) + onClicked: { + Activity.registerAnswerItem(answerBackground) + Activity.resetAnswerAreaColor(); + } } Image { @@ -95,45 +96,21 @@ } Keys.onPressed: { - if(event.key === Qt.Key_Backspace) { - backspace() - } appendText(event.text) } - function backspace() { - userEntry.text = userEntry.text.slice(0, -1) - if(userEntry.text.length === 0) { - userEntry.text = "?" - valid = Activity.setUserAnswer(imgPath, -1) - return - } else { - valid = Activity.setUserAnswer(imgPath, parseInt(userEntry.text)) - return - } - } - function appendText(text) { - if(text === answerBackground.backspaceCode) { - backspace() - return - } - var number = parseInt(text) if(isNaN(number)) return if(userEntry.text === "?") { userEntry.text = "" } - if(userEntry.text.length >= 2) { - valid = false - return - } - - userEntry.text += text - valid = Activity.setUserAnswer(imgPath, parseInt(userEntry.text)) + userEntry.text = text + Activity.resetAnswerAreaColor(); + Activity.setUserAnswer(imgPath, parseInt(userEntry.text)) } GCText { diff --git a/src/activities/enumerate/Enumerate.qml b/src/activities/enumerate/Enumerate.qml --- a/src/activities/enumerate/Enumerate.qml +++ b/src/activities/enumerate/Enumerate.qml @@ -43,12 +43,57 @@ sourceSize.width: Math.max(parent.width, parent.height) Component.onCompleted: { + dialogActivityConfig.initialize() activity.start.connect(start) activity.stop.connect(stop) } onStart: { Activity.start(items); keyboard.populate(); } onStop: { Activity.stop() } + //instruction rectangle + Rectangle { + id: instruction + anchors { + top: parent.top + topMargin: 5 + horizontalCenter: parent.horizontalCenter + } + height: instructionTxt.contentHeight * 1.1 + width: Math.max(Math.min(parent.width * 0.8, instructionTxt.text.length * 10), parent.width * 0.3) + opacity: 0.8 + visible: items.levels + radius: 10 + border.width: 2 + z: instruction.opacity === 0 ? -10 : 10 + border.color: "#DDD" + color: "#373737" + + Behavior on opacity { PropertyAnimation { duration: 200 } } + + //shows/hides the Instruction + MouseArea { + anchors.fill: parent + onClicked: instruction.opacity = instruction.opacity == 0 ? 0.8 : 0 + } + + GCText { + id: instructionTxt + anchors { + top: parent.top + topMargin: 5 + horizontalCenter: parent.horizontalCenter + } + opacity: instruction.opacity + z: instruction.z + fontSize: smallSize + color: "white" + text: items.instructionText + horizontalAlignment: Text.AlignHCenter + width: parent.width * 0.8 + wrapMode: TextEdit.WordWrap + } + } + Keys.onDownPressed: { if(++answerColumn.currentIndex >= answerColumn.count) answerColumn.currentIndex = 0 @@ -65,8 +110,12 @@ property alias background: background property alias bar: bar property alias bonus: bonus - property alias answerColumnModel: answerColumn.model + property alias okButton: okButton + property alias answerColumn: answerColumn property alias itemListModel: itemList.model + property string instructionText: "" + property alias score: score + property var levels: activity.datasetLoader.data.length !== 0 ? activity.datasetLoader.data : null } DropArea { @@ -101,7 +150,6 @@ AnswerArea { imgPath: modelData focus: true - backspaceCode: keyboard.backspace audioEffects: activity.audioEffects } } @@ -147,35 +195,88 @@ { label: "6" }, { label: "7" }, { label: "8" }, - { label: "9" }, - { label: keyboard.backspace } + { label: "9" } ] ] } onKeypress: Activity.currentAnswerItem.appendText(text) onError: console.log("VirtualKeyboard error: " + msg); } + + DialogChooseLevel { + id: dialogActivityConfig + currentActivity: activity.activityInfo + onSaveData: { + levelFolder = dialogActivityConfig.chosenLevels + currentActivity.currentLevels = dialogActivityConfig.chosenLevels + ApplicationSettings.setCurrentLevels(currentActivity.name, dialogActivityConfig.chosenLevels) + activity.focus = true + background.stop() + background.start() + } + onLoadData: { + if(activityData) { + Activity.initLevel() + } + } + onClose: { + home() + } + onStartActivity: { + background.start() + } + } + + Score { + id: score + anchors.top: okButton.bottom + anchors.bottom: keyboard.top + anchors.rightMargin: 10 * ApplicationInfo.ratio + } + DialogHelp { id: dialogHelp onClose: home() } Bar { id: bar anchors.bottom: keyboard.top - content: BarEnumContent { value: help | home | level } + content: BarEnumContent { value: help | home | level | activityConfig } onHelpClicked: { displayDialog(dialogHelp) } onPreviousLevelClicked: Activity.previousLevel() onNextLevelClicked: Activity.nextLevel() onHomeClicked: activity.home() + onActivityConfigClicked: { + displayDialog(dialogActivityConfig) + } } + BarButton { + id: okButton + anchors { + bottom: bar.top + right: parent.right + rightMargin: 9 * ApplicationInfo.ratio + bottomMargin: 9 * ApplicationInfo.ratio + } + source: "qrc:/gcompris/src/core/resource/bar_ok.svg" + sourceSize.width: 80 * ApplicationInfo.ratio + onClicked: Activity.checkAnswers(); + } + + Keys.onReturnPressed: okButton.enabled === true ? Activity.checkAnswers() : "" + Keys.onEnterPressed: okButton.enabled === true ? Activity.checkAnswers() : "" + Bonus { id: bonus + onStop: { + okButton.enabled = true; + } Component.onCompleted: win.connect(Activity.nextLevel) } } diff --git a/src/activities/enumerate/enumerate.js b/src/activities/enumerate/enumerate.js --- a/src/activities/enumerate/enumerate.js +++ b/src/activities/enumerate/enumerate.js @@ -26,8 +26,13 @@ var url = "qrc:/gcompris/src/activities/enumerate/resource/" var url2 = "qrc:/gcompris/src/activities/algorithm/resource/" var items -var currentLevel = 0 -var numberOfLevel = 9 +var maxSubLevel +var dataset +var currentLevel +var currentSubLevel +var numberOfLevel +var numberOfItemType +var numberOfItemMax var itemIcons = [ url2 + "apple.svg", url2 + "banana.svg", @@ -61,69 +66,18 @@ } function initLevel() { + if(items.levels) + items.instructionText = items.levels[currentLevel].objective items.bar.level = currentLevel + 1 + dataset = items.levels + numberOfLevel = dataset.length + currentSubLevel = 0 cleanUp() - - var numberOfItemType - var numberOfItemMax - - switch(currentLevel) - { - case 0: - numberOfItemType = 1; - numberOfItemMax = 5; - break; - case 1: - numberOfItemType = 2; - numberOfItemMax = 5; - break; - case 2: - numberOfItemType = 3; - numberOfItemMax = 4; - break; - case 3: - numberOfItemType = 3; - numberOfItemMax = 5; - break; - case 4: - numberOfItemType = 4; - numberOfItemMax = 5; - break; - case 5: - numberOfItemType = 4; - numberOfItemMax = 6; - break; - case 6: - numberOfItemType = 5; - numberOfItemMax = 5; - break; - case 7: - numberOfItemType = 4; - numberOfItemMax = 6; - break; - case 8: - numberOfItemType = 3; - numberOfItemMax = 8; - break; - default: - numberOfItemType = 2; - numberOfItemMax = 9; - } - - itemIcons = Core.shuffle(itemIcons) - var enumItems = new Array() - var types = new Array() - - for(var type = 0; type < numberOfItemType; type++) { - var nbItems = getRandomInt(1, numberOfItemMax) - for(var j = 0; j < nbItems; j++) { - enumItems.push(itemIcons[type]) - } - answerToFind[itemIcons[type]] = nbItems - types.push(itemIcons[type]) - } - items.answerColumnModel = types - items.itemListModel = enumItems + numberOfItemType = dataset[currentLevel].numberOfItemType + numberOfItemMax = dataset[currentLevel].numberOfItemMax + maxSubLevel = dataset[currentLevel].sublevels + items.score.numberOfSubLevels = maxSubLevel; + initSubLevel(); } function nextLevel() { @@ -147,17 +101,28 @@ function setUserAnswer(imgPath, userValue) { userAnswers[imgPath] = userValue - checkAnswers() - return userAnswers[imgPath] === answerToFind[imgPath] } function checkAnswers() { + var i = 0 for (var key in answerToFind) { if(userAnswers[key] !== answerToFind[key]) { - return; - } + items.answerColumn.itemAt(i).color = "red"; + items.okButton.enabled = false; + }else + items.answerColumn.itemAt(i).color = "green"; + i++ } - items.bonus.good("smiley") + + if(items.okButton.enabled) + nextSubLevel() + else + items.bonus.bad("smiley") +} + +function resetAnswerAreaColor() { + for(var i = 0; i < numberOfItemType; i++ ) + items.answerColumn.itemAt(i).color = items.answerColumn.itemAt(i).activeFocus == 1 ? "#ff07fff2" : "#cccccccc"; } function getRandomInt(min, max) { @@ -170,3 +135,32 @@ currentAnswerItem = item item.forceActiveFocus() } + +function initSubLevel() { + itemIcons = Core.shuffle(itemIcons) + items.score.currentSubLevel = currentSubLevel + 1; + var enumItems = new Array() + var types = new Array() + for(var type = 0; type < numberOfItemType; type++) { + var nbItems = getRandomInt(1, numberOfItemMax) + for(var j = 0; j < nbItems; j++) { + enumItems.push(itemIcons[type]) + } + answerToFind[itemIcons[type]] = nbItems + types.push(itemIcons[type]) + } + items.answerColumn.model = types + items.itemListModel = enumItems +} + +function nextSubLevel() { + if( ++currentSubLevel >= maxSubLevel) { + items.okButton.enabled = false; + items.bonus.good("smiley") + currentSubLevel = 0; + } else { + items.score.playWinAnimation(); + cleanUp(); + initSubLevel(); + } +} diff --git a/src/activities/enumerate/resource/1/Data.qml b/src/activities/enumerate/resource/1/Data.qml new file mode 100644 --- /dev/null +++ b/src/activities/enumerate/resource/1/Data.qml @@ -0,0 +1,52 @@ +/* GCompris - Data.qml + * + * Copyright (C) 2020 Shubham Mishra + * + * Authors: + * Shubham Mishra + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ +import "../../../../core" + +Dataset { + objective: qsTr("Enumerate up to 4 fruits") + difficulty: 1 + data: [ + { + "objective": qsTr("Enumerate 1 fruit"), + "sublevels" : "2", + "numberOfItemType" : 1, + "numberOfItemMax" : 1 + }, + { + "objective": qsTr("Enumerate up to 2 fruits"), + "sublevels" : "3", + "numberOfItemType" : 1, + "numberOfItemMax" : 2 + }, + { + "objective": qsTr("Enumerate up to 3 fruits"), + "sublevels" : "4", + "numberOfItemType" : 1, + "numberOfItemMax" : 3 + }, + { + "objective": qsTr("Enumerate up to 4 fruits"), + "sublevels" : "4", + "numberOfItemType" : 1, + "numberOfItemMax" : 4 + } + ] +} diff --git a/src/activities/enumerate/resource/2/Data.qml b/src/activities/enumerate/resource/2/Data.qml new file mode 100644 --- /dev/null +++ b/src/activities/enumerate/resource/2/Data.qml @@ -0,0 +1,64 @@ +/* GCompris - Data.qml + * + * Copyright (C) 2020 Shubham Mishra + * + * Authors: + * Shubham Mishra + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ +import "../../../../core" + +Dataset { + objective: qsTr("Group 2 types of fruits and Enumerate each group (6 fruits max)") + difficulty: 2 + data: [ + { + "objective": qsTr("Enumerate up to 4 fruits"), + "sublevels" : "4", + "numberOfItemType" : 1, + "numberOfItemMax" : 4 + }, + { + "objective": qsTr("Group 2 types of fruits and enumerate each group (4 fruits max)"), + "sublevels" : "4", + "numberOfItemType" : 2, + "numberOfItemMax" : 4 + }, + { + "objective": qsTr("Enumerate up to 5 fruits"), + "sublevels" : "5", + "numberOfItemType" : 1, + "numberOfItemMax" : 5 + }, + { + "objective": qsTr("Group 2 types of fruits and enumerate each group (5 fruits max)"), + "sublevels" : "5", + "numberOfItemType" : 2, + "numberOfItemMax" : 5 + }, + { + "objective": qsTr("Enumerate up to 6 fruits"), + "sublevels" : "6", + "numberOfItemType" : 1, + "numberOfItemMax" : 6 + }, + { + "objective": qsTr("Group 2 types of fruits and enumerate each group (6 fruits max)"), + "sublevels" : "6", + "numberOfItemType" : 2, + "numberOfItemMax" : 6 + } + ] +} diff --git a/src/activities/enumerate/resource/3/Data.qml b/src/activities/enumerate/resource/3/Data.qml new file mode 100644 --- /dev/null +++ b/src/activities/enumerate/resource/3/Data.qml @@ -0,0 +1,64 @@ +/* GCompris - Data.qml + * + * Copyright (C) 2020 Shubham Mishra + * + * Authors: + * Shubham Mishra + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ +import "../../../../core" + +Dataset { + objective: qsTr("Group 3 types of fruits and enumerate each group (6 fruits max)") + difficulty: 2 + data: [ + { + "objective": qsTr("Group 2 types of fruits and enumerate each group (4 fruits max)"), + "sublevels" : "4", + "numberOfItemType" : 2, + "numberOfItemMax" : 4 + }, + { + "objective": qsTr("Group 3 types of fruits and enumerate each group (4 fruits max)"), + "sublevels" : "4", + "numberOfItemType" : 3, + "numberOfItemMax" : 4 + }, + { + "objective": qsTr("Group 2 types of fruits and enumerate each group (5 fruits max)"), + "sublevels" : "5", + "numberOfItemType" : 2, + "numberOfItemMax" : 5 + }, + { + "objective": qsTr("Group 3 types of fruits and enumerate each group (5 fruits max)"), + "sublevels" : "5", + "numberOfItemType" : 3, + "numberOfItemMax" : 5 + }, + { + "objective": qsTr("Group 2 types of fruits and enumerate each group (6 fruits max)"), + "sublevels" : "6", + "numberOfItemType" : 2, + "numberOfItemMax" : 6 + }, + { + "objective": qsTr("Group 3 types of fruits and enumerate each group (6 fruits max)"), + "sublevels" : "6", + "numberOfItemType" : 3, + "numberOfItemMax" : 6 + } + ] +} diff --git a/src/activities/enumerate/resource/4/Data.qml b/src/activities/enumerate/resource/4/Data.qml new file mode 100644 --- /dev/null +++ b/src/activities/enumerate/resource/4/Data.qml @@ -0,0 +1,100 @@ +/* GCompris - Data.qml + * + * Copyright (C) 2020 Shubham Mishra + * + * Authors: + * Shubham Mishra + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ +import "../../../../core" + +Dataset { + objective: qsTr("Group 4 types of fruits and enumerate each group (9 fruits max)") + difficulty: 3 + data: [ + { + "objective": qsTr("Group 3 types of fruits and enumerate each group (4 fruits max)"), + "sublevels" : "4", + "numberOfItemType" : 3, + "numberOfItemMax" : 4 + }, + { + "objective": qsTr("Group 4 types of fruits and enumerate each group (4 fruits max)"), + "sublevels" : "4", + "numberOfItemType" : 4, + "numberOfItemMax" : 4 + }, + { + "objective": qsTr("Group 3 types of fruits and enumerate each group (5 fruits max)"), + "sublevels" : "5", + "numberOfItemType" : 3, + "numberOfItemMax" : 5 + }, + { + "objective": qsTr("Group 4 types of fruits and enumerate each group (5 fruits max)"), + "sublevels" : "5", + "numberOfItemType" : 4, + "numberOfItemMax" : 5 + }, + { + "objective": qsTr("Group 3 types of fruits and enumerate each group (6 fruits max)"), + "sublevels" : "6", + "numberOfItemType" : 3, + "numberOfItemMax" : 6 + }, + { + "objective": qsTr("Group 4 types of fruits and enumerate each group (6 fruits max)"), + "sublevels" : "6", + "numberOfItemType" : 4, + "numberOfItemMax" : 6 + }, + { + "objective": qsTr("Group 3 types of fruits and enumerate each group (7 fruits max)"), + "sublevels" : "7", + "numberOfItemType" : 3, + "numberOfItemMax" : 7 + }, + { + "objective": qsTr("Group 4 types of fruits and enumerate each group (7 fruits max)"), + "sublevels" : "7", + "numberOfItemType" : 4, + "numberOfItemMax" : 7 + }, + { + "objective": qsTr("Group 3 types of fruits and enumerate each group (8 fruits max)"), + "sublevels" : "8", + "numberOfItemType" : 3, + "numberOfItemMax" : 8 + }, + { + "objective": qsTr("Group 4 types of fruits and enumerate each group (8 fruits max)"), + "sublevels" : "8", + "numberOfItemType" : 4, + "numberOfItemMax" : 8 + }, + { + "objective": qsTr("Group 3 types of fruits and enumerate each group (9 fruits max)"), + "sublevels" : "9", + "numberOfItemType" : 3, + "numberOfItemMax" : 9 + }, + { + "objective": qsTr("Group 4 types of fruits and enumerate each group (9 fruits max)"), + "sublevels" : "9", + "numberOfItemType" : 4, + "numberOfItemMax" : 9 + } + ] +}