[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [gcompris/multiple_dataset] /: multiple dataset, proof of concept
From: Johnny Jazeix <null () kde ! org>
Date: 2018-09-19 17:36:45
Message-ID: E1g2gP7-0000pP-Bf () code ! kde ! org
[Download RAW message or body]
Git commit aad6aa567c3ce79e553ca8a259a4876c3e8985d6 by Johnny Jazeix.
Committed on 19/09/2018 at 17:36.
Pushed by jjazeix into branch 'multiple_dataset'.
multiple dataset, proof of concept
M +1 -0 src/activities/algebra_by/ActivityInfo.qml
A +49 -0 src/activities/algebra_by/resource/1/Data.qml [License: GPL (v3+)]
A +49 -0 src/activities/algebra_by/resource/2/Data.qml [License: GPL (v3+)]
A +49 -0 src/activities/algebra_by/resource/3/Data.qml [License: GPL (v3+)]
A +49 -0 src/activities/algebra_by/resource/4/Data.qml [License: GPL (v3+)]
A +231 -0 src/activities/menu/DialogChooseLevel.qml [License: GPL (v3+)]
M +39 -4 src/activities/menu/Menu.qml
M +2 -1 src/activities/reversecount/ActivityInfo.qml
M +5 -5 src/activities/reversecount/Reversecount.qml
M +1 -1 src/activities/reversecount/Tux.qml
A +49 -0 src/activities/reversecount/resource/1/Data.qml [License: GPL \
(v3+)] A +54 -0 src/activities/reversecount/resource/2/Data.qml [License: \
GPL (v3+)] M +12 -75 src/activities/reversecount/reversecount.js
M +19 -0 src/core/ActivityBase.qml
M +40 -0 src/core/ActivityInfo.cpp
M +44 -22 src/core/ActivityInfo.h
M +0 -14 src/core/ActivityInfoTree.cpp
M +0 -1 src/core/ActivityInfoTree.h
M +14 -0 src/core/ApplicationSettings.cpp
M +11 -5 src/core/ApplicationSettings.h
A +38 -0 src/core/Dataset.qml [License: GPL (v3+)]
M +5 -0 tests/core/ApplicationSettingsTest.cpp
https://commits.kde.org/gcompris/aad6aa567c3ce79e553ca8a259a4876c3e8985d6
diff --git a/src/activities/algebra_by/ActivityInfo.qml \
b/src/activities/algebra_by/ActivityInfo.qml index 4eb99374..7f14046f 100644
--- a/src/activities/algebra_by/ActivityInfo.qml
+++ b/src/activities/algebra_by/ActivityInfo.qml
@@ -37,4 +37,5 @@ ActivityInfo {
credit: ""
section: "math multiplication"
createdInVersion: 0
+ levels: "1,2,3,4"
}
diff --git a/src/activities/algebra_by/resource/1/Data.qml \
b/src/activities/algebra_by/resource/1/Data.qml new file mode 100644
index 00000000..3fcca88b
--- /dev/null
+++ b/src/activities/algebra_by/resource/1/Data.qml
@@ -0,0 +1,49 @@
+/* GCompris - Data.qml
+ *
+ * Copyright (C) 2018 Johnny Jazeix <jazeix@gmail.com>
+ *
+ * Authors:
+ * Johnny Jazeix <jazeix@gmail.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+import "../../../../core"
+
+Dataset {
+ objective: qsTr("This is a long long long long objective. We want to see it it \
can display long long texts. But it is not long long long enough. Or maybe it is...") \
+ data: [ + {
+ "maxNumber": 1, /* Max number on each domino side */
+ "minNumber": 1,
+ "numberOfFish": 3
+ },
+ {
+ "maxNumber": 2,
+ "minNumber": 1,
+ "numberOfFish": 4
+ },
+ {
+ "maxNumber": 3,
+ "minNumber": 1,
+ "numberOfFish": 5
+ },
+ {
+ "maxNumber": 4,
+ "minNumber": 1,
+ "numberOfFish": 5
+ }
+ ]
+}
diff --git a/src/activities/algebra_by/resource/2/Data.qml \
b/src/activities/algebra_by/resource/2/Data.qml new file mode 100644
index 00000000..e919f42d
--- /dev/null
+++ b/src/activities/algebra_by/resource/2/Data.qml
@@ -0,0 +1,49 @@
+/* GCompris - Data.qml
+ *
+ * Copyright (C) 2018 Johnny Jazeix <jazeix@gmail.com>
+ *
+ * Authors:
+ * Johnny Jazeix <jazeix@gmail.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+import "../../../../core"
+
+Dataset {
+ objective: qsTr("obj 2")
+ data: [
+ {
+ "maxNumber": 1, /* Max number on each domino side */
+ "minNumber": 1,
+ "numberOfFish": 3
+ },
+ {
+ "maxNumber": 2,
+ "minNumber": 1,
+ "numberOfFish": 4
+ },
+ {
+ "maxNumber": 3,
+ "minNumber": 1,
+ "numberOfFish": 5
+ },
+ {
+ "maxNumber": 4,
+ "minNumber": 1,
+ "numberOfFish": 5
+ }
+ ]
+}
diff --git a/src/activities/algebra_by/resource/3/Data.qml \
b/src/activities/algebra_by/resource/3/Data.qml new file mode 100644
index 00000000..45d6b690
--- /dev/null
+++ b/src/activities/algebra_by/resource/3/Data.qml
@@ -0,0 +1,49 @@
+/* GCompris - Data.qml
+ *
+ * Copyright (C) 2018 Johnny Jazeix <jazeix@gmail.com>
+ *
+ * Authors:
+ * Johnny Jazeix <jazeix@gmail.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+import "../../../../core"
+
+Dataset {
+ objective: qsTr("obj 3")
+ data: [
+ {
+ "maxNumber": 1, /* Max number on each domino side */
+ "minNumber": 1,
+ "numberOfFish": 3
+ },
+ {
+ "maxNumber": 2,
+ "minNumber": 1,
+ "numberOfFish": 4
+ },
+ {
+ "maxNumber": 3,
+ "minNumber": 1,
+ "numberOfFish": 5
+ },
+ {
+ "maxNumber": 4,
+ "minNumber": 1,
+ "numberOfFish": 5
+ }
+ ]
+}
diff --git a/src/activities/algebra_by/resource/4/Data.qml \
b/src/activities/algebra_by/resource/4/Data.qml new file mode 100644
index 00000000..a0f87426
--- /dev/null
+++ b/src/activities/algebra_by/resource/4/Data.qml
@@ -0,0 +1,49 @@
+/* GCompris - Data.qml
+ *
+ * Copyright (C) 2018 Johnny Jazeix <jazeix@gmail.com>
+ *
+ * Authors:
+ * Johnny Jazeix <jazeix@gmail.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+import "../../../../core"
+
+Dataset {
+ objective: qsTr("obj 4")
+ data: [
+ {
+ "maxNumber": 1, /* Max number on each domino side */
+ "minNumber": 1,
+ "numberOfFish": 3
+ },
+ {
+ "maxNumber": 2,
+ "minNumber": 1,
+ "numberOfFish": 4
+ },
+ {
+ "maxNumber": 3,
+ "minNumber": 1,
+ "numberOfFish": 5
+ },
+ {
+ "maxNumber": 4,
+ "minNumber": 1,
+ "numberOfFish": 5
+ }
+ ]
+}
diff --git a/src/activities/menu/DialogChooseLevel.qml \
b/src/activities/menu/DialogChooseLevel.qml new file mode 100644
index 00000000..c48820b1
--- /dev/null
+++ b/src/activities/menu/DialogChooseLevel.qml
@@ -0,0 +1,231 @@
+/* GCompris - DialogChooseLevel.qml
+ *
+ * Copyright (C) 2018 Johnny Jazeix <jazeix@gmail.com>
+ *
+ * Authors:
+ * Johnny Jazeix <jazeix@gmail.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import QtQuick.Controls 1.5
+import GCompris 1.0
+import "../../core"
+
+/**
+ * A QML component for a full screen configuration dialog.
+ * @ingroup components
+ *
+ * All user editable settings are presented to the user in a
+ * DialogActivityConfig dialog. The global configuration can be accessed
+ * through the Bar in the main menu, activity specific configuration from the
+ * respective activity.
+ *
+ * All config items that are shown in this dialog are persisted
+ * using ApplicationSettings.
+ *
+ * For an example have a look at Menu.qml.
+ *
+ * For more details on how to add configuration to an activity cf.
+ * [the wiki](http://gcompris.net/wiki/Qt_Quick_development_process#Adding_a_configuration_for_a_specific_activity)
+ *
+ * @sa ApplicationSettings
+ * @inherit QtQuick.Item
+ */
+Rectangle {
+ id: dialogChooseLevel
+ visible: false
+
+ /* Public interface: */
+
+ /**
+ * type:string
+ * The name of the activity in case of per-activity config.
+ *
+ * Will be autogenerated unless set by the caller.
+ */
+ property string activityName
+
+ /// @cond INTERNAL_DOCS
+
+ property bool isDialog: true
+
+ /**
+ * type:string
+ * Title of the configuration dialog.
+ */
+ readonly property string title: currentActivity ? qsTr("%1 \
levels").arg(currentActivity.title) : "" +
+ property var difficultiesModel: []
+ property QtObject currentActivity
+
+ property string chosenLevel
+
+ /// @endcond
+
+ /**
+ * Emitted when the config dialog has been closed.
+ */
+ signal close
+
+ /**
+ * Emitted when the config dialog has been started.
+ */
+ signal start
+
+ signal stop
+
+ color: "#696da3"
+ border.color: "black"
+ border.width: 1
+
+ onCurrentActivityChanged: initialize()
+
+ function initialize() {
+ activityName = currentActivity.name.split('/')[0]
+ difficultiesModel = []
+ for(var level in currentActivity.levels) {
+ objectiveLoader.dataFiles.push({"level": currentActivity.levels[level], \
"file": "qrc:/gcompris/src/activities/"+activityName+"/resource/"+currentActivity.levels[level]+"/Data.qml"})
+ }
+ objectiveLoader.start()
+ }
+
+ Loader {
+ id: objectiveLoader
+ property var dataFiles: []
+ property var currentFile
+ signal start
+ signal stop
+
+ onStart: {
+ var file = dataFiles.shift()
+ currentFile = file
+ source = file.file.toString()
+ }
+ onLoaded: {
+ difficultiesModel.push({"level": currentFile.level, "objective": \
item.objective}) + if(dataFiles.length != 0) {
+ start()
+ }
+ else {
+ stop()
+ }
+ }
+ onStop: {
+ difficultiesRepeater.model = difficultiesModel
+ }
+ }
+
+ Row {
+ visible: true
+ spacing: 2
+ Item { width: 10; height: 1 }
+
+ Column {
+ spacing: 10
+ anchors.top: parent.top
+ Item { width: 1; height: 10 }
+ Rectangle {
+ color: "#e6e6e6"
+ radius: 6.0
+ width: dialogChooseLevel.width - 30
+ height: title.height * 1.2
+ border.color: "black"
+ border.width: 2
+
+ Row {
+ spacing: 2
+ padding: 8
+ Image {
+ id: titleIcon
+ anchors {
+ left: parent.left
+ top: parent.top
+ margins: 4 * ApplicationInfo.ratio
+ }
+ }
+
+ GCText {
+ id: title
+ text: dialogChooseLevel.title
+ width: dialogChooseLevel.width - (30 + cancel.width)
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ color: "black"
+ fontSize: 20
+ font.weight: Font.DemiBold
+ wrapMode: Text.WordWrap
+ }
+ }
+ }
+
+ Rectangle {
+ color: "#e6e6e6"
+ radius: 6.0
+ width: dialogChooseLevel.width - 30
+ height: dialogChooseLevel.height - (30 + title.height * 1.2)
+ border.color: "black"
+ border.width: 2
+ anchors.margins: 100
+
+ Flickable {
+ id: flick
+ anchors.margins: 8
+ anchors.fill: parent
+ flickableDirection: Flickable.VerticalFlick
+ clip: true
+ contentHeight: contentItem.childrenRect.height + 40 * \
ApplicationInfo.ratio + ExclusiveGroup {
+ id: levelsGroup
+ }
+ Column {
+ Repeater {
+ id: difficultiesRepeater
+ delegate: GCDialogCheckBox {
+ id: objective
+ width: dialogChooseLevel.width
+ text: modelData.objective
+ exclusiveGroup: levelsGroup
+ checked: chosenLevel == modelData.level
+ onClicked: chosenLevel = modelData.level
+ }
+ }
+ }
+ }
+
+ // The scroll buttons
+ GCButtonScroll {
+ anchors.right: parent.right
+ anchors.rightMargin: 5 * ApplicationInfo.ratio
+ anchors.bottom: flick.bottom
+ anchors.bottomMargin: 5 * ApplicationInfo.ratio
+ onUp: flick.flick(0, 1400)
+ onDown: flick.flick(0, -1400)
+ upVisible: flick.visibleArea.yPosition <= 0 ? false : true
+ downVisible: flick.visibleArea.yPosition + \
flick.visibleArea.heightRatio >= 1 ? false : true + }
+ }
+
+ Item { width: 1; height: 10 }
+ }
+ }
+
+ // The cancel button
+ GCButtonCancel {
+ id: cancel
+ onClose: {
+ parent.close()
+ }
+ }
+}
diff --git a/src/activities/menu/Menu.qml b/src/activities/menu/Menu.qml
index 36fdc430..0c9be144 100644
--- a/src/activities/menu/Menu.qml
+++ b/src/activities/menu/Menu.qml
@@ -381,13 +381,13 @@ ActivityBase {
anchors.horizontalCenter: parent.horizontalCenter
sourceSize.height: iconHeight
anchors.margins: 5
- Image {
+ /*Image {
source: "qrc:/gcompris/src/core/resource/difficulty" +
ActivityInfoTree.menuTree[index].difficulty + \
".svg"; anchors.top: parent.top
sourceSize.width: iconWidth * 0.15
x: 5
- }
+ }*/
Image {
anchors {
horizontalCenter: parent.horizontalCenter
@@ -447,6 +447,29 @@ ActivityBase {
anchors.fill: activityBackground
onClicked: selectCurrentItem()
}
+
+ Rectangle {
+ id: rect
+ width: currentLevelField.width
+ height: currentLevelField.height
+ radius: 8
+ color: "lightgrey"
+ GCText {
+ id: currentLevelField
+ anchors.top: parent.top
+ width: iconWidth * 0.15
+ text: currentLevel
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ if(currentLevel == "") return;
+ dialogChooseLevel.currentActivity = \
ActivityInfoTree.menuTree[index] + \
dialogChooseLevel.chosenLevel = currentLevel; + \
displayDialog(dialogChooseLevel); + }
+ }
+ }
Image {
source: activity.url + (favorite ? "all.svg" : \
"all_disabled.svg"); anchors {
@@ -467,13 +490,25 @@ ActivityBase {
return
particles.burst(50)
ActivityInfoTree.currentActivity = \
ActivityInfoTree.menuTree[index]
- activityLoader.setSource("qrc:/gcompris/src/activities/" + \
ActivityInfoTree.menuTree[index].name, +
+ activityLoader.setSource("qrc:/gcompris/src/activities/" + \
ActivityInfoTree.currentActivity.name, {
'menu': activity,
- 'activityInfo': \
ActivityInfoTree.currentActivity + \
'activityInfo': ActivityInfoTree.currentActivity, + \
'levelFolder': currentLevel })
if (activityLoader.status == Loader.Ready) loadActivity()
}
+
+ DialogChooseLevel {
+ id: dialogChooseLevel
+ onClose: home()
+ onStop: {
+ currentLevel = dialogChooseLevel.chosenLevel
+ ApplicationSettings.setCurrentLevel(name, currentLevel)
+ }
+ }
+
}
highlight: Rectangle {
width: activityCellWidth - activitiesGrid.spacing
diff --git a/src/activities/reversecount/ActivityInfo.qml \
b/src/activities/reversecount/ActivityInfo.qml index 3e175a28..a238db0a 100644
--- a/src/activities/reversecount/ActivityInfo.qml
+++ b/src/activities/reversecount/ActivityInfo.qml
@@ -21,7 +21,7 @@ ActivityInfo {
name: "reversecount/Reversecount.qml"
difficulty: 2
icon: "reversecount/reversecount.svg"
- author: "Bruno Coudoin <bruno.coudoin@gcompris.net>"
+ author: "Emmanuel Charruau <echarruau@gmail.com>"
demo: false
//: Activity title
title: qsTr("Practice subtraction with a fun game")
@@ -37,4 +37,5 @@ ActivityInfo {
credit: ""
section: "math numeration"
createdInVersion: 0
+ levels: "1,2"
}
diff --git a/src/activities/reversecount/Reversecount.qml \
b/src/activities/reversecount/Reversecount.qml index 57259ecb..e686f1a8 100644
--- a/src/activities/reversecount/Reversecount.qml
+++ b/src/activities/reversecount/Reversecount.qml
@@ -51,6 +51,8 @@ ActivityBase {
id: items
property Item main: activity.main
property GCSfx audioEffects: activity.audioEffects
+ readonly property string resourceUrl: activity.resourceUrl
+ property var levels: activity.datasetLoader.item.data
property alias background: background
property alias backgroundImg: backgroundImg
property alias bar: bar
@@ -97,7 +99,7 @@ ActivityBase {
Image {
id: backgroundImg
- source: Activity.url + Activity.backgrounds[0]
+ source: activity.resourceUrl + Activity.backgrounds[0]
sourceSize.height: parent.height * 0.5
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
@@ -112,7 +114,7 @@ ActivityBase {
y: modelData[1] * (background.height- background.height/5) / 5
width: background.width / 5
height: background.height / 5
- source: Activity.url + "iceblock.svg"
+ source: activity.resourceUrl + "iceblock.svg"
}
}
@@ -197,8 +199,7 @@ ActivityBase {
}
PropertyAction {
target: clock; property: 'source';
- value: "qrc:/gcompris/src/activities/reversecount/resource/" +
- "flower" + items.clockPosition + ".svg"
+ value: activity.resourceUrl + "flower" + items.clockPosition + \
".svg" }
ParallelAnimation {
NumberAnimation {
@@ -228,5 +229,4 @@ ActivityBase {
onLoose: Activity.initLevel()
}
}
-
}
diff --git a/src/activities/reversecount/Tux.qml \
b/src/activities/reversecount/Tux.qml index b42d7081..a5ad55f7 100644
--- a/src/activities/reversecount/Tux.qml
+++ b/src/activities/reversecount/Tux.qml
@@ -27,7 +27,7 @@ import GCompris 1.0
Image {
id: tux
- source: Activity.url + "tux_top_south.svg"
+ source: activity.resourceUrl + "tux_top_south.svg"
fillMode: Image.PreserveAspectFit
z: 10
diff --git a/src/activities/reversecount/resource/1/Data.qml \
b/src/activities/reversecount/resource/1/Data.qml new file mode 100644
index 00000000..49633813
--- /dev/null
+++ b/src/activities/reversecount/resource/1/Data.qml
@@ -0,0 +1,49 @@
+/* GCompris - Data.qml
+ *
+ * Copyright (C) 2018 Johnny Jazeix <jazeix@gmail.com>
+ *
+ * Authors:
+ * Johnny Jazeix <jazeix@gmail.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+import "../../../../core"
+
+Dataset {
+ objective: qsTr("Numbers between 1 and 8")
+ data: [
+ {
+ "maxNumber": 1, /* Max number on each domino side */
+ "minNumber": 1,
+ "numberOfFish": 3
+ },
+ {
+ "maxNumber": 2,
+ "minNumber": 1,
+ "numberOfFish": 4
+ },
+ {
+ "maxNumber": 3,
+ "minNumber": 1,
+ "numberOfFish": 5
+ },
+ {
+ "maxNumber": 4,
+ "minNumber": 1,
+ "numberOfFish": 5
+ }
+ ]
+}
diff --git a/src/activities/reversecount/resource/2/Data.qml \
b/src/activities/reversecount/resource/2/Data.qml new file mode 100644
index 00000000..a790cd10
--- /dev/null
+++ b/src/activities/reversecount/resource/2/Data.qml
@@ -0,0 +1,54 @@
+/* GCompris - Data.qml
+ *
+ * Copyright (C) 2018 Johnny Jazeix <jazeix@gmail.com>
+ *
+ * Authors:
+ * Johnny Jazeix <jazeix@gmail.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+import "../../../../core"
+
+Dataset {
+ objective: qsTr("Numbers between 2 and 18")
+ data: [
+ {
+ "maxNumber": 5,
+ "minNumber": 2,
+ "numberOfFish": 5
+ },
+ {
+ "maxNumber": 6,
+ "minNumber": 3,
+ "numberOfFish": 5
+ },
+ {
+ "maxNumber": 7,
+ "minNumber": 4,
+ "numberOfFish": 5
+ },
+ {
+ "maxNumber": 8,
+ "minNumber": 4,
+ "numberOfFish": 5
+ },
+ {
+ "maxNumber": 9,
+ "minNumber": 5,
+ "numberOfFish": 5
+ }
+ ]
+}
diff --git a/src/activities/reversecount/reversecount.js \
b/src/activities/reversecount/reversecount.js index bb290df2..79622083 100644
--- a/src/activities/reversecount/reversecount.js
+++ b/src/activities/reversecount/reversecount.js
@@ -42,7 +42,6 @@ var backgrounds = [
var tuxIceBlockNumber = 0
var tuxIceBlockNumberGoal = 0
var tuxIsMoving = false;
-var debuginttmp = 0
var placeFishToReachBool = false
var level = null;
@@ -62,73 +61,20 @@ var fishes = [
"Fish02.svg"
]
-
-var levels = [
- {
- "maxNumber": 1, /* Max number on each domino side */
- "minNumber": 1,
- "numberOfFish": 3
- },
- {
- "maxNumber": 2,
- "minNumber": 1,
- "numberOfFish": 4
- },
- {
- "maxNumber": 3,
- "minNumber": 1,
- "numberOfFish": 5
- },
- {
- "maxNumber": 4,
- "minNumber": 1,
- "numberOfFish": 5
- },
- {
- "maxNumber": 5,
- "minNumber": 2,
- "numberOfFish": 5
- },
- {
- "maxNumber": 6,
- "minNumber": 3,
- "numberOfFish": 5
- },
- {
- "maxNumber": 7,
- "minNumber": 4,
- "numberOfFish": 5
- },
- {
- "maxNumber": 8,
- "minNumber": 4,
- "numberOfFish": 5
- },
- {
- "maxNumber": 9,
- "minNumber": 5,
- "numberOfFish": 5
- },
-
- ]
-
var numberOfFish
var fishIndex = -1
var currentLevel = 0
-var numberOfLevel = levels.length
+var numberOfLevel = 0
var items
-var url = "qrc:/gcompris/src/activities/reversecount/resource/"
-
-
function start(items_) {
items = items_
currentLevel = 0
+ numberOfLevel = items.levels.length
initLevel()
}
-
function stop() {
fishIndex = -1
}
@@ -138,8 +84,8 @@ function initLevel() {
items.chooseDiceBar.value1 = 0
items.chooseDiceBar.value2 = 0
- items.chooseDiceBar.valueMax = levels[currentLevel].maxNumber
- numberOfFish = levels[currentLevel].numberOfFish
+ items.chooseDiceBar.valueMax = items.levels[currentLevel].maxNumber
+ numberOfFish = items.levels[currentLevel].numberOfFish
fishIndex = 0
tuxIceBlockNumber = 0
@@ -148,11 +94,10 @@ function initLevel() {
calculateNextPlaceFishToReach()
placeFishToReach()
moveTuxToIceBlock()
- items.backgroundImg.source = url + backgrounds[currentLevel % \
backgrounds.length] + items.backgroundImg.source = items.resourceUrl + \
backgrounds[currentLevel % backgrounds.length] items.clockPosition = 4
}
-
function moveTux() {
calculateTuxIceBlockNextPos()
@@ -169,13 +114,12 @@ function moveTux() {
}
}
-
function moveTuxToNextIceBlock() {
- tuxIsMoving = false;
+ tuxIsMoving = false
tuxIceBlockNumber++
tuxIceBlockNumber = tuxIceBlockNumber % iceBlocksLayout.length
- if (tuxIceBlockNumber >= 0 && tuxIceBlockNumber <= 4)
+ if (tuxIceBlockNumber > 0 && tuxIceBlockNumber <= 4)
items.tux.rotation = -90
else if (tuxIceBlockNumber >= 5 && tuxIceBlockNumber <= 8)
items.tux.rotation = 0
@@ -205,7 +149,7 @@ function moveTuxToNextIceBlock() {
return
}
- items.audioEffects.play(url + 'icy_walk.wav')
+ items.audioEffects.play(items.resourceUrl + 'icy_walk.wav')
//if tux reaches its position + dice number before reaching the fish, \
calculation was wrong if (tuxIceBlockNumber == tuxIceBlockNumberGoal) {
items.clockPosition--
@@ -219,7 +163,6 @@ function moveTuxToNextIceBlock() {
tuxIsMoving = true
}
-
function moveTuxToIceBlock() {
items.tux.x = iceBlocksLayout[tuxIceBlockNumber % iceBlocksLayout.length][0] *
items.background.width / 5 +
@@ -229,10 +172,7 @@ function moveTuxToIceBlock() {
(items.background.height / 5 - items.tux.height) / 2
}
-
-
function tuxRunningChanged() {
-
if (tuxIsMoving) {
moveTuxToNextIceBlock()
} else {
@@ -243,7 +183,6 @@ function tuxRunningChanged() {
}
}
-
function calculateTuxIceBlockNextPos() {
tuxIceBlockNumberGoal = tuxIceBlockNumber +
items.chooseDiceBar.value1 + items.chooseDiceBar.value2
@@ -257,9 +196,9 @@ function calculateNextPlaceFishToReach() {
var newFishIndex
do {
newFishIndex = Math.floor(Math.random() *
- (levels[currentLevel].maxNumber * 2 -
- levels[currentLevel].minNumber + 1)) +
- levels[currentLevel].minNumber
+ (items.levels[currentLevel].maxNumber * 2 -
+ items.levels[currentLevel].minNumber + 1)) +
+ items.levels[currentLevel].minNumber
} while((previousFishIndex === newFishIndex) || (newFishIndex >= \
iceBlocksLayout.length)) previousFishIndex = newFishIndex
@@ -274,7 +213,7 @@ function placeFishToReach() {
else
items.fishToReach.opacity = 0
- items.fishToReach.nextSource = url + fishes[fishIndex % fishes.length]
+ items.fishToReach.nextSource = items.resourceUrl + fishes[fishIndex % \
fishes.length]
items.fishToReach.nextX = iceBlocksLayout[fishIndex % iceBlocksLayout.length][0] \
* items.background.width / 5 +
(items.background.width / 5 - items.tux.width) / 2
@@ -283,7 +222,6 @@ function placeFishToReach() {
(items.background.height / 5 - items.tux.height) / 2
}
-
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
@@ -305,4 +243,3 @@ function lost() {
function won() {
items.bonus.good("flower")
}
-
diff --git a/src/core/ActivityBase.qml b/src/core/ActivityBase.qml
index 21b1b3a4..8ce64ce8 100644
--- a/src/core/ActivityBase.qml
+++ b/src/core/ActivityBase.qml
@@ -122,6 +122,15 @@ Item {
*/
property Loading loading
+ /**
+ * type:string
+ * The resource folder for the current activity. The resources
+ * of each activity needs to be stored with the same pattern.
+ * "qrc:/gcompris/src/activities/" + activity name + "/resource/"
+ *
+ */
+ property string resourceUrl: (activityInfo && activityInfo.name) ? \
"qrc:/gcompris/src/activities/" + activityInfo.name.split('/')[0] + "/resource/": "" \
+ /**
* type: bool
* This variable stores if the activity is a musical activity.
@@ -130,6 +139,9 @@ Item {
*/
property bool isMusicalActivity: false
+ property alias datasetLoader: datasetLoader
+ property string levelFolder
+
/**
* Emitted when the user wants to return to the Home/Menu screen.
*/
@@ -232,4 +244,11 @@ Item {
anchors.fill: parent
active: !activityInfo.demo && ApplicationSettings.isDemoMode
}
+
+ Loader {
+ id: datasetLoader
+ asynchronous: false
+ source: resourceUrl + levelFolder + "/Data.qml"
+ active: levelFolder != ""
+ }
}
diff --git a/src/core/ActivityInfo.cpp b/src/core/ActivityInfo.cpp
index 4ced6da1..767a40b1 100644
--- a/src/core/ActivityInfo.cpp
+++ b/src/core/ActivityInfo.cpp
@@ -40,6 +40,7 @@ QString ActivityInfo::name() const
{
return m_name;
}
+
void ActivityInfo::setName(const QString &name)
{
m_name = name;
@@ -47,6 +48,9 @@ void ActivityInfo::setName(const QString &name)
// from the persistant configuration
if(!ApplicationSettings::getInstance()->isKioskMode())
m_favorite = ApplicationSettings::getInstance()->isFavorite(m_name);
+
+ setCurrentLevel();
+
emit nameChanged();
}
@@ -191,6 +195,42 @@ void ActivityInfo::setCreatedInVersion(const int created)
emit createdInVersionChanged();
}
+QStringList ActivityInfo::levels() const
+{
+ return m_levels;
+}
+
+void ActivityInfo::setLevels(const QStringList &levels)
+{
+ // levels only contains one element containing all the difficulties
+ m_levels = levels.front().split(',');
+
+ setCurrentLevel();
+
+ emit levelsChanged();
+}
+
+QString ActivityInfo::currentLevel() const
+{
+ return m_currentLevel;
+}
+
+void ActivityInfo::setCurrentLevel(const QString ¤tLevel)
+{
+ m_currentLevel = currentLevel;
+ emit currentLevelChanged();
+}
+
+void ActivityInfo::setCurrentLevel()
+{
+ if(!m_name.isEmpty()) {
+ if(!m_levels.empty() && \
ApplicationSettings::getInstance()->currentLevel(m_name) == "") { + \
ApplicationSettings::getInstance()->setCurrentLevel(m_name, m_levels[0]); + }
+ m_currentLevel = ApplicationSettings::getInstance()->currentLevel(m_name);
+ }
+}
+
QStringList ActivityInfo::getSectionPath()
{
QStringList path;
diff --git a/src/core/ActivityInfo.h b/src/core/ActivityInfo.h
index ea4fe094..b50a48be 100644
--- a/src/core/ActivityInfo.h
+++ b/src/core/ActivityInfo.h
@@ -39,14 +39,14 @@
*/
class ActivityInfo : public QObject
{
- Q_OBJECT
+ Q_OBJECT
- /**
- * Name of the main activity QML file.
- *
- * Example: "activity/Activity.qml"
- */
- Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+ /**
+ * Name of the main activity QML file.
+ *
+ * Example: "activity/Activity.qml"
+ */
+ Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
/**
* Section(s) this activity belongs to.
@@ -56,63 +56,63 @@ class ActivityInfo : public QObject
* computer, discovery, experiment, fun, math, puzzle,
* reading, strategy.
*/
- Q_PROPERTY(QString section READ section WRITE setSection NOTIFY sectionChanged)
+ Q_PROPERTY(QString section READ section WRITE setSection NOTIFY sectionChanged)
/**
* Difficulty of the activity.
*
* A difficulty level from 1 (easiest) to 6 (most difficult).
*/
- Q_PROPERTY(quint32 difficulty READ difficulty WRITE setDifficulty NOTIFY \
difficultyChanged) + Q_PROPERTY(quint32 difficulty READ difficulty WRITE \
setDifficulty NOTIFY difficultyChanged)
/**
* Relative path to the icon of the activity.
*
* Example: "activity/activity.svg"
*/
- Q_PROPERTY(QString icon READ icon WRITE setIcon NOTIFY iconChanged)
+ Q_PROPERTY(QString icon READ icon WRITE setIcon NOTIFY iconChanged)
/**
* Author of the activity.
*/
- Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged)
+ Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged)
/**
* Whether the activity is part of the demo version of GCompris.
*/
- Q_PROPERTY(bool demo READ demo WRITE setDemo NOTIFY demoChanged)
+ Q_PROPERTY(bool demo READ demo WRITE setDemo NOTIFY demoChanged)
/**
* Title of the activity.
*/
- Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
+ Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
/**
* Description of the activity.
*/
- Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY \
descriptionChanged) + Q_PROPERTY(QString description READ description WRITE \
setDescription NOTIFY descriptionChanged)
/**
* Goal that this activity wants to achieve.
*/
- Q_PROPERTY(QString goal READ goal WRITE setGoal NOTIFY goalChanged)
+ Q_PROPERTY(QString goal READ goal WRITE setGoal NOTIFY goalChanged)
- /**
+ /**
* Prerequisite for using this activity.
*/
- Q_PROPERTY(QString prerequisite READ prerequisite WRITE setPrerequisite NOTIFY \
prerequisiteChanged) + Q_PROPERTY(QString prerequisite READ prerequisite WRITE \
setPrerequisite NOTIFY prerequisiteChanged)
/**
* Manual describing the activity's usage.
*/
- Q_PROPERTY(QString manual READ manual WRITE setManual NOTIFY manualChanged)
+ Q_PROPERTY(QString manual READ manual WRITE setManual NOTIFY manualChanged)
/**
* Credits to third parties.
*/
- Q_PROPERTY(QString credit READ credit WRITE setCredit NOTIFY creditChanged)
+ Q_PROPERTY(QString credit READ credit WRITE setCredit NOTIFY creditChanged)
- Q_PROPERTY(bool favorite READ favorite WRITE setFavorite NOTIFY favoriteChanged)
+ Q_PROPERTY(bool favorite READ favorite WRITE setFavorite NOTIFY favoriteChanged)
/**
* This activity is enabled.
@@ -122,7 +122,17 @@ class ActivityInfo : public QObject
/**
* Version in which this activity has been created
*/
- Q_PROPERTY(int createdInVersion READ createdInVersion WRITE setCreatedInVersion \
NOTIFY createdInVersionChanged) + Q_PROPERTY(int createdInVersion READ \
createdInVersion WRITE setCreatedInVersion NOTIFY createdInVersionChanged) +
+ /**
+ * Contains a list of string defining the folder names for the different \
datasets. + */
+ Q_PROPERTY(QStringList levels READ levels WRITE setLevels NOTIFY levelsChanged)
+
+ /**
+ * Current dataset used for the activity (it is among the 'levels' list)
+ */
+ Q_PROPERTY(QString currentLevel READ currentLevel WRITE setCurrentLevel NOTIFY \
currentLevelChanged)
public:
/// @cond INTERNAL_DOCS
@@ -158,6 +168,10 @@ public:
void setEnabled(const bool);
int createdInVersion() const;
void setCreatedInVersion(const int);
+ QStringList levels() const;
+ void setLevels(const QStringList&);
+ QString currentLevel() const;
+ void setCurrentLevel(const QString&);
QStringList getSectionPath();
@@ -177,7 +191,8 @@ signals:
void favoriteChanged();
void enabledChanged();
void createdInVersionChanged();
-
+ void levelsChanged();
+ void currentLevelChanged();
/// @endcond
private:
QString m_name;
@@ -195,6 +210,13 @@ private:
bool m_favorite;
bool m_enabled;
int m_createdInVersion;
+ QStringList m_levels;
+ QString m_currentLevel;
+
+ /*
+ * Set current level once we have the name and the levels
+ */
+ void setCurrentLevel();
};
#endif // ACTIVITYINFO_H
diff --git a/src/core/ActivityInfoTree.cpp b/src/core/ActivityInfoTree.cpp
index 70e53dda..477cc7f8 100644
--- a/src/core/ActivityInfoTree.cpp
+++ b/src/core/ActivityInfoTree.cpp
@@ -83,20 +83,6 @@ ActivityInfo *ActivityInfoTree::getCurrentActivity() const
return m_currentActivity;
}
-ActivityInfo *ActivityInfoTree::getParentActivity(ActivityInfo *root, ActivityInfo \
*menu)
-{
- qDebug() << "Parent Path= " << menu->getSectionPath();
-
- Q_FOREACH( QObject *object, root->children() )
- {
- ActivityInfo *activityInfo = qobject_cast<ActivityInfo*>(object);
- if(activityInfo->section() == menu->section()) {
- return activityInfo;
- }
- }
- return m_menuTree.at(0);
-}
-
void ActivityInfoTree::menuTreeAppend(ActivityInfo *menu)
{
m_menuTreeFull.append(menu);
diff --git a/src/core/ActivityInfoTree.h b/src/core/ActivityInfoTree.h
index 733d1976..e8396be9 100644
--- a/src/core/ActivityInfoTree.h
+++ b/src/core/ActivityInfoTree.h
@@ -41,7 +41,6 @@ public:
ActivityInfo *menuTree(int) const;
void setCurrentActivity(ActivityInfo *currentActivity);
ActivityInfo *getCurrentActivity() const;
- ActivityInfo *getParentActivity(ActivityInfo *root, ActivityInfo *menu);
void menuTreeAppend(ActivityInfo *menu);
void menuTreeAppend(QQmlEngine *engine,
const QDir &menuDir, const QString &menuFile);
diff --git a/src/core/ApplicationSettings.cpp b/src/core/ApplicationSettings.cpp
index 8ae2296e..75b23011 100644
--- a/src/core/ApplicationSettings.cpp
+++ b/src/core/ApplicationSettings.cpp
@@ -44,6 +44,7 @@ static const QString GENERAL_GROUP_KEY = "General";
static const QString ADMIN_GROUP_KEY = "Admin";
static const QString INTERNAL_GROUP_KEY = "Internal";
static const QString FAVORITE_GROUP_KEY = "Favorite";
+static const QString LEVELS_GROUP_KEY = "Levels";
static const QString FULLSCREEN_KEY = "fullscreen";
static const QString PREVIOUS_HEIGHT_KEY = "previousHeight";
@@ -442,6 +443,19 @@ bool ApplicationSettings::isFavorite(const QString &activity)
return favorite;
}
+void ApplicationSettings::setCurrentLevel(const QString &activity, const QString \
&level) +{
+ updateValueInConfig(LEVELS_GROUP_KEY, activity, level);
+}
+
+QString ApplicationSettings::currentLevel(const QString &activity)
+{
+ m_config.beginGroup(LEVELS_GROUP_KEY);
+ QString level = m_config.value(activity, "").toString();
+ m_config.endGroup();
+ return level;
+}
+
template<class T> void ApplicationSettings::updateValueInConfig(const QString& \
group,
const QString& key, const T& value)
{
diff --git a/src/core/ApplicationSettings.h b/src/core/ApplicationSettings.h
index 6efff404..5cc7cbc7 100644
--- a/src/core/ApplicationSettings.h
+++ b/src/core/ApplicationSettings.h
@@ -54,6 +54,9 @@
* The <em>[Favorite]</em> group is auto-generated from the favorite activities
* selected by a user.
*
+ * The <em>[Levels]</em> group is auto-generated from the levels chosen by
+ * a user (if the activity provides multiple datasets).
+ *
* Besides these global settings there is one group for each activity that
* stores persistent settings.
*
@@ -409,14 +412,14 @@ public:
m_isDemoMode = !isBought;
emit demoModeChanged();
}
- }
+ }
bool sectionVisible() const { return m_sectionVisible; }
void setSectionVisible(const bool newMode) {
- qDebug() << "c++ setSectionVisible=" << newMode;
- m_sectionVisible = newMode;
- emit sectionVisibleChanged();
- }
+ qDebug() << "c++ setSectionVisible=" << newMode;
+ m_sectionVisible = newMode;
+ emit sectionVisibleChanged();
+ }
QString wordset() const { return m_wordset; }
void setWordset(const QString &newWordset) {
@@ -505,6 +508,9 @@ protected slots:
public slots:
Q_INVOKABLE bool isFavorite(const QString &activity);
Q_INVOKABLE void setFavorite(const QString &activity, bool favorite);
+ Q_INVOKABLE void setCurrentLevel(const QString &activity, const QString &level);
+ Q_INVOKABLE QString currentLevel(const QString &activity);
+
Q_INVOKABLE void saveBaseFontSize();
/// @endcond
diff --git a/src/core/Dataset.qml b/src/core/Dataset.qml
new file mode 100644
index 00000000..c2803e55
--- /dev/null
+++ b/src/core/Dataset.qml
@@ -0,0 +1,38 @@
+/* GCompris - Dataset.qml
+ *
+ * Copyright (C) 2018 Johnny Jazeix <jazeix@gmail.com>
+ *
+ * Authors:
+ * Johnny Jazeix <jazeix@gmail.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+
+/**
+ * Contains objective and data variable to instanciate new dataset.
+ * Each activity defines its own data format.
+ * @ingroup components
+ *
+ * Used by each activities wanting to provide multiple dataset along with
+ * their objectives.
+ *
+ */
+Item {
+ id: dataset
+
+ property string objective
+ property var data
+}
diff --git a/tests/core/ApplicationSettingsTest.cpp \
b/tests/core/ApplicationSettingsTest.cpp index bc5b5433..3a09759c 100644
--- a/tests/core/ApplicationSettingsTest.cpp
+++ b/tests/core/ApplicationSettingsTest.cpp
@@ -151,6 +151,11 @@ void CoreApplicationSettingsTest::ActivitySettingsTest()
applicationSettingsMock.saveActivityProgress(dummyActivity, 0);
QCOMPARE(applicationSettingsMock.loadActivityProgress(dummyActivity), 0);
+ // Test current level getter/setter
+ QCOMPARE(applicationSettingsMock.currentLevel(dummyActivity), "");
+ applicationSettingsMock.setCurrentLevel(dummyActivity, "3");
+ QCOMPARE(applicationSettingsMock.currentLevel(dummyActivity), "3");
+
// By Default the activity
QVariantMap configuration;
configuration.insert(QStringLiteral("DummyKey1"), \
QStringLiteral("DummyValue1"));
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic