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

0001 /* GCompris - Babymatch.qml
0002  *
0003  * SPDX-FileCopyrightText: 2015 Pulkit Gupta <pulkitgenius@gmail.com>
0004  *
0005  * Authors:
0006  *   Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
0007  *   Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
0008  *
0009  *   SPDX-License-Identifier: GPL-3.0-or-later
0010  */
0011 import QtQuick 2.12
0012 import GCompris 1.0
0013 
0014 import "../../core"
0015 import "babymatch.js" as Activity
0016 
0017 ActivityBase {
0018     id: activity
0019 
0020     // In most cases, these 3 are the same.
0021     // But for imageName for example, we reuse the images of babymatch, so we need to differentiate them
0022     property string imagesUrl: boardsUrl
0023     property string soundsUrl: boardsUrl
0024     property bool useMultipleDataset: false
0025     property string boardsUrl: "qrc:/gcompris/src/activities/babymatch/resource/"
0026     property int levelCount: 7
0027     property bool answerGlow: true      //For highlighting the answers
0028     property bool displayDropCircle: true       //For displaying drop circles
0029 
0030     onStart: focus = true;
0031     onStop: {}
0032 
0033     pageComponent: Image {
0034         id: background
0035         anchors.fill: parent
0036         source: "qrc:/gcompris/src/activities/guesscount/resource/backgroundW01.svg" 
0037 
0038         signal start
0039         signal stop
0040 
0041         property bool verticalBar: background.width >= background.height
0042 
0043         Component.onCompleted: {
0044             dialogActivityConfig.initialize();
0045             activity.start.connect(start);
0046             activity.stop.connect(stop);
0047         }
0048 
0049         // Add here the QML items you need to access in javascript
0050         QtObject {
0051             id: items
0052             property alias background: background
0053             property int currentLevel: activity.currentLevel
0054             property alias bonus: bonus
0055             property alias availablePieces: availablePieces
0056             property alias backgroundPiecesModel: backgroundPiecesModel
0057             property alias grid: grid
0058             property alias backgroundImageSource: backgroundImageSource
0059             property alias backgroundImage: backgroundImage
0060             property alias leftWidget: leftWidget
0061             property alias instruction: instruction
0062             property alias toolTip: toolTip
0063             property alias score: score
0064             readonly property var levels: activity.datasetLoader.data.length !== 0 ? activity.datasetLoader.data : null
0065             property alias dataset: dataset
0066             property bool inputLocked: false
0067             // same formula used to define dropCircle size, here to define a minimum MouseArea
0068             // size for dropped items if they are smaller than the circles.
0069             property double minimumClickArea: backgroundImage.width >= backgroundImage.height ? backgroundImage.height/35 : backgroundImage.width/35
0070         }
0071 
0072         Loader {
0073             id: dataset
0074             asynchronous: false
0075         }
0076 
0077         onStart: { Activity.start(items, imagesUrl, soundsUrl, boardsUrl, levelCount, answerGlow, displayDropCircle, useMultipleDataset); }
0078         onStop: { Activity.stop(); }
0079 
0080         DialogHelp {
0081             id: dialogHelp
0082             onClose: home();
0083         }
0084 
0085         Bar {
0086             id: bar
0087             level: items.currentLevel + 1
0088             content: BarEnumContent { value: useMultipleDataset ? (help | home | level | activityConfig) : (help | home | level) }
0089             onHelpClicked: displayDialog(dialogHelp);
0090             onPreviousLevelClicked: Activity.previousLevel();
0091             onNextLevelClicked: Activity.nextLevel();
0092             onHomeClicked: {
0093                 Activity.resetData();
0094                 activity.home();
0095             }
0096             onActivityConfigClicked: {
0097                 Activity.initLevel();
0098                 displayDialog(dialogActivityConfig);
0099              }
0100         }
0101 
0102         DialogChooseLevel {
0103             id: dialogActivityConfig
0104             currentActivity: activity.activityInfo
0105             onSaveData: {
0106                 levelFolder = dialogActivityConfig.chosenLevels;
0107                 currentActivity.currentLevels = dialogActivityConfig.chosenLevels;
0108                 ApplicationSettings.setCurrentLevels(currentActivity.name, dialogActivityConfig.chosenLevels);
0109                 activity.focus = true;
0110             }
0111             onLoadData: {
0112                 if(activityData) {
0113                     Activity.initLevel();
0114                 }
0115             }
0116             onClose: {
0117                 home();
0118             }
0119             onStartActivity: {
0120                 background.start();
0121             }
0122         }
0123 
0124         Score {
0125             id: score
0126             visible: numberOfSubLevels > 1
0127             anchors.right: parent.right
0128             anchors.rightMargin: 10 * ApplicationInfo.ratio
0129             anchors.bottom: bar.top
0130         }
0131 
0132         Bonus {
0133             id: bonus
0134             Component.onCompleted: win.connect(Activity.nextSubLevel);
0135         }
0136 
0137         Image {
0138             id: leftWidget
0139             source: "qrc:/gcompris/src/activities/guesscount/resource/backgroundW02.svg"
0140             width: background.verticalBar ?
0141                        90 * ApplicationInfo.ratio :
0142                        background.width
0143             height: background.verticalBar ?
0144                         background.height :
0145                         90 * ApplicationInfo.ratio
0146             anchors.left: parent.left
0147             ListWidget {
0148                 id: availablePieces
0149             }
0150             MouseArea {
0151                 anchors.fill: parent
0152                 enabled: !items.inputLocked
0153                 onPressed: instruction.opacity === 0 ? instruction.show() : instruction.hide();
0154             }
0155         }
0156 
0157         Rectangle {
0158             id: toolTip
0159             anchors {
0160                 bottom: bar.top
0161                 bottomMargin: 10
0162                 left: leftWidget.left
0163                 leftMargin: 5
0164             }
0165             width: toolTipTxt.width + 10
0166             height: toolTipTxt.height + 5
0167             opacity: 1
0168             radius: 10
0169             z: 100
0170             color: "#E8E8E8"
0171             property alias text: toolTipTxt.text
0172             Behavior on opacity { NumberAnimation { duration: 120 } }
0173 
0174             function show(newText) {
0175                 if(newText) {
0176                     text = newText;
0177                     opacity = 0.8;
0178                 } else {
0179                     opacity = 0;
0180                 }
0181             }
0182 
0183             Rectangle {
0184                 width: parent.width - anchors.margins
0185                 height: parent.height - anchors.margins
0186                 anchors.verticalCenter: parent.verticalCenter
0187                 anchors.horizontalCenter: parent.horizontalCenter
0188                 anchors.margins: parent.height/8
0189                 radius: 10
0190                 color: "#87A6DD"  //light blue
0191             }
0192 
0193             Rectangle {
0194                 width: parent.width - anchors.margins
0195                 height: parent.height - anchors.margins
0196                 anchors.verticalCenter: parent.verticalCenter
0197                 anchors.horizontalCenter: parent.horizontalCenter
0198                 anchors.margins: parent.height/4
0199                 radius: 10
0200                 color: "#E8E8E8" //paper white
0201             }
0202 
0203             GCText {
0204                 id: toolTipTxt
0205                 anchors.centerIn: parent
0206                 fontSize: regularSize
0207                 color: "#373737"
0208                 horizontalAlignment: Text.AlignHCenter
0209                 wrapMode: TextEdit.WordWrap
0210             }
0211         }
0212 
0213         Rectangle {
0214             id: grid
0215 
0216             color: "transparent"
0217             z: 2
0218             x: background.verticalBar ? 90 * ApplicationInfo.ratio : 0
0219             y: background.verticalBar ? 0 : 90 * ApplicationInfo.ratio
0220             width: background.verticalBar ?
0221                        background.width - 90 * ApplicationInfo.ratio : background.width
0222             height: background.verticalBar ?
0223                         background.height - (bar.height * 1.1) :
0224                         background.height - (bar.height * 1.1) - 90 * ApplicationInfo.ratio
0225 
0226             // We need two items for the background image:
0227             // - backgroundImageSource is needed to keep the original sourceSize info which is used
0228             // in calculations, and to load quickly the image on startup;
0229             // - backgroundImage is used for the "clean" render of the image,
0230             // with its sourceSize linked to the actual size to get perfect svg rendering,
0231             // but as it can be slow on heavy maps we load this one asynchronously.
0232             Image {
0233                 id: backgroundImageSource
0234                 source: ""
0235                 fillMode: Image.PreserveAspectFit
0236                 anchors.centerIn: parent
0237                 property double ratio: sourceSize.width / sourceSize.height
0238                 property double gridRatio: grid.width / grid.height
0239                 // shrink size by 2 pixels to make sure it is always perfectly hidden by backgroundImage
0240                 width: (source == "" ? grid.width :
0241                         (ratio > gridRatio ? grid.width : grid.height * ratio)) - 2
0242                 height: (source == "" ? grid.height :
0243                         (ratio < gridRatio ? grid.height : grid.width / ratio)) - 2
0244             }
0245 
0246             Image {
0247                 id: backgroundImage
0248                 fillMode: Image.PreserveAspectFit
0249                 source: backgroundImageSource.source
0250                 z: 2
0251                 width: backgroundImageSource.width + 2
0252                 height: backgroundImageSource.height + 2
0253                 sourceSize.width: width
0254                 sourceSize.height: height
0255                 anchors.centerIn: parent
0256                 asynchronous: true
0257 
0258                 //Inserting static background images
0259                 Repeater {
0260                     id: backgroundPieces
0261                     model: backgroundPiecesModel
0262                     delegate: piecesDelegate
0263                     z: 2
0264 
0265                     Component {
0266                         id: piecesDelegate
0267                         Image {
0268                             id: shapeBackground
0269                             source: Activity.imagesUrl + imgName
0270                             x: posX * backgroundImage.width - width / 2
0271                             y: posY * backgroundImage.height - height / 2
0272 
0273                             height:
0274                                 imgHeight ?
0275                                     imgHeight * backgroundImage.height :
0276                                     (backgroundImage.source == "" ?
0277                                          backgroundImage.height * sourceShape.sourceSize.height / backgroundImage.height :
0278                                          backgroundImage.height * sourceShape.sourceSize.height /
0279                                          backgroundImageSource.sourceSize.height)
0280 
0281                             width:
0282                                 imgWidth ?
0283                                     imgWidth * backgroundImage.width :
0284                                     (backgroundImage.source == "" ?
0285                                          backgroundImage.width * sourceShape.sourceSize.width / backgroundImage.width :
0286                                          backgroundImage.width * sourceShape.sourceSize.width /
0287                                          backgroundImageSource.sourceSize.width)
0288 
0289                             sourceSize.width: width
0290                             sourceSize.height: height
0291                             fillMode: Image.PreserveAspectFit
0292                             Image {
0293                                 id: sourceShape
0294                                 anchors.centerIn: parent
0295                                 source: Activity.imagesUrl + imgName
0296                                 visible: false
0297                             }
0298                         }
0299                     }
0300                 }
0301 
0302                 MouseArea {
0303                     anchors.fill: parent
0304                     enabled: !items.inputLocked
0305                     onPressed: instruction.opacity === 0 ? instruction.show() : instruction.hide();
0306                 }
0307             }
0308         }
0309 
0310         Rectangle {
0311             id: instruction
0312             anchors.horizontalCenter: instructionTxt.horizontalCenter
0313             anchors.verticalCenter: instructionTxt.verticalCenter
0314             width: instructionTxt.width + 40
0315             height: instructionTxt.height + 40
0316             opacity: 0.8
0317             radius: 10
0318             z: 3
0319             color: "#87A6DD"  //light blue
0320             property alias text: instructionTxt.text
0321 
0322             Behavior on opacity { PropertyAnimation { duration: 200 } }
0323 
0324             function show() {
0325                 if(text)
0326                     opacity = 1;
0327             }
0328             function hide() {
0329                 opacity = 0;
0330             }
0331 
0332             Rectangle {
0333                 id: insideFill
0334                 width: parent.width - anchors.margins
0335                 height: parent.height - anchors.margins
0336                 anchors.verticalCenter: parent.verticalCenter
0337                 anchors.horizontalCenter: parent.horizontalCenter
0338                 anchors.margins: parent.height / 8
0339                 radius: 10
0340                 color: "#E8E8E8" //paper white
0341             }
0342         }
0343 
0344         GCText {
0345             id: instructionTxt
0346             anchors {
0347                 top: background.verticalBar ? grid.top : leftWidget.bottom
0348                 topMargin:  20
0349                 horizontalCenter: background.verticalBar ? grid.horizontalCenter : leftWidget.horizontalCenter
0350             }
0351             opacity: instruction.opacity
0352             z: instruction.z
0353             fontSize: regularSize
0354             color: "#373737"
0355             horizontalAlignment: Text.AlignHCenter
0356             width: Math.max(Math.min(parent.width * 0.7, text.length * 10), parent.width * 0.3)
0357             wrapMode: TextEdit.WordWrap
0358         }
0359 
0360 
0361         ListModel {
0362             id: backgroundPiecesModel
0363         }
0364 
0365         Item {
0366             id: movePlaceholder
0367             z: 1000
0368             anchors.fill: background
0369         }
0370     }
0371 }