diff --git a/src/activities/activities.txt b/src/activities/activities.txt --- a/src/activities/activities.txt +++ b/src/activities/activities.txt @@ -119,6 +119,7 @@ note_names number_sequence numbers-odd-even +question_and_answer paintings penalty piano_composition diff --git a/src/activities/question_and_answer/ActivityInfo.qml b/src/activities/question_and_answer/ActivityInfo.qml new file mode 100644 --- /dev/null +++ b/src/activities/question_and_answer/ActivityInfo.qml @@ -0,0 +1,40 @@ +/* GCompris - ActivityInfo.qml + * + * Copyright (C) 2018 Amit Sagtani + * + * 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: "question_and_answer/Question_and_answer.qml" + difficulty: 3 + icon: "question_and_answer/question_and_answer.svg" + author: "Amit Sagtani <asagtani06@gmail.com>" + demo: true + //: Activity title + title: qsTr("Questions and Answers") + //: Help title + description: qsTr("Click on the start button to start answering and when finished click on submit to evaluate") + //intro: "put here in comment the text for the intro voice" + //: Help goal + goal: qsTr("Answer questions asked as per the levels. The questions set might be predefined or handpicked in admin mode.") + //: Help prerequisite + prerequisite: "" + //: Help manual + manual: "" + credit: "" + section: "fun" + createdInVersion: 9500 +} diff --git a/src/activities/question_and_answer/CMakeLists.txt b/src/activities/question_and_answer/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/src/activities/question_and_answer/CMakeLists.txt @@ -0,0 +1 @@ +GCOMPRIS_ADD_RCC(activities/question_and_answer *.qml *.svg *.js resource/*) diff --git a/src/activities/question_and_answer/MenuScreen.qml b/src/activities/question_and_answer/MenuScreen.qml new file mode 100644 --- /dev/null +++ b/src/activities/question_and_answer/MenuScreen.qml @@ -0,0 +1,218 @@ +/* GCompris - MenuScreen.qml +* +* Copyright (C) Amit Sagtani +* +* Authors: +* Pascal Georges (pascal.georges1@free.fr) (GTK+ version) +* Holger Kaelberer (Qt Quick port of imageid) +* Siddhesh suthar (Qt Quick port) +* Bruno Coudoin (Integration Lang dataset) +* +* 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 QtGraphicalEffects 1.0 +import QtQuick.Controls 1.5 + +import "../../core" +import "question_and_answer.js" as Activity + +Image { + id: menuScreen + anchors.fill: parent + fillMode: Image.Tile + source: "qrc:/gcompris/src/activities/digital_electricity/resource/texture02.png" + sourceSize.width: Math.max(parent.width, parent.height) + opacity: 0 + + property alias menuModel: menuModel + property bool keyboardMode: false + property bool started: opacity == 1 + + Behavior on opacity { PropertyAnimation { duration: 200 } } + + visible: opacity != 0 + + function start() { + focus = true + forceActiveFocus() + menuGrid.currentIndex = 0 + opacity = 1 + } + + function stop() { + focus = false + opacity = 0 + } + + Keys.onEscapePressed: { + home() + } + + //Keys.enabled : (items.mode == "expert") ? false : true + Keys.onPressed: { + if(event.key === Qt.Key_Space) { + menuGrid.currentItem.selectCurrentItem() + event.accepted = true + } + if(event.key === Qt.Key_Enter) { + menuGrid.currentItem.selectCurrentItem() + event.accepted = true + } + if(event.key === Qt.Key_Return) { + menuGrid.currentItem.selectCurrentItem() + event.accepted = true + } + if(event.key === Qt.Key_Left) { + menuGrid.moveCurrentIndexLeft() + event.accepted = true + } + if(event.key === Qt.Key_Right) { + menuGrid.moveCurrentIndexRight() + event.accepted = true + } + if(event.key === Qt.Key_Up) { + menuGrid.moveCurrentIndexUp() + event.accepted = true + } + if(event.key === Qt.Key_Down) { + menuGrid.moveCurrentIndexDown() + event.accepted = true + } + } + + Keys.onReleased: { + keyboardMode = true + event.accepted = false + } + + // sections + property int iconWidth: 180 * ApplicationInfo.ratio + property int iconHeight: 180 * ApplicationInfo.ratio + + property int levelCellWidth: background.width / Math.floor(background.width / iconWidth ) + property int levelCellHeight: iconHeight * 1.2 + + ListModel { + id: menuModel + } + + GridView { + id: menuGrid + anchors { + fill: parent + bottomMargin: bar.height + } + cellWidth: levelCellWidth + cellHeight: levelCellHeight + clip: true + model: menuModel + keyNavigationWraps: true + property int spacing: 10 + + delegate: Item { + id: delegateItem + width: levelCellWidth - menuGrid.spacing + height: levelCellHeight - menuGrid.spacing + property string sectionName: name + opacity: 1 + + Rectangle { + id: activityBackground + width: levelCellWidth - menuGrid.spacing + height: levelCellHeight - menuGrid.spacing + anchors.horizontalCenter: parent.horizontalCenter + color: "white" + opacity: 0.5 + } + + Image { + id: containerImage + source: image + anchors.top: activityBackground.top + anchors.horizontalCenter: parent.horizontalCenter + height: activityBackground.height*0.8 - 6 + width: height + anchors.margins: 5 + sourceSize.height: height + fillMode: Image.PreserveAspectCrop + clip: true + } + + GCText { + id: categoryName + anchors.top: containerImage.bottom + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + width: activityBackground.width + height: activityBackground.height*0.2 - 6 + fontSizeMode: Text.Fit + elide: Text.ElideRight + maximumLineCount: 2 + wrapMode: Text.WordWrap + text: name + opacity: 1 + } + + ParticleSystemStarLoader { + id: particles + anchors.fill: activityBackground + } + MouseArea { + anchors.fill: activityBackground + enabled: menuScreen.started + onClicked: selectCurrentItem() + } + + function selectCurrentItem() { + particles.burst(50) + console.log(name) + Activity.initializeSubActivity(index) + menuScreen.stop() + } + + } //delegate close + + highlight: Rectangle { + width: levelCellWidth - menuGrid.spacing + height: levelCellHeight - menuGrid.spacing + color: "#AA41AAC4" + border.width: 3 + border.color: "black" + visible: true + Behavior on x { SpringAnimation { spring: 2; damping: 0.2 } } + Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } } + } + + Rectangle { + id: menusMask + visible: false + anchors.fill: menuGrid + gradient: Gradient { + GradientStop { position: 0.0; color: "#FFFFFFFF" } + GradientStop { position: 0.92; color: "#FFFFFFFF" } + GradientStop { position: 0.96; color: "#00FFFFFF" } + } + } + + layer.enabled: ApplicationInfo.useOpenGL + layer.effect: OpacityMask { + id: activitiesOpacity + source: menuGrid + maskSource: menusMask + anchors.fill: menuGrid + } + } // grid view close +} diff --git a/src/activities/question_and_answer/Question_and_answer.qml b/src/activities/question_and_answer/Question_and_answer.qml new file mode 100644 --- /dev/null +++ b/src/activities/question_and_answer/Question_and_answer.qml @@ -0,0 +1,540 @@ +/* GCompris - question_and_answer.qml + * + * Copyright (C) 2018 Amit Sagtani + * + * Authors: + * Amit Sagtani + * + * 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 QtQuick.Controls 1.5 +import QtQuick.Layouts 1.1 +import QtQuick.Controls.Styles 1.4 + +import "../../core" +import "question_and_answer.js" as Activity + +ActivityBase { + id: activity + onStart: focus = true + onStop: {} + pageComponent: Image { + id: background + anchors.fill: parent + source: "qrc:/gcompris/src/activities/algebra_by/resource/background.svg" + signal start + signal stop + + Component.onCompleted: { + dialogActivityConfig.getInitialConfiguration() + activity.start.connect(start) + activity.stop.connect(stop) + } + + // Add here the QML items you need to access in javascript + QtObject { + id: items + property Item main: activity.main + property alias background: background + property alias bar: bar + property alias bonus: bonus + property alias menuScreen: menuScreen + property alias menuModel: menuScreen.menuModel + property alias startFinishButton: startFinishButton + property string currentMode: "freeMode" + property alias questionsGrid: questionsGrid + property alias sampleQuestion: sampleQuestion + property alias playArea: playArea + property alias parser: parser + property int noOfQuestions + property int sampleWidth: 750 + property bool levelStarted: false + property bool showAnswerStatus: false + property var questions: [] + property var answers: [] + property var allQuestions: [] + property var longestQuestion: "" + property int questionsCount: 0 + property var hash: [] + property int currentSubActivity + property var buttonType: "submit" + property bool editAnswers: false + } + + onStart: { Activity.init(items) } + onStop: { Activity.stop() } + + JsonParser { + id: parser + } + + GCText { + id: noQuestionText + visible: (items.questions.length === 0) + anchors.verticalCenter: playArea.verticalCenter + horizontalAlignment: Text.AlignHCenter + width: playArea.width + text: qsTr("Please select at least one question in the configuration screen.") + z: 1 + wrapMode: Text.WordWrap + color: "white" + fontSize: regularSize + } + + GCText { + id: sampleQuestion + visible: false + width: (background.width < background.height) ? playArea.width / 2 :(text.length > 20) ? playArea.width / 2 : playArea.width / 5 + height: (text.length > 20) ? contentHeight : 200 + wrapMode: Text.WordWrap + color: "white" + fontSize: smallSize + } + + Rectangle { + id: playArea + width: background.width * 0.95 + height: (background.width > background.height) ? background.height * 0.90 - bar.height : background.height * 0.90 - bar.height - startFinishButton.width + border.color: "black" + border.width: 5 + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: background.top + anchors.topMargin: 60 + color: "#32000000" + radius: 20 + } + + GridView { + id: questionsGrid + visible: false + model: items.questions.length + anchors.top: playArea.top + anchors.left: playArea.left + anchors.leftMargin: 30 + width: playArea.width + height: playArea.height - 200 + anchors.horizontalCenter: playArea.horizontalCenter + cellHeight: (sampleQuestion.height < sampleQuestion.width * 0.1) ? sampleQuestion.height * 2 : sampleQuestion.height * 1.2 + cellWidth: sampleQuestion.width * 2 + property int spacing: 60 + delegate: + Item { + id: questionItem + state: "short" + property alias text: sampleAnswer.text + GCText { + id: questionText + text: items.questions[index] + wrapMode: Text.WordWrap + horizontalAlignment: Text.AlignHCenter + fontSize: smallSize + verticalAlignment: Text.AlignVCenter + width: questionsGrid.cellWidth * 0.5 + height: questionsGrid.cellHeight + fontSizeMode: Text.Fit + } + GCText { + id: sampleAnswer + visible: false + height: getHeight() + width: questionsGrid.cellWidth * 0.3 + wrapMode: Text.WordWrap + color: "white" + fontSize: tinySize + function getHeight() { + if(text.length > 20) { + if(contentHeight > questionsGrid.cellHeight * 0.8) { + return questionsGrid.cellHeight * 0.8 + } else { + return contentHeight * 1.1 + } + } else { + return bar.height * 0.4 + } + } + } + Rectangle { + id: answerRectangle + border.color: "black" + border.width: 5 + radius: 10 + anchors.left: questionText.right + width: getWidth() + height: sampleAnswer.height * 0.8 + property alias cellWidth: questionText.width + property real cellHeight: questionsGrid.cellHeight + property alias text: questionItem.text + color: "transparent" + function getWidth() { + if(sampleAnswer.contentWidth < questionsGrid.cellWidth * 0.3) { + if(sampleAnswer.contentWidth < questionsGrid.cellWidth * 0.1) + return questionsGrid.cellWidth * 0.1 + else + return sampleAnswer.contentWidth * 1.2 + } else { + return questionsGrid.cellWidth * 0.3 + } + } + TextArea { + id: answerText + width: parent.width + height: parent.height + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + anchors.topMargin: 20 + activeFocusOnPress: true + readOnly: !items.editAnswers + horizontalAlignment: TextInput.AlignHCenter + implicitWidth: bar.height * 0.9 + implicitHeight: 130/800*parent.width + text: answerRectangle.text + font.pixelSize: 24 + backgroundVisible: false + + onTextChanged:{ + answerRectangle.text = answerText.text + } + + onActiveFocusChanged: { + if (!items.levelStarted && items.buttonType != "restart") { + items.levelStarted = true + items.startFinishButton.visibility = true + items.editAnswers = true + answerText.focus = true + } + } + } + } + Image { + id: question_image + width: 50 + height: 50 + visible: items.showAnswerStatus + fillMode: Image.PreserveAspectFit + source: (answerRectangle.text).trim() === items.answers[index] ? + "qrc:/gcompris/src/activities/question_and_answer/resource/right.svg" : + "qrc:/gcompris/src/activities/photo_hunter/resource/wrong.svg" + } + + states: [ + State { + name: "short" + when: (items.sampleQuestion.contentHeight <= items.playArea.height) || questionText.text.length < 0.5 * items.longestQuestion.length + + PropertyChanges { + target: questionText + width: questionsGrid.cellWidth * 0.5 + height: questionsGrid.cellHeight + } + PropertyChanges { + target: answerRectangle + anchors.left: questionText.right + anchors.leftMargin: 50 + anchors.verticalCenter: questionText.verticalCenter + anchors.horizontalCenter: undefined + } + PropertyChanges { + target: question_image + anchors.verticalCenter: questionText.verticalCenter + anchors.left: answerRectangle.right + anchors.top: questionText.top + } + }, + State { + name: "long" + when: (items.sampleQuestion.contentHeight > items.playArea.height) && questionText.text.length > 0.5 * items.longestQuestion.length + PropertyChanges { + target: questionText + width: questionsGrid.cellWidth - 40 + height: questionsGrid.cellHeight * 0.3 + } + PropertyChanges { + target: answerRectangle + anchors.top: questionText.bottom + anchors.horizontalCenter: questionText.horizontalCenter + anchors.verticalCenter: undefined + anchors.left: undefined + } + PropertyChanges { + target: question_image + anchors.left: answerRectangle.right + anchors.top: answerRectangle.top + anchors.verticalCenter: answerRectangle.verticalCenter + } + } + ] + } + + } + MenuScreen { + id: menuScreen + z:2 + } + + BarButton { + id: startFinishButton + property bool visibility: true + source: "qrc:/gcompris/src/core/resource/bar_ok.svg" + height: bar.height * 0.8 + width: startFinishButton.height + sourceSize.width: startFinishButton.width + sourceSize.height: startFinishButton.height + z: 10 + anchors.top: playArea.bottom + anchors.right: playArea.right + visible: !menuScreen.visible && visibility && !noQuestionText.visible + ParticleSystemStarLoader { + id: okButtonParticles + clip: false + } + onClicked: { + if(items.buttonType == "submit") { + if(items.levelStarted) { + items.showAnswerStatus = true + items.levelStarted = false + items.buttonType = "restart" + startFinishButton.source = "qrc:/gcompris/src/core/resource/bar_reload.svg" + items.editAnswers = false + } + } else { + Activity.restartLevel() + items.buttonType = "submit" + startFinishButton.source = "qrc:/gcompris/src/core/resource/bar_ok.svg" + startFinishButton.visibility = false + items.editAnswers = false + } + } + } + + BarButton { + id: sandClock + source: "qrc:/gcompris/src/activities/question_and_answer/resource/sandClock.svg" + visible: startFinishButton.visible && items.buttonType != "restart" + height: bar.height * 0.5 + anchors.verticalCenter: startFinishButton.verticalCenter + anchors.margins: 20 + width: startFinishButton.height / 2 + sourceSize.width: startFinishButton.width + sourceSize.height: startFinishButton.height + z: 10 + anchors.top: playArea.bottom + anchors.right: startFinishButton.left + ParticleSystemStarLoader { + id: okButtonParticles2 + clip: false + } + } + SequentialAnimation { + id: anim + running: true + loops: Animation.Infinite + NumberAnimation { + target: sandClock + property: "rotation" + from: -10; to: 10 + duration: 700 + easing.type: Easing.InOutQuad + } + NumberAnimation { + target: sandClock + property: "rotation" + from: 10; to: -10 + duration: 700 + easing.type: Easing.InOutQuad + } + } + + ExclusiveGroup { + id: configOptions + } + + DialogActivityConfig { + id: dialogActivityConfig + currentActivity: activity + content: Component { + Item { + width: dialogActivityConfig.width + height: dialogActivityConfig.height + property alias grid: grid + property alias adminMode: adminMode + GCDialogCheckBox { + id: freeMode + width: parent.width - 50 + text: qsTr("Free Mode") + checked: items.currentMode === "freeMode" ? true : false + exclusiveGroup: configOptions + onCheckedChanged: { + if(checked) { + items.currentMode = "freeMode" + adminMode.checked = false + + } + Activity.modeChanged() + } + } + + GCDialogCheckBox { + id: adminMode + width: parent.width - 50 + text: qsTr("Admin Mode") + checked: items.currentMode === "adminMode" ? true : false + anchors.top: freeMode.bottom + exclusiveGroup: configOptions + onCheckedChanged: { + if(checked) { + items.currentMode = "adminMode" + freeMode.checked = false + } + Activity.modeChanged() + } + } + + CheckBox { + id:sampleCheckBox + text: items.longestQuestion + checked: false + width: ((dialogActivityConfig.width * 2) / (items.allQuestions[0].length)) * 0.9 + visible: false + style: CheckBoxStyle { + label: Text { + text: items.longestQuestion + wrapMode: Text.WordWrap + anchors.leftMargin: 10 + } + indicator: Rectangle { + implicitWidth: sampleCheckBox.width / 5 + } + } + } + GridView { + id: grid + width: dialogActivityConfig.width + height: dialogActivityConfig.height + anchors.top: adminMode.bottom + visible: adminMode.checked + anchors.topMargin: 30 + cellWidth: (dialogActivityConfig.width * 2) / (items.allQuestions[0].length) + cellHeight: Math.max(sampleCheckBox.height, 40) + model: items.questionsCount + focus: true + delegate: Component { + id: contractDelegate + CheckBox { + id:checkBoxQuestion + property int questionSet: items.hash[index][0] + property int questionIndex: items.hash[index][1] + checked: false + width: grid.cellWidth * 0.9 + height: grid.cellHeight * 0.9 + style: CheckBoxStyle { + label: Text { + text: (items.allQuestions.length > 0) ? items.allQuestions[checkBoxQuestion.questionSet][checkBoxQuestion.questionIndex] : "" + wrapMode: Text.WordWrap + anchors.leftMargin: 10 + } + indicator: Rectangle { + implicitWidth: grid.cellWidth / 8 + implicitHeight: Math.max(grid.cellHeight / 2, 40) + radius: 3 + border.color: control.activeFocus ? "darkblue" : "gray" + border.width: 1 + Rectangle { + visible: control.checked + color: "#555" + border.color: "#333" + radius: 1 + anchors.margins: 4 + anchors.fill: parent + } + } + } + onCheckedChanged: { + if(checked) { + Activity.addQuestion(questionSet, questionIndex) + } else { + Activity.removeQuestion(items.allQuestions[questionSet][questionIndex]) + } + } + } + } + } + } + } + onClose: { + Activity.getMaxWidth() + home() + } + + onLoadData: { + if(dataToSave["currentMode"]) { + items.currentMode = dataToSave["currentMode"] + } + } + onSaveData: { + dataToSave = {"currentMode": items.currentMode} + } + + function setDefaultValues() { + items.levelStarted = false + if (items.currentMode === "adminMode") { + items.questions = [] + items.answers = [] + } + dialogActivityConfig.active = true + displayDialog(dialogActivityConfig) + var dialogChildren = dialogActivityConfig.configItem.grid.contentItem.children + for(var child in dialogChildren) { + if (typeof dialogChildren[child].checked !== 'undefined') { + dialogChildren[child].checked = false + } + } + } + } + + DialogHelp { + id: dialogHelp + onClose: home() + } + + Bar { + id: bar + property BarEnumContent activityZoneContent: BarEnumContent { value: home | level | config} + property BarEnumContent menuScreenContent: BarEnumContent { value: help | home } + content: menuScreen.started ? menuScreenContent : activityZoneContent + onHelpClicked: { + displayDialog(dialogHelp) + } + onPreviousLevelClicked: Activity.previousLevel() + onNextLevelClicked: Activity.nextLevel() + onHomeClicked: { + if(items.menuScreen.started) + activity.home() + else { + Activity.launchMenuScreen() + } + } + onConfigClicked: { + dialogActivityConfig.setDefaultValues() + } + } + + Bonus { + id: bonus + Component.onCompleted: win.connect(Activity.nextLevel) + } + } + +} diff --git a/src/activities/question_and_answer/question_and_answer.js b/src/activities/question_and_answer/question_and_answer.js new file mode 100644 --- /dev/null +++ b/src/activities/question_and_answer/question_and_answer.js @@ -0,0 +1,189 @@ +/* GCompris - question_and_answer.js + * + * Copyright (C) 2018 Amit Sagtani + * + * Authors: + * "Amit Sagtani" + * + * 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 + +var currentLevel = 0 +var numberOfLevel +var numberOfSubActivities +var currentActivityIndex = 0 +var items +var datasetDetails +var dataset +var questions +var allQuestions +var restartingLevel = false + +function init(items_) { + items = items_ + datasetDetails = items.parser.parseFromUrl("qrc:/gcompris/src/activities/question_and_answer/resource/dataset.json").data + numberOfSubActivities = datasetDetails.length + items.menuModel.clear(); + initializeMenuScreen() + start() +} + +function initializeMenuScreen() { + for(var i = 0; i < numberOfSubActivities; i++) { + var data = { + name: datasetDetails[i]["category"], + image: datasetDetails[i]["category_image_src"], + } + items.menuModel.append(data) + } +} + +function start() { + currentLevel = 0 + launchMenuScreen() +} + +function stop() { +} + +function resetButtonVisibility() { + items.startFinishButton.visibility = true + items.showAnswerStatus = false +} + +function modeChanged() { + resetButtonVisibility() + items.levelStarted = false + setQuestions() +} + +function setQuestions() { + if(items.currentMode === "freeMode") { + items.questions = dataset["questions"][currentLevel] + items.answers = dataset["answers"][currentLevel] + } else if (!restartingLevel){ + items.questions = [] + items.answers = [] + } + items.questionsGrid.visible = true +} + +function getMaxWidth() { + if(items.questions.length === 0) + return + var maxLength = items.questions[0].length + var index = 0 + for(var i = 1; i < items.questions.length; i++) { + if(items.questions[i].length > maxLength) { + maxLength = items.questions[i].length + index = i + } + } + items.sampleQuestion.text = items.questions[index] +} + +function initializeButtonProperty() { + items.startFinishButton.visibility = false + items.startFinishButton.source = "qrc:/gcompris/src/core/resource/bar_ok.svg" + items.buttonType = "submit" + items.editAnswers = false +} + +function initLevel() { + items.bar.level = currentLevel + 1 + resetButtonVisibility() + items.levelStarted = false + setQuestions() + getMaxWidth() + initializeButtonProperty() +} + +function nextLevel() { + if(numberOfLevel <= ++currentLevel) { + currentLevel = 0 + } + items.questionsGrid.visible = false + initLevel(); +} + +function previousLevel() { + if(--currentLevel < 0) { + currentLevel = numberOfLevel - 1 + } + items.questionsGrid.visible = false + initLevel(); +} + +function restartLevel() { + restartingLevel = true + nextLevel() + previousLevel() + resetButtonVisibility() + clearAnswerAreas() + restartingLevel = false +} + + +function addQuestion(questionSet, questionIndex) { + items.questions = items.questions.concat(dataset["questions"][questionSet][questionIndex]) + items.answers = items.answers.concat(dataset["answers"][questionSet][questionIndex]) +} + +function removeQuestion(questionValue) { + for( var i = 0; i < items.questions.length; i++){ + if ( items.questions[i] === questionValue) { + items.questions.splice(i, 1); + items.answers.splice(i, 1); + } + } +} + +function setLongestQuestion() { + var longestText = "" + for(var i = 0; i < items.allQuestions.length; i++) { + for(var j = 0; j < items.allQuestions[i].length; j++) { + if(items.allQuestions[i][j].length > longestText.length) + longestText = items.allQuestions[i][j] + items.hash[items.questionsCount] = [i, j] + items.questionsCount++ + } + } + items.longestQuestion = longestText +} +function clearAnswerAreas() { + var answers = items.questionsGrid.contentItem.children + for(var child in answers) { + if(typeof answers[child].text !== 'undefined') { + answers[child].text = "" + } + } +} +function initializeSubActivity(index) { + currentActivityIndex = index + currentLevel = 0 + dataset = items.parser.parseFromUrl("qrc:/gcompris/src/activities/question_and_answer/resource/dataset" + currentActivityIndex + ".json").data + numberOfLevel = dataset["questions"].length + items.questionsCount = 0 + items.noOfQuestions = numberOfLevel + items.allQuestions = dataset["questions"] + setLongestQuestion() + initLevel() + clearAnswerAreas() +} + +function launchMenuScreen() { + items.menuScreen.start() +} diff --git a/src/activities/question_and_answer/question_and_answer.svg b/src/activities/question_and_answer/question_and_answer.svg new file mode 100644 --- /dev/null +++ b/src/activities/question_and_answer/question_and_answer.svg @@ -0,0 +1,83 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/src/activities/question_and_answer/resource/dataset.json b/src/activities/question_and_answer/resource/dataset.json new file mode 100644 --- /dev/null +++ b/src/activities/question_and_answer/resource/dataset.json @@ -0,0 +1,16 @@ +{ + "data": [ + { + "category": "Multiplication", + "category_image_src": "qrc:/gcompris/src/activities/algebra_by/algebra_by.svg" + }, + { + "category": "Addition", + "category_image_src": "qrc:/gcompris/src/activities/algebra_plus/algebra_plus.svg" + }, + { + "category": "Sample Questions", + "category_image_src": "qrc:/gcompris/src/activities/algebra_plus/algebra_plus.svg" + } + ] +} diff --git a/src/activities/question_and_answer/resource/dataset0.json b/src/activities/question_and_answer/resource/dataset0.json new file mode 100644 --- /dev/null +++ b/src/activities/question_and_answer/resource/dataset0.json @@ -0,0 +1,29 @@ + + { + "data": { + "category": "Multiplication", + "category_image_src": "qrc:/gcompris/src/activities/algebra_by/algebra_by.svg", + "operator":"*", + "questions": [ + ["2 * 1", "2 * 2", "2 * 3", "2 * 4", "2 * 5", "2 * 6", "2 * 7", "2 * 8", "2 * 9"], + ["3 * 1", "3 * 2", "3 * 3", "3 * 4", "3 * 5", "3 * 6", "3 * 7", "3 * 8", "3 * 9"], + ["4 * 1", "4 * 2", "4 * 3", "4 * 4", "4 * 5", "4 * 6", "4 * 7", "4 * 8", "4 * 9"], + ["5 * 1", "5 * 2", "5 * 3", "5 * 4", "5 * 5", "5 * 6", "5 * 7", "5 * 8", "5 * 9"], + ["6 * 1", "6 * 2", "6 * 3", "6 * 4", "6 * 5", "6 * 6", "6 * 7", "6 * 8", "6 * 9"], + ["7 * 1", "7 * 2", "7 * 3", "7 * 4", "7 * 5", "7 * 6", "7 * 7", "7 * 8", "7 * 9"], + ["8 * 1", "8 * 2", "8 * 3", "8 * 4", "8 * 5", "8 * 6", "8 * 7", "8 * 8", "8 * 9"], + ["9 * 1", "9 * 2", "9 * 3", "9 * 4", "9 * 5", "9 * 6", "9 * 7", "9 * 8", "9 * 9"] + ], + "answers": [ + ["2", "4", "6", "8", "10", "12", "14", "16", "18", "20"], + ["3", "6", "9", "12", "15", "18", "21", "24", "27", "30"], + ["4", "8", "12", "16", "20", "24", "28", "32", "36", "40"], + ["5", "10", "15", "20", "25", "30", "35", "40", "45", "50"], + ["6", "12", "18", "24", "30", "36", "42", "48", "54", "60"], + ["7", "14", "21", "28", "35", "42", "49", "56", "63", "70"], + ["8", "16", "24", "32", "40", "48", "56", "64", "72", "80"], + ["9", "18", "27", "36", "45", "54", "63", "72", "81", "90"] + ] + } + +} diff --git a/src/activities/question_and_answer/resource/dataset1.json b/src/activities/question_and_answer/resource/dataset1.json new file mode 100644 --- /dev/null +++ b/src/activities/question_and_answer/resource/dataset1.json @@ -0,0 +1,29 @@ + + { + "data": { + "category": "Addition", + "category_image_src": "qrc:/gcompris/src/activities/algebra_plus/algebra_plus.svg", + "operator":"+", + "questions": [ + ["2 + 1", "2 + 2", "2 + 3", "2 + 4", "2 + 5", "2 + 6", "2 + 7", "2 + 8", "2 + 9"], + ["3 + 1", "3 + 2", "3 + 3", "3 + 4", "3 + 5", "3 + 6", "3 + 7", "3 + 8", "3 + 9"], + ["4 + 1", "4 + 2", "4 + 3", "4 + 4", "4 + 5", "4 + 6", "4 + 7", "4 + 8", "4 + 9"], + ["5 + 1", "5 + 2", "5 + 3", "5 + 4", "5 + 5", "5 + 6", "5 + 7", "5 + 8", "5 + 9"], + ["6 + 1", "6 + 2", "6 + 3", "6 + 4", "6 + 5", "6 + 6", "6 + 7", "6 + 8", "6 + 9"], + ["7 + 1", "7 + 2", "7 + 3", "7 + 4", "7 + 5", "7 + 6", "7 + 7", "7 + 8", "7 + 9"], + ["8 + 1", "8 + 2", "8 + 3", "8 + 4", "8 + 5", "8 + 6", "8 + 7", "8 + 8", "8 + 9"], + ["9 + 1", "9 + 2", "9 + 3", "9 + 4", "9 + 5", "9 + 6", "9 + 7", "9 + 8", "9 + 9"] + ], + "answers": [ + ["3", "4", "5", "6", "7", "8", "9", "10", "11"], + ["4", "5", "6", "7", "8", "9", "10", "11", "12"], + ["5", "6", "7", "8", "9", "10", "11", "12", "13"], + ["6", "7", "8", "9", "10", "11", "12", "13", "14"], + ["7", "8", "9", "10", "11", "12", "13", "14", "15"], + ["8", "9", "10", "11", "12", "13", "14", "15", "16"], + ["9", "10", "11", "12", "13", "14", "15", "16", "17"], + ["10", "11", "12", "13", "14", "15", "16", "17", "18"] + ] + } + +} diff --git a/src/activities/question_and_answer/resource/dataset2.json b/src/activities/question_and_answer/resource/dataset2.json new file mode 100644 --- /dev/null +++ b/src/activities/question_and_answer/resource/dataset2.json @@ -0,0 +1,29 @@ + + { + "data": { + "category": "Sample Questions", + "category_image_src": "qrc:/gcompris/src/activities/algebra_plus/algebra_plus.svg", + "operator":"+", + "questions": [ + ["What is the capital of India?", "What is the capital of India?", "What is the capital of India?", "What is the capital of India?", "What is the capital of India?", "What is the capital of India?", "What is the capital of India?", "What is the capital of India?", "What is the capital of India?"], + ["How many wonders are there in the world", "How many wonders are there in the world", "How many wonders are there in the world", "How many wonders are there in the world"], + ["For how many years did the french revolution last?", "For how many years did the french revolution last?", "For how many years did the french revolution last?", "For how many years did the french revolution last?"], + ["When the color yellow is mixed in the color red what is the new color formed?", "When the color yellow is mixed in the color red what is the new color formed", "When the color yellow is mixed in the color red what is the new color formed", "When the color yellow is mixed in the color red what is the new color formed"], + ["6 + 1", "6 + 2", "6 + 3", "6 + 4", "6 + 5", "6 + 6", "6 + 7", "6 + 8", "6 + 9"], + ["7 + 1", "7 + 2", "7 + 3", "7 + 4", "7 + 5", "7 + 6", "7 + 7", "7 + 8", "7 + 9"], + ["8 + 1", "8 + 2", "8 + 3", "8 + 4", "8 + 5", "8 + 6", "8 + 7", "8 + 8", "8 + 9"], + ["9 + 1", "9 + 2", "9 + 3", "9 + 4", "9 + 5", "9 + 6", "9 + 7", "9 + 8", "9 + 9"] + ], + "answers": [ + ["New Delhi", "New Delhi", "New Delhi", "New Delhi", "New Delhi", "New Delhi", "New Delhi", "New Delhi", "New Delhi"], + ["7", "7", "7", "7"], + ["10", "10", "10", "10"], + ["Orange", "Orange", "Orange", "Orange"], + ["7", "8", "9", "10", "11", "12", "13", "14", "15"], + ["8", "9", "10", "11", "12", "13", "14", "15", "16"], + ["9", "10", "11", "12", "13", "14", "15", "16", "17"], + ["10", "11", "12", "13", "14", "15", "16", "17", "18"] + ] + } + +} diff --git a/src/activities/question_and_answer/resource/right.svg b/src/activities/question_and_answer/resource/right.svg new file mode 100644 --- /dev/null +++ b/src/activities/question_and_answer/resource/right.svg @@ -0,0 +1,407 @@ + + + + + green tick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + green tick + 2011-09-09T14:54:18 + a green tick. + https://openclipart.org/detail/159733/green-tick-by-koppi + + + koppi + + + + + green + grün + haken + häkchen + tick + + + + + + + + + + + diff --git a/src/activities/question_and_answer/resource/sandClock.svg b/src/activities/question_and_answer/resource/sandClock.svg new file mode 100644 --- /dev/null +++ b/src/activities/question_and_answer/resource/sandClock.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + +