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

0001 /* GCompris - redraw.qml
0002  *
0003  * SPDX-FileCopyrightText: 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
0004  *
0005  * Authors:
0006  *   Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
0007  *   Bruno Coudoin <bruno.coudoin@gcompris.net> (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 import QtGraphicalEffects 1.0
0014 
0015 import "../../core"
0016 import "redraw.js" as Activity
0017 
0018 ActivityBase {
0019     id: activity
0020 
0021     onStart: focus = true
0022     onStop: {}
0023 
0024     property bool symmetry: false
0025 
0026     pageComponent: Image {
0027         id: background
0028         anchors.fill: parent
0029         source: Activity.url + "background.svg"
0030         fillMode: Image.PreserveAspectCrop
0031         sourceSize.width: width
0032         sourceSize.height: height
0033 
0034         property bool landscape: width >= height
0035         property int areaWidth: landscape ? (width - colorSelectorFlick.width) / 2 - 20 :
0036                                             width - colorSelectorFlick.width - 20
0037         property int areaHeight: landscape ? height - bar.height * 1.2 - 20:
0038                                              (height - bar.height * 1.2) / 2 - 20
0039         property int cellSize: Math.min(areaWidth / items.numberOfColumn,
0040                                         areaHeight / items.numberOfLine)
0041         signal start
0042         signal stop
0043 
0044         Component.onCompleted: {
0045             dialogActivityConfig.initialize()
0046             activity.start.connect(start)
0047             activity.stop.connect(stop)
0048         }
0049 
0050         // Add here the QML items you need to access in javascript
0051         QtObject {
0052             id: items
0053             property Item main: activity.main
0054             property alias background: background
0055             property int currentLevel: activity.currentLevel
0056             property alias bonus: bonus
0057             property alias checkTimer: checkTimer
0058             property int colorSelector: 0
0059             property alias userModel: userModel
0060             property int numberOfColumn
0061             property int numberOfColor
0062             property int numberOfLine: targetModelData.length / numberOfColumn
0063             property alias targetModel: targetModel
0064             property var targetModelData
0065             readonly property var levels: activity.datasetLoader.data.length !== 0 ? activity.datasetLoader.data : null
0066             property bool buttonsBlocked: false
0067         }
0068 
0069         onStart: { Activity.start(items) }
0070         onStop: {
0071             checkTimer.stop()
0072             Activity.stop()
0073         }
0074 
0075         Keys.enabled: !items.buttonsBlocked
0076         Keys.onPressed: {
0077             if(event.key >= Qt.Key_0 && event.key < Qt.Key_0 + items.numberOfColor)
0078                 items.colorSelector = event.key - Qt.Key_0
0079 
0080             if(event.key === Qt.Key_Backspace)
0081                 userModel.clearCurrentItem()
0082         }
0083         Keys.onEnterPressed: userModel.paintCurrentItem()
0084         Keys.onReturnPressed: userModel.paintCurrentItem()
0085         Keys.onSpacePressed: userModel.paintCurrentItem()
0086         Keys.onDeletePressed: userModel.clearCurrentItem()
0087         Keys.onRightPressed: userModel.moveCurrentIndexRight()
0088         Keys.onLeftPressed: userModel.moveCurrentIndexLeft()
0089         Keys.onDownPressed: userModel.moveCurrentIndexDown()
0090         Keys.onUpPressed: userModel.moveCurrentIndexUp()
0091         // For creating new content, dump the drawing on the console
0092         Keys.onTabPressed: Activity.dump()
0093 
0094         Row {
0095             anchors {
0096                 top: parent.top
0097                 right: parent.right
0098                 left: parent.left
0099                 bottom: bar.top
0100             }
0101             anchors.margins: 10
0102             spacing: 20
0103 
0104             // The color selector
0105             Flickable {
0106                 id: colorSelectorFlick
0107                 interactive: true
0108                 width: height / 7
0109                 height: background.height - bar.height * 1.2
0110                 boundsBehavior: Flickable.StopAtBounds
0111                 contentHeight: items.numberOfColor * width
0112                 Column {
0113                     id: colorSelector
0114                     Repeater {
0115                         model: items.numberOfColor
0116                         Item {
0117                             width: colorSelectorFlick.width
0118                             height: width
0119                             Image {
0120                                 id: img
0121                                 source: Activity.url + Activity.colorShortcut[modelData] + ".svg"
0122                                 sourceSize.width: colorSelectorFlick.width
0123                                 z: iAmSelected ? 10 : 1
0124 
0125                                 property bool iAmSelected: modelData == items.colorSelector
0126 
0127                                 states: [
0128                                     State {
0129                                         name: "notclicked"
0130                                         when: !img.iAmSelected && !mouseArea.containsMouse
0131                                         PropertyChanges {
0132                                             target: img
0133                                             scale: 0.8
0134                                         }
0135                                     },
0136                                     State {
0137                                         name: "clicked"
0138                                         when: mouseArea.pressed
0139                                         PropertyChanges {
0140                                             target: img
0141                                             scale: 0.7
0142                                         }
0143                                     },
0144                                     State {
0145                                         name: "hover"
0146                                         when: mouseArea.containsMouse && !img.iAmSelected
0147                                         PropertyChanges {
0148                                             target: img
0149                                             scale: 1
0150                                         }
0151                                     },
0152                                     State {
0153                                         name: "selected"
0154                                         when: img.iAmSelected
0155                                         PropertyChanges {
0156                                             target: img
0157                                             scale: 1.1
0158                                         }
0159                                     }
0160                                 ]
0161 
0162                                 Behavior on scale { NumberAnimation { duration: 70 } }
0163                                 MouseArea {
0164                                     id: mouseArea
0165                                     anchors.fill: parent
0166                                     hoverEnabled: true
0167                                     onClicked: {
0168                                         activity.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/scroll.wav')
0169                                         items.colorSelector = modelData
0170                                     }
0171                                 }
0172                             }
0173                             GCText {
0174                                 id: text1
0175                                 anchors.fill: parent
0176                                 text: modelData
0177                                 fontSize: regularSize
0178                                 z: modelData == items.colorSelector ? 12 : 2
0179                                 font.bold: true
0180                                 style: Text.Outline
0181                                 styleColor: "black"
0182                                 color: "white"
0183                             }
0184                             DropShadow {
0185                                 anchors.fill: text1
0186                                 cached: false
0187                                 horizontalOffset: 1
0188                                 verticalOffset: 1
0189                                 radius: 8.0
0190                                 samples: 16
0191                                 color: "#80000000"
0192                                 source: text1
0193                             }
0194                         }
0195                     }
0196                 }
0197             }
0198             Grid {
0199                 id: drawAndExampleArea
0200                 columns: background.landscape ? 2 : 1
0201                 width: parent.width - colorSelector.width
0202                 height: parent.height - bar.height * 1.2
0203                 spacing: 10
0204 
0205                 // The drawing area
0206                 Grid {
0207                     id: drawingArea
0208                     width: background.areaWidth
0209                     height: background.areaHeight
0210                     columns: items.numberOfColumn
0211                     Repeater {
0212                         id: userModel
0213                         model: items.targetModelData.length
0214                         property int currentItem: 0
0215                         property bool keyNavigation: false
0216 
0217                         function reset() {
0218                             for(var i=0; i < items.userModel.count; ++i)
0219                                 userModel.itemAt(i).paint(items.colorSelector)
0220                             currentItem = 0
0221                             keyNavigation = false
0222                         }
0223 
0224                         function clearCurrentItem() {
0225                             userModel.itemAt(currentItem).paint(0)
0226                         }
0227 
0228                         function paintCurrentItem() {
0229                             userModel.itemAt(currentItem).playEffect(items.colorSelector)
0230                             userModel.itemAt(currentItem).paint(items.colorSelector)
0231                         }
0232 
0233                         function moveCurrentIndexRight() {
0234                             keyNavigation = true
0235                             if(currentItem++ >= items.targetModelData.length - 1)
0236                                 currentItem = 0
0237                         }
0238 
0239                         function moveCurrentIndexLeft() {
0240                             keyNavigation = true
0241                             if(currentItem-- <= 0)
0242                                 currentItem = items.targetModelData.length - 1
0243                         }
0244 
0245                         function moveCurrentIndexUp() {
0246                             keyNavigation = true
0247                             currentItem -= items.numberOfColumn
0248                             if(currentItem < 0)
0249                                 currentItem += items.targetModelData.length
0250                         }
0251 
0252                         function moveCurrentIndexDown() {
0253                             keyNavigation = true
0254                             currentItem += items.numberOfColumn
0255                             if(currentItem > items.targetModelData.length - 1)
0256                                 currentItem -= items.targetModelData.length
0257                         }
0258 
0259                         Item {
0260                             id: userItem
0261                             width: background.cellSize
0262                             height: background.cellSize
0263                             property color color: Activity.colors[colorIndex]
0264                             property int colorIndex
0265 
0266                             function paint(color) {
0267                                 colorIndex = color
0268                             }
0269 
0270                             function playEffect(color) {
0271                                 if(color === 0)
0272                                     activity.audioEffects.play(Activity.url + 'eraser.wav')
0273                                 else
0274                                     activity.audioEffects.play(Activity.url + 'brush.wav')
0275                             }
0276 
0277                             Rectangle {
0278                                 id: userRect
0279                                 anchors.fill: parent
0280                                 border.width: userModel.keyNavigation && userModel.currentItem == modelData ? 3 : 1
0281                                 border.color: 'black'
0282                                 color: parent.color
0283 
0284                                 Behavior on color {
0285                                     ColorAnimation {
0286                                         duration: 200
0287                                         onRunningChanged: {
0288                                             if(!running) checkTimer.restart();
0289                                         }
0290                                     }
0291                                 }
0292                             }
0293                             GCText {
0294                                 id: text2
0295                                 anchors.fill: parent
0296                                 anchors.margins: 4
0297                                 text: parent.colorIndex == 0 ? "" : parent.colorIndex
0298                                 fontSize: regularSize
0299                                 font.bold: true
0300                                 style: Text.Outline
0301                                 styleColor: "black"
0302                                 color: "white"
0303                             }
0304                             DropShadow {
0305                                 anchors.fill: text2
0306                                 cached: false
0307                                 horizontalOffset: 1
0308                                 verticalOffset: 1
0309                                 radius: 8.0
0310                                 samples: 16
0311                                 color: "#80000000"
0312                                 source: text2
0313                             }
0314                         }
0315                     }
0316                 }
0317 
0318                 // The painting to reproduce
0319                 Grid {
0320                     id: imageArea
0321                     width: background.areaWidth
0322                     height: background.areaHeight
0323                     columns: items.numberOfColumn
0324                     LayoutMirroring.enabled: activity.symmetry
0325                     LayoutMirroring.childrenInherit: true
0326                     Repeater {
0327                         id: targetModel
0328                         model: items.targetModelData
0329                         Item {
0330                             width: background.cellSize
0331                             height: background.cellSize
0332                             property alias color: targetRect.color
0333 
0334                             Rectangle {
0335                                 id: targetRect
0336                                 anchors.fill: parent
0337                                 color: Activity.colors[modelData]
0338                                 border.width: 1
0339                                 border.color: 'black'
0340                             }
0341                             GCText {
0342                                 id: text3
0343                                 anchors.fill: parent
0344                                 anchors.margins: 4
0345                                 text: modelData == 0 ? "" : modelData
0346                                 fontSize: regularSize
0347                                 font.bold: true
0348                                 style: Text.Outline
0349                                 styleColor: "black"
0350                                 color: "white"
0351                             }
0352                             DropShadow {
0353                                 anchors.fill: text3
0354                                 cached: false
0355                                 horizontalOffset: 1
0356                                 verticalOffset: 1
0357                                 radius: 8.0
0358                                 samples: 16
0359                                 color: "#80000000"
0360                                 source: text3
0361                             }
0362 
0363                         }
0364                     }
0365                 }
0366             }
0367         }
0368 
0369         Timer {
0370             id: checkTimer
0371             interval: 500
0372             onTriggered: Activity.checkModel()
0373         }
0374 
0375         MultiPointTouchArea {
0376             x: drawAndExampleArea.x
0377             y: drawAndExampleArea.y
0378             width: drawingArea.width
0379             height: drawingArea.height
0380             onPressed: checkTouchPoint(touchPoints)
0381             onTouchUpdated: checkTouchPoint(touchPoints)
0382             enabled: !bonus.isPlaying
0383 
0384             function checkTouchPoint(touchPoints) {
0385                 for(var i in touchPoints) {
0386                     var touch = touchPoints[i]
0387                     var block = drawingArea.childAt(touch.x, touch.y)
0388                     if(block) {
0389                         block.playEffect(items.colorSelector)
0390                         block.paint(items.colorSelector)
0391                     }
0392                 }
0393             }
0394         }
0395 
0396         DialogChooseLevel {
0397             id: dialogActivityConfig
0398             currentActivity: activity.activityInfo
0399             onSaveData: {
0400                 levelFolder = dialogActivityConfig.chosenLevels
0401                 currentActivity.currentLevels = dialogActivityConfig.chosenLevels
0402                 ApplicationSettings.setCurrentLevels(currentActivity.name, dialogActivityConfig.chosenLevels)
0403                 activity.focus = true
0404             }
0405             onLoadData: {
0406                 if(activityData) {
0407                     Activity.initLevel()
0408                 }
0409             }
0410             onClose: {
0411                 home()
0412             }
0413             onStartActivity: {
0414                 background.stop()
0415                 background.start()
0416             }
0417         }
0418 
0419         DialogHelp {
0420             id: dialogHelp
0421             onClose: home()
0422         }
0423 
0424         Bar {
0425             id: bar
0426             level: items.currentLevel + 1
0427             content: BarEnumContent { value: help | home | level | activityConfig}
0428             onHelpClicked: {
0429                 displayDialog(dialogHelp)
0430             }
0431             onPreviousLevelClicked: Activity.previousLevel()
0432             onNextLevelClicked: Activity.nextLevel()
0433             onHomeClicked: activity.home()
0434             onActivityConfigClicked: {
0435                  displayDialog(dialogActivityConfig)
0436              }
0437         }
0438 
0439         Bonus {
0440             id: bonus
0441             Component.onCompleted: win.connect(Activity.nextLevel)
0442         }
0443     }
0444 }