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 }