Warning, /education/gcompris/src/activities/canal_lock/CanalLock.qml is written in an unsupported language. File is not indexed.
0001 /* GCompris - canal_lock.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 0014 import "../../core" 0015 import "." 0016 0017 ActivityBase { 0018 id: activity 0019 0020 onStart: focus = true 0021 onStop: {} 0022 0023 property string url: "qrc:/gcompris/src/activities/canal_lock/resource/" 0024 0025 pageComponent: Image { 0026 id: background 0027 source: activity.url + "sky.svg" 0028 anchors.fill: parent 0029 sourceSize.width: width 0030 sourceSize.height: height 0031 0032 property int running: 0 0033 0034 signal start 0035 signal stop 0036 0037 Component.onCompleted: { 0038 activity.start.connect(start) 0039 activity.stop.connect(stop) 0040 } 0041 0042 // Needed to get keyboard focus on IntroMessage 0043 Keys.forwardTo: message 0044 0045 IntroMessage { 0046 id: message 0047 anchors { 0048 top: parent.top 0049 topMargin: 10 0050 right: parent.right 0051 rightMargin: 5 0052 left: parent.left 0053 leftMargin: 5 0054 } 0055 z: 100 0056 intro: [ 0057 qsTr("Your goal is to lead Tux across the canal lock to get the wooden logs, " 0058 +"using the different types of water locks available."), 0059 qsTr("The vertical colored bars represent the water locks, which can be operated by clicking on them. " 0060 +"Two locks of the same type cannot be operated simultaneously.") , 0061 qsTr("The water level inside the lock will change according to the side of the canal it is " 0062 +"connected to. Use this property to help Tux get the job done.") 0063 ] 0064 } 0065 0066 onStart: water.state = 'down' 0067 0068 Image { 0069 source: activity.url + "sun.svg" 0070 sourceSize.width: Math.min(120 * ApplicationInfo.ratio, parent.width * 0.15) 0071 x: 10 0072 y: 10 0073 } 0074 0075 Image { 0076 source: activity.url + "cloud1.svg" 0077 sourceSize.width: Math.min(120 * ApplicationInfo.ratio, parent.width * 0.15) 0078 anchors.top: parent.top 0079 anchors.left: parent.left 0080 anchors.leftMargin: parent.width * 0.18 0081 anchors.topMargin: parent.height * 0.1 0082 } 0083 0084 Image { 0085 source: activity.url + "cloud2.svg" 0086 sourceSize.width: Math.min(130 * ApplicationInfo.ratio, parent.width * 0.2) 0087 anchors.top: parent.top 0088 anchors.left: parent.left 0089 anchors.leftMargin: parent.width * 0.25 0090 anchors.topMargin: parent.height * 0.02 0091 } 0092 0093 Rectangle { 0094 color: "#805451" 0095 anchors.left: background.left 0096 anchors.right: background.right 0097 anchors.top: canal.bottom 0098 anchors.topMargin: -boat.leftPositionY 0099 anchors.bottom: background.bottom 0100 } 0101 0102 Item { 0103 id: canalArea 0104 anchors.top: parent.top 0105 anchors.left: parent.left 0106 anchors.right: parent.right 0107 anchors.bottom: bar.top 0108 } 0109 0110 Image { 0111 id: canal 0112 source: activity.url + "canal_lock.svg" 0113 anchors.centerIn: canalArea 0114 height: canalArea.height 0115 width: canalArea.width 0116 sourceSize.width: width 0117 sourceSize.height: height 0118 fillMode: Image.PreserveAspectFit 0119 0120 Image { 0121 id: canalLeft 0122 source: activity.url + "canal_left.svg" 0123 anchors.top: canal.top 0124 anchors.left: canal.left 0125 width: (background.width - parent.paintedWidth) / 2 + 1 0126 height: parent.height 0127 sourceSize.height: height 0128 fillMode: Image.TileHorizontally 0129 } 0130 0131 Image { 0132 source: activity.url + "canal_right.svg" 0133 anchors.top: canal.top 0134 anchors.right: parent.right 0135 width: canalLeft.width 0136 height: parent.height 0137 sourceSize.height: height 0138 fillMode: Image.TileHorizontally 0139 } 0140 0141 Rectangle { 0142 id: water 0143 anchors.bottom: parent.bottom 0144 anchors.bottomMargin: (canal.height - canal.paintedHeight) / 2 + 0145 canal.paintedHeight * 0.23 0146 anchors.horizontalCenter: parent.horizontalCenter 0147 anchors.horizontalCenterOffset: parent.paintedWidth * 0.035 0148 color: "#4f76d6" 0149 width: parent.paintedWidth * 0.205 0150 height: minHeight 0151 state: "undef" 0152 0153 property int maxHeight: canal.paintedHeight * 0.328 0154 property int minHeight: canal.paintedHeight * 0.15 0155 property int duration: 3500 0156 0157 Behavior on height { NumberAnimation { duration: water.duration } } 0158 0159 onStateChanged: { 0160 if( water.state == "undef") 0161 return 0162 activity.audioEffects.play(activity.url + 'water_fill.wav') 0163 if( water.state == 'up' && boat.state == 'middleDown') 0164 boat.state = 'middleUp' 0165 else if( water.state == 'down' && boat.state == 'middleUp') 0166 boat.state = 'middleDown' 0167 } 0168 0169 states: [ 0170 State { 0171 name: "undef" 0172 PropertyChanges { target: water; height: water.minHeight} 0173 }, 0174 State { 0175 name: "down" 0176 PropertyChanges { target: water; height: water.minHeight} 0177 }, 0178 State { 0179 name: "up" 0180 PropertyChanges { target: water; height: water.maxHeight} 0181 } 0182 ] 0183 } 0184 0185 Lock { 0186 id: lock1 0187 color: "#dfb625" 0188 anchors.bottomMargin: (canal.height - canal.paintedHeight) / 2 + 0189 canal.paintedHeight * 0.03 0190 anchors.horizontalCenterOffset: - canal.paintedWidth * 0.16 0191 minHeight: canal.paintedHeight * 0.05 0192 maxHeight: canal.paintedHeight * 0.18 0193 duration: 0 0194 0195 MouseArea { 0196 anchors.fill: parent 0197 anchors.margins: -20 * ApplicationInfo.ratio 0198 onClicked: { 0199 if(background.running) 0200 return 0201 lock1.duration = 400 0202 if(lock1.state == 'close' && 0203 door2.state == 'close' && 0204 lock2.state == 'close') { 0205 activity.audioEffects.play(activity.url + 'lock.wav') 0206 lock1.state = 'open' 0207 water.state = 'down' 0208 } else if(lock1.state == 'open') { 0209 activity.audioEffects.play(activity.url + 'lock.wav') 0210 lock1.state = 'close' 0211 } else { 0212 activity.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/crash.wav") 0213 } 0214 } 0215 } 0216 0217 } 0218 0219 Lock { 0220 id: lock2 0221 color: "#dfb625" 0222 anchors.bottomMargin: (canal.height - canal.paintedHeight) / 2 + 0223 canal.paintedHeight * 0.03 0224 anchors.horizontalCenterOffset: canal.paintedWidth * 0.22 0225 minHeight: canal.paintedHeight * 0.05 0226 maxHeight: canal.paintedHeight * 0.18 0227 duration: 0 0228 0229 MouseArea { 0230 anchors.fill: parent 0231 anchors.margins: -20 * ApplicationInfo.ratio 0232 onClicked: { 0233 if(background.running) 0234 return 0235 lock2.duration = lock1.duration 0236 if(lock2.state == 'close' && 0237 door1.state == 'close' && 0238 lock1.state == 'close') { 0239 activity.audioEffects.play(activity.url + 'lock.wav') 0240 lock2.state = 'open' 0241 water.state = 'up' 0242 } else if(lock2.state == 'open') { 0243 activity.audioEffects.play(activity.url + 'lock.wav') 0244 lock2.state = 'close' 0245 } else { 0246 activity.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/crash.wav") 0247 } 0248 } 0249 } 0250 0251 } 0252 0253 Lock { 0254 id: door1 0255 color: "#31cb25" 0256 anchors.bottomMargin: (canal.height - canal.paintedHeight) / 2 + 0257 canal.paintedHeight * 0.2 0258 anchors.horizontalCenterOffset: - canal.paintedWidth * 0.07 0259 minHeight: canal.paintedHeight * 0.05 0260 maxHeight: canal.paintedHeight * 0.4 0261 duration: 0 0262 0263 MouseArea { 0264 anchors.fill: parent 0265 anchors.margins: -20 * ApplicationInfo.ratio 0266 onClicked: { 0267 if(background.running) 0268 return 0269 door1.duration = water.duration 0270 if(door1.state == 'close' && 0271 water.state == 'down') { 0272 door1.state = 'open' 0273 leftLight.state = 'green' 0274 activity.audioEffects.play(activity.url + 'door_open.wav') 0275 } else if(door1.state == 'open') { 0276 door1.state = 'close' 0277 leftLight.state = 'red' 0278 activity.audioEffects.play(activity.url + 'door_close.wav') 0279 } else { 0280 activity.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/crash.wav") 0281 } 0282 } 0283 } 0284 } 0285 0286 Lock { 0287 id: door2 0288 color: "#31cb25" 0289 anchors.bottomMargin: (canal.height - canal.paintedHeight) / 2 + 0290 canal.paintedHeight * 0.2 0291 anchors.horizontalCenterOffset: canal.paintedWidth * 0.14 0292 minHeight: canal.paintedHeight * 0.15 0293 maxHeight: canal.paintedHeight * 0.4 0294 duration: 0 0295 0296 MouseArea { 0297 anchors.fill: parent 0298 anchors.margins: -20 * ApplicationInfo.ratio 0299 onClicked: { 0300 if(background.running) 0301 return 0302 door2.duration = water.duration 0303 if(door2.state == 'close' && 0304 water.state == 'up') { 0305 door2.state = 'open' 0306 rightLight.state = 'green' 0307 activity.audioEffects.play(activity.url + 'door_open.wav') 0308 } else if(door2.state == 'open') { 0309 door2.state = 'close' 0310 rightLight.state = 'red' 0311 activity.audioEffects.play(activity.url + 'door_close.wav') 0312 } else { 0313 activity.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/crash.wav") 0314 } 0315 } 0316 } 0317 } 0318 0319 Image { 0320 id: leftLight 0321 source: activity.url + "light_red.svg" 0322 anchors.bottom: canal.bottom 0323 anchors.bottomMargin: (canal.height - canal.paintedHeight) / 2 + 0324 canal.paintedHeight * 0.46 0325 anchors.horizontalCenter: canal.horizontalCenter 0326 anchors.horizontalCenterOffset: - canal.paintedWidth * 0.18 0327 sourceSize.height: canal.paintedHeight * 0.1 0328 0329 states: [ 0330 State { 0331 name: "green" 0332 PropertyChanges { 0333 target: leftLight 0334 source: activity.url + "light_green.svg" 0335 } 0336 }, 0337 State { 0338 name: "red" 0339 PropertyChanges { 0340 target: leftLight 0341 source: activity.url + "light_red.svg" 0342 } 0343 } 0344 ] 0345 } 0346 0347 Image { 0348 id: rightLight 0349 source: activity.url + "light_red.svg" 0350 anchors.bottom: canal.bottom 0351 anchors.bottomMargin: (canal.height - canal.paintedHeight) / 2 + 0352 canal.paintedHeight * 0.60 0353 anchors.horizontalCenter: canal.horizontalCenter 0354 anchors.horizontalCenterOffset: canal.paintedWidth * 0.20 0355 sourceSize.height: canal.paintedHeight * 0.1 0356 mirror: true 0357 0358 states: [ 0359 State { 0360 name: "green" 0361 PropertyChanges { 0362 target: rightLight 0363 source: activity.url + "light_green.svg" 0364 } 0365 }, 0366 State { 0367 name: "red" 0368 PropertyChanges { 0369 target: rightLight 0370 source: activity.url + "light_red.svg" 0371 } 0372 } 0373 ] 0374 } 0375 0376 Image { 0377 id: boat 0378 source: activity.url + "boat1.svg" 0379 sourceSize.width: water.width * 0.74 0380 anchors { 0381 bottom: canal.bottom 0382 bottomMargin: leftPositionY 0383 horizontalCenter: canal.horizontalCenter 0384 horizontalCenterOffset: leftPositionX 0385 0386 onHorizontalCenterOffsetChanged: { 0387 if(boat.anchors.horizontalCenterOffset == boat.rightPositionX && 0388 boat.source == activity.url + "boat1.svg") { 0389 boat.source = activity.url + "boat2.svg" 0390 bonus.good("flower") 0391 } else if(boat.anchors.horizontalCenterOffset == boat.leftPositionX) { 0392 boat.source = activity.url + "boat1.svg" 0393 } 0394 } 0395 } 0396 state: 'left' 0397 0398 property int leftPositionX: - (canal.paintedWidth / 2) * 0.8 0399 property int leftPositionY: (canal.height - canal.paintedHeight) / 2 + 0400 canal.paintedHeight * 0.37 0401 property int middlePositionX: canal.paintedWidth * 0.035 0402 property int rightPositionX: (canal.paintedWidth / 2) * 0.7 0403 property int rightPositionY: (canal.height - canal.paintedHeight) / 2 + 0404 canal.paintedHeight * 0.55 0405 property int duration: 0 0406 0407 Behavior on anchors.horizontalCenterOffset { 0408 NumberAnimation { 0409 duration: boat.duration 0410 onRunningChanged: background.running ? background.running++ : background.running-- 0411 } 0412 } 0413 Behavior on anchors.bottomMargin { 0414 NumberAnimation { 0415 duration: boat.duration 0416 onRunningChanged: background.running ? background.running++ : background.running-- 0417 } 0418 } 0419 0420 MouseArea { 0421 anchors.fill: parent 0422 onClicked: { 0423 if(background.running) 0424 return 0425 boat.duration = water.duration 0426 var prevState = boat.state 0427 if(boat.state == "left" && door1.opened) 0428 boat.state = "middleDown" 0429 else if(boat.state == "middleUp" && door2.opened) 0430 boat.state = "right" 0431 else if(boat.state == "right" && door2.opened) 0432 boat.state = "middleUp" 0433 else if(boat.state == "middleDown" && door1.opened) 0434 boat.state = "left" 0435 0436 if(prevState !== boat.state) 0437 activity.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/water.wav') 0438 0439 } 0440 } 0441 0442 states: [ 0443 State { 0444 name: "left" 0445 PropertyChanges { 0446 target: boat 0447 anchors.horizontalCenterOffset: boat.leftPositionX 0448 anchors.bottomMargin: boat.leftPositionY 0449 } 0450 }, 0451 State { 0452 name: "middleDown" 0453 PropertyChanges { 0454 target: boat 0455 anchors.horizontalCenterOffset: boat.middlePositionX 0456 anchors.bottomMargin: boat.leftPositionY 0457 } 0458 }, 0459 State { 0460 name: "middleUp" 0461 PropertyChanges { 0462 target: boat 0463 anchors.horizontalCenterOffset: boat.middlePositionX 0464 anchors.bottomMargin: boat.rightPositionY 0465 } 0466 }, 0467 State { 0468 name: "right" 0469 PropertyChanges { 0470 target: boat 0471 anchors.horizontalCenterOffset: boat.rightPositionX 0472 anchors.bottomMargin: boat.rightPositionY 0473 } 0474 } 0475 ] 0476 } 0477 } 0478 0479 DialogHelp { 0480 id: dialogHelp 0481 onClose: home() 0482 } 0483 0484 Bar { 0485 id: bar 0486 content: BarEnumContent { value: help | home } 0487 onHelpClicked: { 0488 displayDialog(dialogHelp) 0489 } 0490 onHomeClicked: home(); 0491 } 0492 0493 Bonus { 0494 id: bonus 0495 } 0496 } 0497 0498 }