Warning, /education/gcompris/src/activities/crane/Crane.qml is written in an unsupported language. File is not indexed.
0001 /* GCompris - Crane.qml 0002 * 0003 * SPDX-FileCopyrightText: 2016 Stefan Toncu <stefan.toncu29@gmail.com> 0004 * SPDX-FileCopyrightText: 2020 Timothée Giet <animtim@gmail.com> 0005 * 0006 * Authors: 0007 * <Marc BRUN> (GTK+ version) 0008 * Stefan Toncu <stefan.toncu29@gmail.com> (Qt Quick port) 0009 * Timothée Giet <animtim@gmail.com> (layout refactoring) 0010 * 0011 * SPDX-License-Identifier: GPL-3.0-or-later 0012 */ 0013 0014 import QtQuick 2.12 0015 import QtGraphicalEffects 1.0 0016 import GCompris 1.0 0017 0018 import "../../core" 0019 import "crane.js" as Activity 0020 0021 ActivityBase { 0022 id: activity 0023 0024 // Overload this in your activity to change it 0025 // Put you default-<locale>.json files in it 0026 property string dataSetUrl: "qrc:/gcompris/src/activities/crane/resource/" 0027 0028 onStart: focus = true 0029 onStop: {} 0030 0031 pageComponent: Image { 0032 id: background 0033 source: activity.dataSetUrl+"background.svg" 0034 fillMode: Image.PreserveAspectCrop 0035 anchors.fill: parent 0036 sourceSize.width: width 0037 sourceSize.height: height 0038 0039 signal start 0040 signal stop 0041 0042 Component.onCompleted: { 0043 activity.start.connect(start) 0044 dialogActivityConfig.initialize() 0045 activity.stop.connect(stop) 0046 } 0047 0048 // Add here the QML items you need to access in javascript 0049 QtObject { 0050 id: items 0051 property Item main: activity.main 0052 property alias background: background 0053 property GCSfx audioEffects: activity.audioEffects 0054 property int currentLevel: activity.currentLevel 0055 property alias bonus: bonus 0056 property alias board: board 0057 property alias grid: answerGrid 0058 property alias answerRepeater: answerRepeater 0059 property alias modelRepeater: modelRepeater 0060 property alias gridRepeater: gridRepeater 0061 property alias showGrid1: showGrid1 0062 property alias score: score 0063 property alias selector: selector 0064 property int selected: -1 0065 property int columns 0066 property int rows 0067 property bool ok: true 0068 property int sensivity: 80 0069 property bool pieceIsMoving: false 0070 readonly property var levels: activity.datasetLoader.data 0071 property double gridBaseWidth: items.board.width / items.columns 0072 property double gridBaseHeight: items.board.height / items.rows 0073 property bool buttonsBlocked: false 0074 } 0075 0076 onStart: { Activity.start(items) } 0077 onStop: { Activity.stop() } 0078 0079 property bool portrait: height >= width ? true : false 0080 property bool inLine: true 0081 0082 Keys.onPressed: { 0083 if (items.buttonsBlocked){ 0084 return 0085 } 0086 else if (event.key === Qt.Key_Left){ 0087 Activity.move("left") 0088 left.opacity = 0.6 0089 } 0090 else if (event.key === Qt.Key_Right){ 0091 Activity.move("right") 0092 right.opacity = 0.6 0093 } 0094 else if (event.key === Qt.Key_Up){ 0095 Activity.move("up") 0096 up.opacity = 0.6 0097 } 0098 else if (event.key === Qt.Key_Down){ 0099 Activity.move("down") 0100 down.opacity = 0.6 0101 } 0102 else if (event.key === Qt.Key_Space || 0103 event.key === Qt.Key_Tab || 0104 event.key === Qt.Key_Enter || 0105 event.key === Qt.Key_Return) 0106 Activity.move("next") 0107 } 0108 0109 Keys.onReleased: { 0110 up.opacity = 1 0111 down.opacity = 1 0112 left.opacity = 1 0113 right.opacity = 1 0114 } 0115 0116 Item { 0117 id: layoutArea 0118 anchors.top: background.top 0119 anchors.bottom: bar.top 0120 anchors.left: background.left 0121 anchors.right: background.right 0122 anchors.bottomMargin: bar.height * 0.2 0123 } 0124 0125 //implementation of Swipe effect 0126 MouseArea { 0127 anchors.fill: layoutArea 0128 property int startX; 0129 property int startY; 0130 enabled: !items.buttonsBlocked 0131 0132 onPressed: { 0133 startX = mouse.x; 0134 startY = mouse.y; 0135 } 0136 onReleased: Activity.gesture(mouse.x - startX, mouse.y - startY) 0137 } 0138 0139 Rectangle { 0140 id: boardBg 0141 color: "#77c0d9" 0142 radius: width * 0.03 0143 border.color: "#77c0d9" 0144 border.width: width * 0.02 0145 z: 1 0146 clip: true 0147 0148 anchors { 0149 top: crane_top.bottom 0150 bottom: crane_body.top 0151 right: crane_vertical.left 0152 margins: 5 * ApplicationInfo.ratio 0153 } 0154 0155 width: background.portrait ? (layoutArea.width - crane_vertical.width) * 0.8 : ((layoutArea.width - anchors.margins * 2 - crane_vertical.width) * 0.5 ) * 0.9 0156 } 0157 0158 Rectangle { 0159 id: board 0160 z: 1 0161 color: "#b9e2f0" 0162 anchors.centerIn: boardBg 0163 width: boardBg.width - boardBg.border.width * 2 0164 height: boardBg.height - boardBg.border.width * 2 0165 } 0166 0167 Grid { 0168 id: showGrid1 0169 columns: items.columns 0170 rows: items.rows 0171 z: 1 0172 anchors.centerIn: board 0173 layer.enabled: ApplicationInfo.useOpenGL 0174 layer.effect: OpacityMask { 0175 maskSource: board 0176 } 0177 Repeater { 0178 id: gridRepeater 0179 0180 Rectangle { 0181 width: items.gridBaseWidth 0182 height: items.gridBaseHeight 0183 color: "transparent" 0184 border.width: 2 0185 border.color: "#77c0d9" 0186 } 0187 } 0188 } 0189 0190 0191 Grid { 0192 id: answerGrid 0193 columns: items.columns 0194 rows: items.rows 0195 z: 4 0196 anchors.centerIn: board 0197 0198 Repeater { 0199 id: answerRepeater 0200 0201 Image { 0202 id: figure 0203 sourceSize.height: height 0204 sourceSize.width: width 0205 width: items.gridBaseWidth 0206 height: items.gridBaseHeight 0207 fillMode: Image.PreserveAspectFit 0208 0209 property int initialIndex: -1 0210 0211 property alias anim: anim 0212 property int distance 0213 property int indexChange 0214 property int startPoint 0215 property string animationProperty 0216 property int _index: index // make current index accessible from outside 0217 0218 SequentialAnimation { 0219 id: anim 0220 PropertyAction { target: items; property: "ok"; value: "false"} 0221 NumberAnimation { target: figure; property: figure.animationProperty; from: figure.startPoint; to: figure.startPoint + distance; duration: 200 } 0222 PropertyAction { target: figure; property: "opacity"; value: 0 } 0223 NumberAnimation { target: figure; property: figure.animationProperty; from: figure.startPoint + distance; to: figure.startPoint; duration: 0; } 0224 PropertyAction { target: figure; property: "opacity"; value: 1 } 0225 PropertyAction { target: items.answerRepeater.itemAt(items.selected + indexChange); property: "source"; value: figure.source } 0226 PropertyAction { target: items.answerRepeater.itemAt(items.selected + indexChange); property: "initialIndex"; value: figure.initialIndex } 0227 PropertyAction { target: figure; property: "initialIndex"; value: -1 } 0228 PropertyAction { target: figure; property: "source"; value: "" } 0229 PropertyAction { target: items; property: "ok"; value: "true"} 0230 PropertyAction { target: items; property: "pieceIsMoving"; value: "false"} 0231 ScriptAction { script: Activity.checkAnswer() } 0232 } 0233 0234 MouseArea { 0235 anchors.fill: parent 0236 enabled: !items.buttonsBlocked 0237 0238 // Swipe effect 0239 property int startX; 0240 property int startY; 0241 0242 onPressed: { 0243 startX = mouse.x; 0244 startY = mouse.y; 0245 } 0246 0247 onReleased: 0248 Activity.gesture(mouse.x - startX, mouse.y - startY) 0249 0250 // Select a figure with mouse/touch 0251 onClicked: { 0252 if (source != "" && !items.pieceIsMoving) 0253 items.selected = index 0254 } 0255 } 0256 } 0257 } 0258 } 0259 0260 Image { 0261 id: selector 0262 source: activity.dataSetUrl+"selected.svg" 0263 sourceSize.width: width 0264 sourceSize.height: height 0265 width: items.gridBaseWidth 0266 height: items.gridBaseHeight 0267 opacity: 1 0268 state: "uninitialized" 0269 0270 x: 0 0271 y: 0 0272 z: 100 0273 0274 Behavior on x { NumberAnimation { duration: 200 } } 0275 Behavior on y { NumberAnimation { duration: 200 } } 0276 0277 states: [ 0278 State { 0279 name: "uninitialized" 0280 PropertyChanges { 0281 target: selector 0282 x: 0 0283 y: 0 0284 } 0285 PropertyChanges { 0286 target: cable 0287 height: 0 0288 x: 0 0289 } 0290 }, 0291 State { 0292 name: "initialized" 0293 PropertyChanges { 0294 target: selector 0295 x: answerRepeater.itemAt(items.selected) ? answerRepeater.itemAt(items.selected).x + board.x : 0 0296 y: answerRepeater.itemAt(items.selected) ? answerRepeater.itemAt(items.selected).y + board.y : 0 0297 } 0298 PropertyChanges { 0299 target: cable 0300 height: answerRepeater.itemAt(items.selected) ? answerRepeater.itemAt(items.selected).y + board.y - crane_top.y : 0 0301 x: answerRepeater.itemAt(items.selected) ? answerRepeater.itemAt(items.selected).x + board.x + items.gridBaseWidth / 2 : 0 0302 } 0303 } 0304 ] 0305 0306 } 0307 0308 Rectangle { 0309 id: modelBoardBg 0310 color: "#e294b7" 0311 radius: width * 0.03 0312 border.color: "#e294b7" 0313 border.width: width * 0.02 0314 z: 1 0315 0316 anchors { 0317 left: background.portrait ? boardBg.left : crane_vertical.right 0318 top: background.portrait ? crane_body.bottom : background.inLine ? boardBg.top : parent.top 0319 topMargin: background.portrait ? boardBg.anchors.margins : background.inLine ? 0 : crane_top.height * 1.5 0320 leftMargin: background.portrait ? 0 : boardBg.anchors.margins * 1.2 0321 margins: boardBg.anchors.margins 0322 } 0323 0324 width: boardBg.width 0325 height: boardBg.height 0326 } 0327 0328 Rectangle { 0329 id: modelBoard 0330 z: 1 0331 color: "#f0b9d2" 0332 anchors.centerIn: modelBoardBg 0333 width: board.width 0334 height: board.height 0335 } 0336 0337 Grid { 0338 id: modelGrid 0339 columns: items.columns 0340 rows: items.rows 0341 anchors.centerIn: modelBoard 0342 z: 4 0343 0344 Repeater { 0345 id: modelRepeater 0346 0347 Image { 0348 id: modelFigure 0349 sourceSize.height: height 0350 sourceSize.width: width 0351 width: items.gridBaseWidth 0352 height: items.gridBaseHeight 0353 fillMode: Image.PreserveAspectFit 0354 } 0355 } 0356 } 0357 0358 Grid { 0359 id: showGrid2 0360 columns: items.columns 0361 rows: items.rows 0362 z: 1 0363 opacity: showGrid1.opacity 0364 anchors.centerIn: modelBoard 0365 layer.enabled: ApplicationInfo.useOpenGL 0366 layer.effect: OpacityMask { 0367 maskSource: modelBoard 0368 } 0369 Repeater { 0370 id: gridRepeater2 0371 model: gridRepeater.model 0372 0373 Rectangle { 0374 width: items.gridBaseWidth 0375 height: items.gridBaseHeight 0376 color: "transparent" 0377 border.width: 2 0378 border.color: showGrid1.opacity == 1 ? "#e294b7" : "transparent" 0379 } 0380 } 0381 } 0382 0383 0384 Image { 0385 id: crane_top 0386 source: activity.dataSetUrl+"crane_up.svg" 0387 sourceSize.width: width 0388 width: background.portrait ? layoutArea.width * 0.8: layoutArea.width * 0.5 0389 fillMode: Image.PreserveAspectFit 0390 z: 4 0391 anchors { 0392 top: layoutArea.top 0393 right: crane_vertical.right 0394 rightMargin: 0 0395 margins: boardBg.anchors.margins 0396 } 0397 } 0398 0399 Image { 0400 id: crane_vertical 0401 source: activity.dataSetUrl+"crane_vertical.svg" 0402 sourceSize.height: height 0403 fillMode: Image.PreserveAspectFit 0404 anchors { 0405 top: crane_top.top 0406 bottom: crane_body.verticalCenter 0407 right: background.portrait ? layoutArea.right : layoutArea.horizontalCenter 0408 rightMargin: background.portrait ? width / 2 : - width / 2 0409 topMargin: boardBg.anchors.margins 0410 } 0411 } 0412 0413 Image { 0414 id: crane_body 0415 source: activity.dataSetUrl+"crane_only.svg" 0416 z: 2 0417 height: bar.height 0418 sourceSize.height: height 0419 fillMode: Image.PreserveAspectFit 0420 mirror: background.portrait ? true : false 0421 anchors.verticalCenterOffset: crane_top.height * 0.5 0422 } 0423 0424 Image { 0425 id: crane_command 0426 source: activity.dataSetUrl+"command.svg" 0427 sourceSize.height: height 0428 anchors.margins: 5 * ApplicationInfo.ratio 0429 fillMode: Image.PreserveAspectFit 0430 Controls { 0431 id: up 0432 source: activity.dataSetUrl+"arrow_up.svg" 0433 anchors { 0434 right: parent.horizontalCenter 0435 rightMargin: width * 1.15 0436 } 0437 command: "up" 0438 } 0439 0440 Controls { 0441 id: down 0442 source: activity.dataSetUrl+"arrow_down.svg" 0443 anchors { 0444 right: parent.horizontalCenter 0445 rightMargin: width * 0.1 0446 } 0447 command: "down" 0448 } 0449 0450 Controls { 0451 id: left 0452 source: activity.dataSetUrl+"arrow_left.svg" 0453 anchors { 0454 left: parent.horizontalCenter 0455 leftMargin: width * 0.1 0456 } 0457 command: "left" 0458 } 0459 0460 Controls { 0461 id: right 0462 source: activity.dataSetUrl+"arrow_right.svg" 0463 anchors { 0464 left: parent.horizontalCenter 0465 leftMargin: width * 1.15 0466 } 0467 command: "right" 0468 } 0469 } 0470 0471 Rectangle { 0472 id: cable 0473 color: "#373737" 0474 width: 5 0475 height: 0 0476 x: 0 0477 z: 3 0478 anchors.top: crane_top.top 0479 anchors.topMargin: 10 0480 0481 Behavior on x { NumberAnimation { duration: 200 } } 0482 Behavior on height { NumberAnimation { duration: 200 } } 0483 } 0484 0485 states: [ 0486 State { 0487 name: "horizontal" 0488 when: !background.portrait 0489 PropertyChanges{ 0490 target: crane_command 0491 width: boardBg.width 0492 } 0493 AnchorChanges{ 0494 target: crane_body 0495 anchors.left: crane_vertical.left 0496 anchors.right: undefined 0497 anchors.bottom: layoutArea.bottom 0498 anchors.verticalCenter: undefined 0499 } 0500 AnchorChanges{ 0501 target: score 0502 anchors.right: modelBoardBg.right 0503 anchors.bottom: undefined 0504 anchors.verticalCenter: crane_body.verticalCenter 0505 anchors.left: undefined 0506 } 0507 AnchorChanges{ 0508 target:crane_command 0509 anchors.top: boardBg.bottom 0510 anchors.bottom: crane_body.bottom 0511 anchors.right: undefined 0512 anchors.left: undefined 0513 anchors.horizontalCenter: boardBg.horizontalCenter 0514 } 0515 }, 0516 State { 0517 name: "vertical" 0518 when: background.portrait 0519 PropertyChanges{ 0520 target: crane_command 0521 width: undefined 0522 } 0523 AnchorChanges{ 0524 target: crane_body 0525 anchors.left: undefined 0526 anchors.right: crane_vertical.right 0527 anchors.bottom: undefined 0528 anchors.verticalCenter: layoutArea.verticalCenter 0529 } 0530 AnchorChanges{ 0531 target: score 0532 anchors.right: undefined 0533 anchors.bottom: undefined 0534 anchors.verticalCenter: crane_body.verticalCenter 0535 anchors.left: layoutArea.left 0536 } 0537 AnchorChanges{ 0538 target:crane_command 0539 anchors.top: boardBg.bottom 0540 anchors.bottom: modelBoardBg.top 0541 anchors.right: crane_body.left 0542 anchors.left: score.right 0543 anchors.horizontalCenter: undefined 0544 } 0545 } 0546 ] 0547 0548 0549 DialogHelp { 0550 id: dialogHelp 0551 onClose: home() 0552 } 0553 0554 DialogChooseLevel { 0555 id: dialogActivityConfig 0556 currentActivity: activity.activityInfo 0557 onClose: { 0558 home() 0559 } 0560 0561 onSaveData: { 0562 levelFolder = dialogActivityConfig.chosenLevels 0563 currentActivity.currentLevels = dialogActivityConfig.chosenLevels 0564 ApplicationSettings.setCurrentLevels(currentActivity.name, dialogActivityConfig.chosenLevels) 0565 } 0566 0567 onStartActivity: { 0568 background.stop() 0569 background.start() 0570 } 0571 } 0572 0573 Bar { 0574 id: bar 0575 level: items.currentLevel + 1 0576 content: BarEnumContent { value: help | home | level | activityConfig} 0577 onHelpClicked: { 0578 displayDialog(dialogHelp) 0579 } 0580 onPreviousLevelClicked: Activity.previousLevel() 0581 onNextLevelClicked: Activity.nextLevel() 0582 onHomeClicked: activity.home() 0583 onActivityConfigClicked: { 0584 displayDialog(dialogActivityConfig) 0585 } 0586 } 0587 0588 Bonus { 0589 id: bonus 0590 Component.onCompleted: win.connect(Activity.nextLevel) 0591 } 0592 0593 Score { 0594 id: score 0595 visible: true 0596 anchors.right: modelBoardBg.right 0597 anchors.margins: 5 * ApplicationInfo.ratio 0598 onStop: { Activity.nextSubLevel() } 0599 } 0600 } 0601 0602 }