diff --git a/src/activities/activities.txt b/src/activities/activities.txt index c0fe20266b..8a912d6843 100644 --- a/src/activities/activities.txt +++ b/src/activities/activities.txt @@ -121,6 +121,7 @@ paintings penalty photo_hunter planegame +question_and_answer railroad readingh readingv diff --git a/src/activities/question_and_answer/ActivityInfo.qml b/src/activities/question_and_answer/ActivityInfo.qml new file mode 100644 index 0000000000..0c17d1284f --- /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: "Question_and_answer activity" + //: Help title + description: "" + //intro: "put here in comment the text for the intro voice" + //: Help goal + goal: "" + //: 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 index 0000000000..4b1c9ef9c9 --- /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 index 0000000000..2fdbf44435 --- /dev/null +++ b/src/activities/question_and_answer/MenuScreen.qml @@ -0,0 +1,219 @@ +/* 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" //"qrc:/gcompris/src/activities/algebra_by/resource/background.svg" + sourceSize.width: Math.max(parent.width, parent.height) + opacity: 0 + + property alias menuModel: menuModel + //property alias iAmReady: iAmReady + 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 //(items.mode == "expert") ? 0 : 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 index 0000000000..0bf8bc6a3e --- /dev/null +++ b/src/activities/question_and_answer/Question_and_answer.qml @@ -0,0 +1,273 @@ +/* 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 +import "dataset.js" as Dataset + +ActivityBase { + id: activity + property var dataset: Dataset + onStart: focus = true + onStop: {} + pageComponent: Image { + id: background + anchors.fill: parent + source: "qrc:/gcompris/src/activities/algebra_by/resource/background.svg" //"qrc:/gcompris/src/activities/digital_electricity/resource/texture02.png" + signal start + signal stop + + Component.onCompleted: { + 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 int noOfQuestions: 9 + property bool levelStarted: false + property bool showAnswerStatus: false + property var questions: [] + property var answers: [] + } + + onStart: { Activity.init(items, dataset) } + onStop: { Activity.stop() } + + Rectangle { + id: playArea + width: background.width * 0.95 + height: background.height * 0.90 - bar.height + border.color: "black" + border.width: 5 + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: bar.top + anchors.bottomMargin: 30 + color: "#32000000" + radius: 20 + } + + GridView { + id: questionsGrid + model: items.questions.length + anchors.top: playArea.top + anchors.left: playArea.left + anchors.margins: 50 + width: playArea.width - 200 + height: playArea.height - 200 + cellHeight: height / 3 + cellWidth: background.width > background.height ? width / 3 : width / 2 + property int spacing: 60 + + delegate: + Item { + GCText { + id: questionText + text: items.questions[index] + " = " + fontSizeMode: Text.Fit + wrapMode: Text.WordWrap + width: questionsGrid.cellWidth / 2.6 + height: questionsGrid.cellHeight + } + TextField { + id: answerText + height: bar.height * 0.3 + width: bar.height * 0.9 + //anchors.margins: 30 + anchors.left: questionText.right + //validator: IntValidator{bottom: 1; top: 200;} + activeFocusOnPress: true + readOnly: !items.levelStarted + onReadOnlyChanged: focus = false + horizontalAlignment: TextInput.AlignHCenter + onVisibleChanged: text = "" + font.pixelSize: 24 + style: TextFieldStyle { + textColor: "black" + background: Rectangle { + radius: 5 + color: "transparent" + implicitWidth: bar.height * 0.9 + implicitHeight: 130/800*parent.width + border.color: "#333" + border.width: 2 + } + } + } + Image { + id: question_image + width: 50 + height: 50 + anchors.left: answerText.right + anchors.top: questionText.top + visible: items.showAnswerStatus + fillMode: Image.PreserveAspectFit + source: (answerText.text).trim() === items.answers[index] ? + "qrc:/gcompris/src/activities/question_and_answer/resource/right.svg" : + "qrc:/gcompris/src/activities/photo_hunter/resource/wrong.svg" + } + } + + } + + MenuScreen { + id: menuScreen + } + + Button { + id: startFinishButton + property bool visibility: true + style: GCButtonStyle { theme: "highContrast" } + height: bar.height * 0.4 + visible: !menuScreen.visible && visibility + text: items.levelStarted ? qsTr("Submit") : qsTr("Start") + onClicked: { + if(items.levelStarted) { + items.showAnswerStatus = true + items.levelStarted = false + visibility = false + } + else { + items.levelStarted = true + items.showAnswerStatus = false + } + + //items.levelStarted = !items.levelStarted + //Activity.checkAnswer() + console.log(items.answers) + } + anchors.top: playArea.bottom + anchors.right: restartButton.left + anchors.margins: 20 + } + + Button { + id: restartButton + style: GCButtonStyle { theme: "highContrast"} + height: bar.height * 0.4 + visible: !menuScreen.visible + text: qsTr("Restart") + onClicked: { + Activity.nextLevel() + Activity.previousLevel() + console.log(" 23 ".trim()) + items.showAnswerStatus = false + startFinishButton.visibility = true + } + anchors.top: playArea.bottom + anchors.right: playArea.right + anchors.margins: 20 + } + + ExclusiveGroup { + id: configOptions + } + + DialogActivityConfig { + id: dialogActivityConfig + content: Component { + Column { + spacing: 10 + width: dialogActivityConfig.width + height: dialogActivityConfig.height + + 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" + console.log("Free mode selected.") + } + } + } + + GCDialogCheckBox { + id: adminMode + width: parent.width - 50 + text: qsTr("Admin Mode") + checked: items.currentMode === "adminMode" ? true : false + //exclusiveGroup: configOptions + onCheckedChanged: { + if(checked) { + items.currentMode = "adminMode" + console.log("Admin mode selected") + } + } + } + } + } + onClose: home() + } + + DialogHelp { + id: dialogHelp + onClose: home() + } + + Bar { + id: bar + property BarEnumContent activityZoneContent: BarEnumContent { value: home | level } + property BarEnumContent menuScreenContent: BarEnumContent { value: help | home | config } + 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.active = true + displayDialog(dialogActivityConfig) + } + } + + Bonus { + id: bonus + Component.onCompleted: win.connect(Activity.nextLevel) + } + } + +} diff --git a/src/activities/question_and_answer/Questions.qml b/src/activities/question_and_answer/Questions.qml new file mode 100644 index 0000000000..6957cb0f17 --- /dev/null +++ b/src/activities/question_and_answer/Questions.qml @@ -0,0 +1,11 @@ +import QtQuick 2.6 +import GCompris 1.0 +import QtQuick.Controls 1.5 +import "../../core" +import "question_and_answer.js" as Activity + +Rectangle { + GCText{ + text: "Hello World" + } +} diff --git a/src/activities/question_and_answer/dataset.js b/src/activities/question_and_answer/dataset.js new file mode 100644 index 0000000000..40fe5b0fcc --- /dev/null +++ b/src/activities/question_and_answer/dataset.js @@ -0,0 +1,76 @@ +/* GCompris - dataset.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 . + */ + +function get() { + return [ + { + 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"] + ] + }, + + { + 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/question_and_answer.js b/src/activities/question_and_answer/question_and_answer.js new file mode 100644 index 0000000000..6dd0d6e51c --- /dev/null +++ b/src/activities/question_and_answer/question_and_answer.js @@ -0,0 +1,107 @@ +/* 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 dataset +var questions + +function init(items_, dataset_) { + items = items_ + dataset = dataset_.get() + numberOfSubActivities = dataset.length + items.menuModel.clear(); + initializeMenuScreen() + start() +} + +function initializeMenuScreen() { + for(var i = 0; i < numberOfSubActivities; i++) { + var data = { + name: dataset[i]["category"], + image: dataset[i]["category_image_src"], + } + items.menuModel.append(data) + } +} + +function start() { + currentLevel = 0 + launchMenuScreen() +} + +function stop() { +} + +function initLevel() { + items.bar.level = currentLevel + 1 + items.startFinishButton.visibility = true + items.showAnswerStatus = false + items.levelStarted = false + setQuestions() +} + +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 setQuestions() { + //questions = [] + if(items.currentMode === "freeMode") { + items.questions = dataset[currentActivityIndex]["questions"][currentLevel] + items.answers = dataset[currentActivityIndex]["answers"][currentLevel] + } + //items.questions = questions + items.questionsGrid.visible = true +} + +function initializeSubActivity(index) { + currentActivityIndex = index + currentLevel = 0 + numberOfLevel = dataset[currentActivityIndex]["questions"].length + items.noOfQuestions = numberOfLevel + initLevel() +} + +function launchMenuScreen() { + items.menuScreen.start() +} + +function checkAnswer() { + +} 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 index 0000000000..c1f9f474a8 --- /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/right.svg b/src/activities/question_and_answer/resource/right.svg new file mode 100644 index 0000000000..4aa3709dc0 --- /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 + + + + + + + + + + +