Warning, /education/gcompris/src/core/DialogChooseLevel.qml is written in an unsupported language. File is not indexed.
0001 /* GCompris - DialogChooseLevel.qml
0002 *
0003 * SPDX-FileCopyrightText: 2018 Johnny Jazeix <jazeix@gmail.com>
0004 *
0005 * Authors:
0006 * Johnny Jazeix <jazeix@gmail.com>
0007 *
0008 * SPDX-License-Identifier: GPL-3.0-or-later
0009 */
0010 import QtQuick 2.12
0011 import GCompris 1.0
0012
0013 /**
0014 * todo
0015 * @ingroup components
0016 *
0017 * todo
0018 *
0019 * @sa ApplicationSettings
0020 * @inherit QtQuick.Item
0021 */
0022 Rectangle {
0023 id: dialogChooseLevel
0024 visible: false
0025 focus: visible
0026
0027 /* Public interface: */
0028
0029 /**
0030 * type:string
0031 * The name of the activity in case of per-activity config.
0032 *
0033 * Will be autogenerated unless set by the caller.
0034 */
0035 property string activityName: currentActivity.name.split('/')[0]
0036
0037 /// @cond INTERNAL_DOCS
0038
0039 property bool isDialog: true
0040
0041 /**
0042 * type:string
0043 * Title of the configuration dialog.
0044 */
0045 readonly property string title: currentActivity ? qsTr("%1 settings").arg(currentActivity.title) : ""
0046
0047 property var difficultiesModel: []
0048 property QtObject currentActivity
0049
0050 property var chosenLevels: []
0051
0052 property var activityData
0053 onActivityDataChanged: loadData()
0054 /// @endcond
0055
0056 /**
0057 * By default, we display configuration (this avoids to add code in each
0058 * activity to set it by default).
0059 */
0060 property bool displayDatasetAtStart: !hasConfig
0061
0062 /**
0063 * Emitted when the config dialog has been closed.
0064 */
0065 signal close
0066
0067 /**
0068 * Emitted when the config dialog has been started.
0069 */
0070 signal start
0071
0072 onStart: initialize()
0073
0074 signal stop
0075
0076 /**
0077 * Emitted when the settings are to be saved.
0078 *
0079 * The actual persisting of the settings in the settings file is done by
0080 * DialogActivityConfig. The activity has to take care to update its
0081 * internal state.
0082 */
0083 signal saveData
0084
0085 signal startActivity
0086
0087 /**
0088 * Emitted when the config settings have been loaded.
0089 */
0090 signal loadData
0091
0092 property bool datasetButtonVisible: true
0093 property bool hasConfigOrDataset: hasConfig || hasDataset
0094 property bool hasConfig: currentActivity && currentActivity.hasConfig
0095 property bool hasDataset: currentActivity && currentActivity.hasDataset && datasetButtonVisible
0096
0097 color: "#696da3"
0098
0099 property bool inMenu: false
0100
0101 onVisibleChanged: {
0102 if(visible) {
0103 configLoader.initializePanel()
0104 }
0105 }
0106
0107 Keys.onPressed: {
0108 if(event.key === Qt.Key_Down) {
0109 scrollItem.down();
0110 } else if(event.key === Qt.Key_Up) {
0111 scrollItem.up();
0112 } else if(event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
0113 if(saveAndStartButton.visible) {
0114 saveAndStartButton.clicked();
0115 } else {
0116 saveButton.clicked();
0117 }
0118 } else if(datasetVisibleButton.enabled && optionsVisibleButton.enabled &&
0119 (event.key === Qt.Key_Left || event.key === Qt.Key_Right)) {
0120 if(datasetVisibleButton.selected) {
0121 optionsVisibleButton.clicked();
0122 } else {
0123 datasetVisibleButton.clicked();
0124 }
0125 }
0126 }
0127
0128 Keys.onEscapePressed: {
0129 cancelButton.clicked();
0130 }
0131
0132 Keys.onReleased: {
0133 if(event.key === Qt.Key_Back) {
0134 cancelButton.clicked();
0135 event.accepted = true;
0136 }
0137 }
0138
0139 onClose: activity.forceActiveFocus();
0140
0141 function initialize() {
0142 // dataset information
0143 chosenLevels = currentActivity.currentLevels.slice()
0144 difficultiesModel = []
0145 for(var level in currentActivity.levels) {
0146 var data = currentActivity.getDataset(currentActivity.levels[level])
0147 difficultiesModel.push({
0148 "level": currentActivity.levels[level],
0149 "enabled": data.enabled,
0150 "objective": data.objective,
0151 "difficulty": data.difficulty,
0152 "selectedInConfig": (chosenLevels.indexOf(currentActivity.levels[level]) != -1)
0153 })
0154 }
0155 difficultiesRepeater.model = difficultiesModel
0156
0157 // Defaults to config if in an activity else to dataset if in menu
0158 if(displayDatasetAtStart) {
0159 datasetVisibleButton.clicked()
0160 }
0161 else {
0162 optionsVisibleButton.clicked()
0163 }
0164 }
0165
0166 Column {
0167 id: titleColumn
0168 spacing: 10
0169 anchors.top: parent.top
0170 anchors.topMargin: 15
0171 anchors.horizontalCenter: parent.horizontalCenter
0172 width: dialogChooseLevel.width - 30
0173 Rectangle {
0174 id: titleRectangle
0175 color: "#e6e6e6"
0176 radius: 10 * ApplicationInfo.ratio
0177 width: parent.width
0178 height: title.height + 10 * 2
0179
0180 GCText {
0181 id: title
0182 text: dialogChooseLevel.title
0183 width: titleColumn.width - 10
0184 anchors.horizontalCenter: titleRectangle.horizontalCenter
0185 anchors.verticalCenter: titleRectangle.verticalCenter
0186 horizontalAlignment: Text.AlignHCenter
0187 verticalAlignment: Text.AlignVCenter
0188 fontSize: 20
0189 font.weight: Font.DemiBold
0190 wrapMode: Text.WordWrap
0191 }
0192 }
0193
0194 // Header buttons
0195 Row {
0196 id: datasetOptionsRow
0197 height: dialogChooseLevel.height / 12
0198 width: titleRectangle.width
0199 spacing: titleRectangle.width * 0.1
0200 GCButton {
0201 id: datasetVisibleButton
0202 text: qsTr("Dataset")
0203 enabled: hasDataset
0204 height: parent.height
0205 width: titleRectangle.width * 0.45
0206 opacity: enabled ? 1 : 0
0207 theme: "settingsButton"
0208 selected: datasetVisibleButton.selected
0209 onClicked: { selected = true; }
0210 // reset the view to original position when changing tab
0211 onSelectedChanged: { flick.contentY = 0; }
0212 }
0213 GCButton {
0214 id: optionsVisibleButton
0215 text: qsTr("Options")
0216 enabled: hasConfig
0217 height: parent.height
0218 width: titleRectangle.width * 0.45
0219 opacity: enabled ? 1 : 0
0220 theme: "settingsButton"
0221 selected: !datasetVisibleButton.selected
0222 onClicked: { datasetVisibleButton.selected = false; } //showOptions()
0223 }
0224 }
0225
0226 // "Dataset"/"Options" content
0227 Rectangle {
0228 color: "#bdbed0"
0229 radius: 10 * ApplicationInfo.ratio
0230 width: dialogChooseLevel.width - 30
0231 height: dialogChooseLevel.height - (2 * parent.anchors.topMargin) - titleRectangle.height - datasetOptionsRow.height - saveAndPlayRow.height - (3 * parent.spacing)
0232 border.color: "white"
0233 border.width: 3 * ApplicationInfo.ratio
0234
0235 Flickable {
0236 id: flick
0237 flickDeceleration: 1500
0238 anchors.margins: 10 * ApplicationInfo.ratio
0239 anchors.fill: parent
0240 flickableDirection: Flickable.VerticalFlick
0241 clip: true
0242 contentHeight: contentItem.childrenRect.height + 40 * ApplicationInfo.ratio
0243
0244 Loader {
0245 id: configLoader
0246 visible: !datasetVisibleButton.selected
0247 active: optionsVisibleButton.enabled
0248 source: active ? "qrc:/gcompris/src/activities/"+activityName+"/ActivityConfig.qml" : ""
0249
0250 // Load configuration at start of activity
0251 // in the menu, it's done when the visibility property
0252 // of the dialog changes
0253 onItemChanged: if(!inMenu) { initializePanel(); }
0254
0255 function initializePanel() {
0256 if(item) {
0257 // only connect once the signal to save data
0258 if(item.background !== dialogChooseLevel) {
0259 item.background = dialogChooseLevel
0260 dialogChooseLevel.saveData.connect(save)
0261 }
0262 getInitialConfiguration()
0263 }
0264 }
0265 function getInitialConfiguration() {
0266 activityData = Qt.binding(function() { return item.dataToSave })
0267 if(item) {
0268 item.dataToSave = ApplicationSettings.loadActivityConfiguration(activityName)
0269 item.setDefaultValues()
0270 }
0271 }
0272 function save() {
0273 item.saveValues()
0274 ApplicationSettings.saveActivityConfiguration(activityName, item.dataToSave)
0275 }
0276 }
0277
0278 Column {
0279 visible: datasetVisibleButton.selected
0280 spacing: 10
0281
0282 Repeater {
0283 id: difficultiesRepeater
0284 delegate: Row {
0285 height: datasetVisibleButton.selected ? objective.height : 0
0286 visible: modelData.enabled
0287 spacing: 10
0288 Image {
0289 id: difficultyIcon
0290 source: "qrc:/gcompris/src/core/resource/difficulty" +
0291 modelData.difficulty + ".svg";
0292 sourceSize.height: objective.indicatorImageHeight
0293 sourceSize.width: height
0294 anchors.top: objective.top
0295 }
0296 GCDialogCheckBox {
0297 id: objective
0298 width: datasetOptionsRow.width - difficultyIcon.width - 2 * flick.anchors.margins - indicatorImageHeight
0299 text: modelData.objective
0300 checked: chosenLevels.indexOf(modelData.level) != -1
0301 onVisibleChanged: {
0302 if(visible) checked = (chosenLevels.indexOf(modelData.level) != -1)
0303 }
0304 onClicked: {
0305 if(checked) {
0306 chosenLevels.push(modelData.level)
0307 }
0308 else if(chosenLevels.length > 1) {
0309 chosenLevels.splice(chosenLevels.indexOf(modelData.level), 1)
0310 }
0311 else {
0312 // At least one must be selected
0313 checked = true;
0314 }
0315 }
0316 }
0317 }
0318 }
0319 }
0320 }
0321
0322 // The scroll buttons
0323 GCButtonScroll {
0324 id: scrollItem
0325 anchors.right: parent.right
0326 anchors.rightMargin: 5 * ApplicationInfo.ratio
0327 anchors.bottom: flick.bottom
0328 anchors.bottomMargin: 5 * ApplicationInfo.ratio
0329 onUp: flick.flick(0, 1000)
0330 onDown: flick.flick(0, -1000)
0331 upVisible: flick.atYBeginning ? false : true
0332 downVisible: flick.atYEnd ? false : true
0333 }
0334 }
0335 // Footer buttons
0336 Row {
0337 id: saveAndPlayRow
0338 height: dialogChooseLevel.height / 12
0339 width: titleRectangle.width
0340 spacing: titleRectangle.width * 0.05
0341 GCButton {
0342 id: cancelButton
0343 text: qsTr("Cancel")
0344 height: parent.height
0345 width: titleRectangle.width * 0.25
0346 theme: "settingsButton"
0347 onClicked: close();
0348 }
0349 GCButton {
0350 id: saveButton
0351 text: qsTr("Save")
0352 height: parent.height
0353 width: titleRectangle.width * 0.25
0354 theme: "settingsButton"
0355 onClicked: {
0356 saveData();
0357 if (inMenu === false) {
0358 startActivity();
0359 }
0360 close();
0361 }
0362 }
0363 GCButton {
0364 id: saveAndStartButton
0365 text: qsTr("Save and start")
0366 height: parent.height
0367 width: titleRectangle.width * 0.4
0368 visible: inMenu === true
0369 theme: "settingsButton"
0370 onClicked: {
0371 saveData();
0372 startActivity();
0373 }
0374 }
0375 }
0376 }
0377 }