diff --git a/src/activities/babymatch/Babymatch.qml b/src/activities/babymatch/Babymatch.qml index d12e2dfc1..8d881c0d4 100644 --- a/src/activities/babymatch/Babymatch.qml +++ b/src/activities/babymatch/Babymatch.qml @@ -1,316 +1,348 @@ /* GCompris - Babymatch.qml * * Copyright (C) 2015 Pulkit Gupta * * Authors: * Bruno Coudoin (GTK+ version) * Pulkit Gupta (Qt Quick port) * * 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 QtQuick 2.6 import GCompris 1.0 import "../../core" import "babymatch.js" as Activity ActivityBase { id: activity // In most cases, these 3 are the same. // But for imageName for example, we reuse the images of babymatch, so we need to differentiate them property string imagesUrl: boardsUrl property string soundsUrl: boardsUrl + property bool useMultipleDataset: false property string boardsUrl: "qrc:/gcompris/src/activities/babymatch/resource/" property int levelCount: 7 property bool answerGlow: true //For highlighting the answers property bool displayDropCircle: true //For displaying drop circles onStart: focus = true onStop: {} pageComponent: Image { id: background anchors.fill: parent source: "qrc:/gcompris/src/activities/guesscount/resource/backgroundW01.svg" signal start signal stop property bool vert: background.width >= background.height Component.onCompleted: { + dialogActivityConfig.initialize() activity.start.connect(start) activity.stop.connect(stop) } // Add here the QML items you need to access in javascript QtObject { id: items property alias background: background property alias bar: bar property alias bonus: bonus property alias availablePieces: availablePieces property alias backgroundPiecesModel: backgroundPiecesModel property alias file: file property alias grid: grid property alias backgroundImage: backgroundImage property alias leftWidget: leftWidget property alias instruction: instruction property alias toolTip: toolTip property alias score: score + property var levels: activity.datasetLoader.data.length !== 0 ? activity.datasetLoader.data : null property alias dataset: dataset } Loader { id: dataset asynchronous: false } - onStart: { Activity.start(items, imagesUrl, soundsUrl, boardsUrl, levelCount, answerGlow, displayDropCircle) } + onStart: { Activity.start(items, imagesUrl, soundsUrl, boardsUrl, levelCount, answerGlow, displayDropCircle, useMultipleDataset) } onStop: { Activity.stop() } DialogHelp { id: dialogHelp onClose: home() } Bar { id: bar - content: BarEnumContent { value: help | home | level } + content: BarEnumContent { value: useMultipleDataset ? (help | home | level | activityConfig) : (help | home | level) } onHelpClicked: {displayDialog(dialogHelp)} onPreviousLevelClicked: Activity.previousLevel() onNextLevelClicked: Activity.nextLevel() - onHomeClicked: activity.home() + onHomeClicked: { + Activity.resetData(); + activity.home() + } + onActivityConfigClicked: { + Activity.initLevel() + displayDialog(dialogActivityConfig) + } } + DialogChooseLevel { + id: dialogActivityConfig + currentActivity: activity.activityInfo + onSaveData: { + levelFolder = dialogActivityConfig.chosenLevels + currentActivity.currentLevels = dialogActivityConfig.chosenLevels + ApplicationSettings.setCurrentLevels(currentActivity.name, dialogActivityConfig.chosenLevels) + activity.focus = true + } + onLoadData: { + if(activityData) { + Activity.initLevel() + } + } + onClose: { + home() + } + onStartActivity: { + background.start() + } + } + Score { id: score visible: numberOfSubLevels > 1 } Bonus { id: bonus Component.onCompleted: win.connect(Activity.nextSubLevel) } File { id: file name: "" } Image { id: leftWidget source: "qrc:/gcompris/src/activities/guesscount/resource/backgroundW02.svg" width: background.vert ? 90 * ApplicationInfo.ratio : background.width height: background.vert ? background.height : 90 * ApplicationInfo.ratio anchors.left: parent.left ListWidget { id: availablePieces vert: background.vert } MouseArea { anchors.fill: parent onPressed: (instruction.opacity == 0 ? instruction.show() : instruction.hide()) } } Rectangle { id: toolTip anchors { bottom: bar.top bottomMargin: 10 left: leftWidget.left leftMargin: 5 } width: toolTipTxt.width + 10 height: toolTipTxt.height + 5 opacity: 1 radius: 10 z: 100 color: "#E8E8E8" property alias text: toolTipTxt.text Behavior on opacity { NumberAnimation { duration: 120 } } function show(newText) { if(newText) { text = newText opacity = 0.8 } else { opacity = 0 } } Rectangle { width: parent.width - anchors.margins height: parent.height - anchors.margins anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter anchors.margins: parent.height/8 radius: 10 color: "#87A6DD" //light blue } Rectangle { width: parent.width - anchors.margins height: parent.height - anchors.margins anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter anchors.margins: parent.height/4 radius: 10 color: "#E8E8E8" //paper white } GCText { id: toolTipTxt anchors.centerIn: parent fontSize: regularSize color: "#373737" horizontalAlignment: Text.AlignHCenter wrapMode: TextEdit.WordWrap } } Rectangle { id: grid color: "transparent" z: 2 x: background.vert ? 90 * ApplicationInfo.ratio : 0 y: background.vert ? 0 : 90 * ApplicationInfo.ratio width: background.vert ? background.width - 90 * ApplicationInfo.ratio : background.width height: background.vert ? background.height - (bar.height * 1.1) : background.height - (bar.height * 1.1) - 90 * ApplicationInfo.ratio Image { id: backgroundImage fillMode: Image.PreserveAspectFit property double ratio: sourceSize.width / sourceSize.height property double gridRatio: grid.width / grid.height property alias instruction: instruction source: "" z: 2 width: source == "" ? grid.width : (ratio > gridRatio ? grid.width : grid.height * ratio) height: source == "" ? grid.height : (ratio < gridRatio ? grid.height : grid.width / ratio) anchors.topMargin: 10 anchors.centerIn: parent //Inserting static background images Repeater { id: backgroundPieces model: backgroundPiecesModel delegate: piecesDelegate z: 2 Component { id: piecesDelegate Image { id: shapeBackground source: Activity.imagesUrl + imgName x: posX * backgroundImage.width - width / 2 y: posY * backgroundImage.height - height / 2 height: imgHeight ? imgHeight * backgroundImage.height : (backgroundImage.source == "" ? backgroundImage.height * shapeBackground.sourceSize.height / backgroundImage.height : backgroundImage.height * shapeBackground.sourceSize.height / backgroundImage.sourceSize.height) width: imgWidth ? imgWidth * backgroundImage.width : (backgroundImage.source == "" ? backgroundImage.width * shapeBackground.sourceSize.width / backgroundImage.width : backgroundImage.width * shapeBackground.sourceSize.width / backgroundImage.sourceSize.width) fillMode: Image.PreserveAspectFit } } } MouseArea { anchors.fill: parent onPressed: (instruction.opacity == 0 ? instruction.show() : instruction.hide()) } } } Rectangle { id: instruction anchors.horizontalCenter: instructionTxt.horizontalCenter anchors.verticalCenter: instructionTxt.verticalCenter width: instructionTxt.width + 40 height: instructionTxt.height + 40 opacity: 0.8 radius: 10 z: 3 color: "#87A6DD" //light blue property alias text: instructionTxt.text Behavior on opacity { PropertyAnimation { duration: 200 } } function show() { if(text) opacity = 1 } function hide() { opacity = 0 } Rectangle { id: insideFill width: parent.width - anchors.margins height: parent.height - anchors.margins anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter anchors.margins: parent.height/8 radius: 10 color: "#E8E8E8" //paper white } } GCText { id: instructionTxt anchors { top: background.vert ? grid.top : leftWidget.bottom topMargin: 20 horizontalCenter: background.vert ? grid.horizontalCenter : leftWidget.horizontalCenter } opacity: instruction.opacity z: instruction.z fontSize: regularSize color: "#373737" horizontalAlignment: Text.AlignHCenter width: Math.max(Math.min(parent.width * 0.9, text.length * 11), parent.width * 0.3) wrapMode: TextEdit.WordWrap } ListModel { id: backgroundPiecesModel } } } diff --git a/src/activities/babymatch/babymatch.js b/src/activities/babymatch/babymatch.js index ad3af13a5..dabbc8108 100644 --- a/src/activities/babymatch/babymatch.js +++ b/src/activities/babymatch/babymatch.js @@ -1,254 +1,259 @@ /* GCompris - babymatch.js * * Copyright (C) 2015 Pulkit Gupta * * Authors: * Bruno Coudoin (GTK+ version) * Pulkit Gupta (Qt Quick port) * * 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 . */ .pragma library .import QtQuick 2.6 as Quick .import GCompris 1.0 as GCompris //for ApplicationInfo +var useMultipleDataset var currentLevel = 1 var currentSubLevel = 0 var numberOfLevel var numberOfSubLevel var items var imagesUrl var soundsUrl var boardsUrl var glowEnabled var glowEnabledDefault var spots = [] var showText = [] var displayDropCircle -function start(items_, imagesUrl_, soundsUrl_, boardsUrl_, levelCount_, answerGlow_, displayDropCircle_) { +function start(items_, imagesUrl_, soundsUrl_, boardsUrl_, levelCount_, answerGlow_, displayDropCircle_, useMultipleDataset_) { items = items_ imagesUrl = imagesUrl_ soundsUrl = soundsUrl_ boardsUrl = boardsUrl_ - numberOfLevel = levelCount_ + useMultipleDataset = useMultipleDataset_ + numberOfLevel = useMultipleDataset ? items.levels.length : levelCount_ glowEnabledDefault = answerGlow_ displayDropCircle = displayDropCircle_ currentLevel = 1 currentSubLevel = 0 numberOfSubLevel = 0 + resetData() + initLevel() +} + +function resetData() { + items.availablePieces.model.clear() + for(var i = 0 ; i < spots.length ; ++ i) + spots[i].destroy() spots = [] + + for(var i = 0 ; i < showText.length ; ++ i) + showText[i].destroy() showText = [] - initLevel() + + items.backgroundPiecesModel.clear() + items.backgroundImage.source = "" } function stop() { for(var i = 0 ; i < spots.length ; ++ i) spots[i].destroy() } function initLevel() { items.bar.level = currentLevel - var filename = boardsUrl + "board" + "/" + "board" + currentLevel + "_" + currentSubLevel + ".qml" - items.dataset.source = filename + if(useMultipleDataset) + items.dataset.source = items.levels[currentLevel-1][currentSubLevel]; + else + items.dataset.source = boardsUrl + "board" + "/" + "board" + currentLevel + "_" + currentSubLevel + ".qml" var levelData = items.dataset.item - - items.availablePieces.model.clear() - for(var i = 0 ; i < spots.length ; ++ i) - spots[i].destroy() - spots = [] - - for(var i = 0 ; i < showText.length ; ++ i) - showText[i].destroy() - showText = [] - - items.backgroundPiecesModel.clear() - items.backgroundImage.source = "" - + resetData(); items.availablePieces.view.currentDisplayedGroup = 0 items.availablePieces.view.previousNavigation = 1 items.availablePieces.view.nextNavigation = 1 items.availablePieces.view.okShowed = false items.availablePieces.view.showGlow = false items.availablePieces.view.ok.height = 0 var dropItemComponent = Qt.createComponent("qrc:/gcompris/src/activities/babymatch/DropAnswerItem.qml") var textItemComponent = Qt.createComponent("qrc:/gcompris/src/activities/babymatch/TextItem.qml") //print(dropItemComponent.errorString()) if(currentSubLevel == 0 && levelData.numberOfSubLevel != undefined) numberOfSubLevel = levelData.numberOfSubLevel items.score.currentSubLevel = currentSubLevel + 1 items.score.numberOfSubLevels = numberOfSubLevel + 1 if(levelData.glow === undefined) glowEnabled = glowEnabledDefault else glowEnabled = levelData.glow items.toolTip.show('') if(levelData.instruction === undefined) { items.instruction.opacity = 0 items.instruction.text = "" } else if(!displayDropCircle) { items.instruction.opacity = 0 items.instruction.text = levelData.instruction } else { items.instruction.opacity = 1 items.instruction.text = levelData.instruction } // Fill available pieces var arr=[], levelDataLength = levelData.levels.length for(var i=0 ; i < levelDataLength ; i++) arr[i] = i var i = 0, j = 0, k = 0, n = 0 while(levelDataLength--) { //Randomize the order of pieces var rand = Math.floor(Math.random() * levelDataLength) i = arr[rand] arr.splice(rand,1) //Create answer pieces if(levelData.levels[i].type === undefined) { items.availablePieces.model.append( { "imgName": levelData.levels[i].pixmapfile, "imgSound": levelData.levels[i].soundFile ? soundsUrl + levelData.levels[i].soundFile : "qrc:/gcompris/src/core/resource/sounds/scroll.wav", "imgHeight": levelData.levels[i].height === undefined ? 0 : levelData.levels[i].height, "imgWidth": levelData.levels[i].width === undefined ? 0 : levelData.levels[i].width, "toolTipText": // We remove the text before the pipe symbol if any (translation disembiguation) levelData.levels[i].toolTipText === undefined ? "" : (levelData.levels[i].toolTipText.split('|').length > 1 ? levelData.levels[i].toolTipText.split('|')[1] : levelData.levels[i].toolTipText), }); spots[j++] = dropItemComponent.createObject( items.backgroundImage, { "posX": levelData.levels[i].x, "posY": levelData.levels[i].y, "imgName" : levelData.levels[i].pixmapfile, }); } //Create Text pieces for the level which has to display additional information else if(levelData.levels[i].type === "DisplayText") { showText[k++] = textItemComponent.createObject( items.backgroundImage, { "posX": levelData.levels[i].x, "posY": levelData.levels[i].y, "textWidth": levelData.levels[i].width, "showText" : levelData.levels[i].text }); } //Create static background pieces else { if(levelData.levels[i].type === "SHAPE_BACKGROUND_IMAGE") { items.backgroundImage.source = imagesUrl + levelData.levels[i].pixmapfile if(levelData.levels[i].width) items.backgroundImage.sourceSize.width = levelData.levels[i].width if(levelData.levels[i].height) items.backgroundImage.sourceSize.height = levelData.levels[i].height } else { items.backgroundPiecesModel.append( { "imgName": levelData.levels[i].pixmapfile, "posX": levelData.levels[i].x, "posY": levelData.levels[i].y, "imgHeight": levelData.levels[i].height === undefined ? 0 : levelData.levels[i].height, "imgWidth": levelData.levels[i].width === undefined ? 0 : levelData.levels[i].width, }); } } } //Initialize displayedGroup variable which is used for showing navigation bars for(var i=0;i * * Authors: * Pulkit Gupta * * 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 GCompris 1.0 ActivityInfo { name: "chronos/Chronos.qml" difficulty: 1 icon: "chronos/chronos.svg" author: "Pulkit Gupta <pulkitgenius@gmail.com>" demo: true //: Activity title title: qsTr("Chronos") //: Help title description: qsTr("Drag and Drop the items to organize the story") // intro: "Slide the pictures into the order that tells the story" //: Help goal goal: qsTr("Sort the pictures into the order that tells the story") //: Help prerequisite prerequisite: qsTr("Tell a short story") //: Help manual manual: qsTr("Pick from the pictures on the left and put them on the red dots") credit: qsTr("Moon photo is copyright NASA. The space sounds come from Tuxpaint and Vegastrike which are released under the GPL license. The transportation images are copyright Franck Doucet. Dates of Transportation are based on those found in <https://www.wikipedia.org>.") section: "sciences history" createdInVersion: 4000 + levels: "1,2" } diff --git a/src/activities/chronos/CMakeLists.txt b/src/activities/chronos/CMakeLists.txt index 0f6d6e687..4d4fc6509 100644 --- a/src/activities/chronos/CMakeLists.txt +++ b/src/activities/chronos/CMakeLists.txt @@ -1 +1 @@ -GCOMPRIS_ADD_RCC(activities/chronos *.qml *.svg *.js resource/board/* resource/images/* resource/sound/*.${COMPRESSED_AUDIO}) +GCOMPRIS_ADD_RCC(activities/chronos *.qml *.svg *.js resource/*.svg resource/*/*) diff --git a/src/activities/chronos/Chronos.qml b/src/activities/chronos/Chronos.qml index 96278d5ca..0336326c5 100644 --- a/src/activities/chronos/Chronos.qml +++ b/src/activities/chronos/Chronos.qml @@ -1,34 +1,34 @@ /* GCompris - Chronos.qml * * Copyright (C) 2015 Pulkit Gupta * * Authors: * José Jorge (GTK+ version) * Pulkit Gupta (Qt Quick port) * * 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 QtQuick 2.6 import "../babymatch" Babymatch { id: activity - onStart: focus = true onStop: {} + useMultipleDataset: true boardsUrl: "qrc:/gcompris/src/activities/chronos/resource/" levelCount: 6 } diff --git a/src/activities/chronos/resource/1/Data.qml b/src/activities/chronos/resource/1/Data.qml new file mode 100644 index 000000000..c301b4a9b --- /dev/null +++ b/src/activities/chronos/resource/1/Data.qml @@ -0,0 +1,37 @@ +/* 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("For children who can read numbers") + difficulty: 5 + data: [ + [ + "qrc:/gcompris/src/activities/chronos/resource/board/board1_0.qml" + ], + [ + "qrc:/gcompris/src/activities/chronos/resource/board/board3_0.qml" + ], + [ + "qrc:/gcompris/src/activities/chronos/resource/board/board4_0.qml" + ] + ] +} diff --git a/src/activities/chronos/resource/2/Data.qml b/src/activities/chronos/resource/2/Data.qml new file mode 100644 index 000000000..39f47bfd1 --- /dev/null +++ b/src/activities/chronos/resource/2/Data.qml @@ -0,0 +1,45 @@ +/* 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("For children who can read words") + difficulty: 6 + data: [ + [ + "qrc:/gcompris/src/activities/chronos/resource/board/board2_0.qml" + ], + [ + "qrc:/gcompris/src/activities/chronos/resource/board/board5_0.qml", + "qrc:/gcompris/src/activities/chronos/resource/board/board5_1.qml", + "qrc:/gcompris/src/activities/chronos/resource/board/board5_2.qml", + "qrc:/gcompris/src/activities/chronos/resource/board/board5_3.qml", + "qrc:/gcompris/src/activities/chronos/resource/board/board5_4.qml", + + ], + [ + "qrc:/gcompris/src/activities/chronos/resource/board/board6_0.qml", + "qrc:/gcompris/src/activities/chronos/resource/board/board6_1.qml", + "qrc:/gcompris/src/activities/chronos/resource/board/board6_2.qml", + "qrc:/gcompris/src/activities/chronos/resource/board/board6_3.qml", + ] + ] +}