Warning, /education/gcompris/src/activities/adjacent_numbers/Adjacent_numbers.qml is written in an unsupported language. File is not indexed.

0001 /* GCompris - Adjacent_numbers.qml
0002  *
0003  * SPDX-FileCopyrightText: 2023 Alexandre Laurent <littlewhite.dev@gmail.com>
0004  * SPDX-FileCopyrightText: 2024 Timothée Giet <animtim@gmail.com>
0005  * SPDX-License-Identifier: GPL-3.0-or-later
0006  */
0007 import QtQuick 2.12
0008 import QtQml.Models 2.12
0009 
0010 import GCompris 1.0
0011 import "../../core"
0012 import "adjacent_numbers.js" as Activity
0013 import "qrc:/gcompris/src/core/core.js" as Core
0014 
0015 ActivityBase {
0016     id: activity
0017 
0018     onStart: focus = true
0019     onStop: {}
0020 
0021     pageComponent: Image {
0022         id: background
0023         source: "qrc:/gcompris/src/activities/chess/resource/background-wood.svg"
0024         anchors.fill: parent
0025         fillMode: Image.PreserveAspectCrop
0026         sourceSize.height: height
0027         signal start
0028         signal stop
0029 
0030         Component.onCompleted: {
0031             activity.start.connect(start)
0032             activity.stop.connect(stop)
0033         }
0034 
0035         QtObject {
0036             id: items
0037             property Item main: activity.main
0038             // UI elements
0039             property alias background: background
0040             property alias instruction: instruction
0041             property alias bar: bar
0042             property alias bonus: bonus
0043             property alias score: score
0044             property alias questionTilesModel: questionTilesModel
0045             property alias questionTilesFlow: questionTilesFlow
0046             property alias proposedTilesModel: proposedTilesModel
0047             property GCSfx audioEffects: activity.audioEffects
0048 
0049             // Activity options
0050             property bool randomSubLevels: true // not presented to the user
0051             property bool immediateAnswer: true
0052 
0053             // Updated by JS
0054             property bool answerCompleted: false
0055             property bool buttonsEnabled: true
0056 
0057             readonly property var levels: activity.datasetLoader.data.length !== 0 ? activity.datasetLoader.data : null
0058         }
0059         property int baseMargins: 10 * ApplicationInfo.ratio
0060 
0061         onStart: { Activity.start(items) }
0062         onStop: { Activity.stop() }
0063 
0064         Rectangle {
0065             id: instructionArea
0066             opacity: 1
0067             radius: background.baseMargins
0068             color: "#373737"
0069             height: 40 * ApplicationInfo.ratio
0070             width: Math.min(320 * ApplicationInfo.ratio, parent.width - 2 * background.baseMargins)
0071             anchors.horizontalCenter: parent.horizontalCenter
0072             anchors.top: parent.top
0073             anchors.topMargin: background.baseMargins
0074 
0075             GCText {
0076                 id: instruction
0077                 wrapMode: TextEdit.WordWrap
0078                 horizontalAlignment: Text.AlignHCenter
0079                 verticalAlignment: Text.AlignVCenter
0080                 height: parent.height - background.baseMargins
0081                 width: parent.width - 2 * background.baseMargins
0082                 fontSizeMode: Text.Fit
0083                 color: 'white'
0084                 anchors.centerIn: instructionArea
0085             }
0086         }
0087 
0088         Item {
0089             id: layoutArea
0090             anchors.top: instructionArea.bottom
0091             anchors.bottom: okButton.top
0092             anchors.left: background.left
0093             anchors.right: background.right
0094             anchors.margins: background.baseMargins
0095         }
0096 
0097         Item {
0098             id: questionArea
0099             z: 100
0100             anchors.top: layoutArea.top
0101             anchors.topMargin: background.baseMargins
0102             anchors.horizontalCenter: layoutArea.horizontalCenter
0103             width: layoutArea.width - background.baseMargins * 2
0104             height: (layoutArea.height  - background.baseMargins * 3) * 0.5
0105             property int tileSize: Core.fitItems(questionArea.width, questionArea.height, questionTilesModel.count) - background.baseMargins
0106 
0107             Rectangle {
0108                 anchors.centerIn: parent
0109                 width: questionTilesFlow.childrenRect.width + background.baseMargins
0110                 height: questionTilesFlow.childrenRect.height + background.baseMargins
0111                 color: "#80FFFFFF"
0112                 radius: height * 0.1
0113             }
0114 
0115             Item {
0116                 anchors.centerIn: parent
0117                 anchors.verticalCenterOffset: background.baseMargins * 0.5
0118                 anchors.horizontalCenterOffset: anchors.verticalCenterOffset
0119                 width: questionTilesFlow.childrenRect.width + background.baseMargins
0120                 height: questionTilesFlow.childrenRect.height + background.baseMargins
0121                 DelegateModel {
0122                     id: questionTilesDelegateModel
0123                     model: ListModel {
0124                         id: questionTilesModel
0125                     }
0126                     delegate: DroppableTile {
0127                         width: Math.max(1, questionArea.tileSize)
0128                         onTileChanged: (newValue) => {
0129                             Activity.updatePupilAnswer(index, newValue)
0130                         }
0131                     }
0132                 }
0133 
0134                 Flow {
0135                     id: questionTilesFlow
0136                     width: questionArea.width
0137                     height: questionArea.height
0138                     spacing: background.baseMargins
0139 
0140                     Repeater {
0141                         model: questionTilesDelegateModel
0142                     }
0143                 }
0144             }
0145         }
0146 
0147         Item {
0148             id: proposedTilesArea
0149             z: 200
0150             anchors.bottom: layoutArea.bottom
0151             anchors.bottomMargin: background.baseMargins
0152             anchors.horizontalCenter: layoutArea.horizontalCenter
0153             height: questionArea.height
0154             width: questionArea.width
0155 
0156             property int tileSize: Core.fitItems(proposedTilesArea.width, proposedTilesArea.height, proposedTilesModel.count) - background.baseMargins
0157 
0158             Item {
0159                 anchors.centerIn: parent
0160                 width: proposedTilesFlow.childrenRect.width
0161                 height: proposedTilesFlow.childrenRect.height
0162                 DelegateModel {
0163                     id: proposedTilesDelegateModel
0164                     model: ListModel {
0165                         id: proposedTilesModel
0166                     }
0167                     delegate: DraggableTile {
0168                         width: Math.max(1, proposedTilesArea.tileSize)
0169                     }
0170                 }
0171 
0172                 Flow {
0173                     id: proposedTilesFlow
0174                     width: proposedTilesArea.width
0175                     height: proposedTilesArea.height
0176                     spacing: background.baseMargins
0177 
0178                     Repeater {
0179                         model: proposedTilesDelegateModel
0180                     }
0181                 }
0182             }
0183         }
0184 
0185         DialogHelp {
0186             id: dialogHelp
0187             onClose: home()
0188         }
0189 
0190         Score {
0191             id: score
0192             anchors.top: undefined
0193             anchors.bottom: background.bottom
0194             anchors.bottomMargin: bar.height * 1.5
0195             anchors.right: background.right
0196             anchors.rightMargin: background.baseMargins
0197             currentSubLevel: 0
0198             numberOfSubLevels: 10
0199             onStop: {
0200                 Activity.nextSubLevel();
0201             }
0202         }
0203 
0204         BarButton {
0205             id: okButton
0206             anchors.right: score.left
0207             anchors.rightMargin: background.baseMargins
0208             anchors.verticalCenter: score.verticalCenter
0209             source: "qrc:/gcompris/src/core/resource/bar_ok.svg"
0210             width: 70 * ApplicationInfo.ratio
0211             height: width
0212             sourceSize.height: width
0213             sourceSize.width: width
0214             onClicked: validateKey();
0215             enabled: visible && items.buttonsEnabled
0216             visible: !items.immediateAnswer && items.answerCompleted
0217         }
0218 
0219         Bar {
0220             id: bar
0221             content: BarEnumContent { value: help | home | level | activityConfig }
0222             onHelpClicked: {
0223                 displayDialog(dialogHelp)
0224             }
0225             onPreviousLevelClicked: Activity.previousLevel()
0226             onNextLevelClicked: Activity.nextLevel()
0227             onHomeClicked: activity.home()
0228             onActivityConfigClicked: {
0229                 displayDialog(dialogActivityConfig)
0230             }
0231         }
0232 
0233         Bonus {
0234             id: bonus
0235             Component.onCompleted: win.connect(Activity.nextLevel)
0236         }
0237 
0238         DialogChooseLevel {
0239             id: dialogActivityConfig
0240             currentActivity: activity.activityInfo
0241 
0242             onClose: home()
0243 
0244             onLoadData: {
0245                 if(activityData && activityData["answerMode"]) {
0246                     items.immediateAnswer = activityData["answerMode"] == 1
0247                 }
0248             }
0249 
0250             onSaveData: {
0251                 levelFolder = dialogActivityConfig.chosenLevels
0252                 currentActivity.currentLevels = dialogActivityConfig.chosenLevels
0253                 ApplicationSettings.setCurrentLevels(currentActivity.name, dialogActivityConfig.chosenLevels)
0254             }
0255 
0256             onStartActivity: {
0257                 background.stop()
0258                 background.start()
0259             }
0260         }
0261 
0262         Keys.onReturnPressed: validateKey();
0263 
0264         Keys.onEnterPressed: validateKey();
0265 
0266         function validateKey() {
0267             if(okButton.enabled) {
0268                 Activity.checkAnswer();
0269             }
0270         }
0271 
0272         SequentialAnimation {
0273             id: okButtonAnimation
0274             running: false
0275             NumberAnimation { target: okButton; property: "scale"; to: 0.9; duration: 70 }
0276             NumberAnimation { target: okButton; property: "scale"; to: 1; duration: 70 }
0277         }
0278     }
0279 }