Warning, /education/gcompris/src/activities/renewable_energy/Hydro.qml is written in an unsupported language. File is not indexed.
0001 /* GCompris - hydro.qml 0002 * 0003 * SPDX-FileCopyrightText: 2015 Sagar Chand Agarwal <atomsagar@gmail.com> 0004 * SPDX-FileCopyrightText: 2022 Timothée Giet <animtim@gmail.com> 0005 * 0006 * Authors: 0007 * Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version) 0008 * Sagar Chand Agarwal <atomsagar@gmail.com> (Qt Quick port) 0009 * Timothée Giet <animtim@gmail.com> (Big refactoring) 0010 * 0011 * SPDX-License-Identifier: GPL-3.0-or-later 0012 */ 0013 import QtQuick 2.12 0014 import GCompris 1.0 0015 import "../../core" 0016 0017 Item { 0018 id: hydro 0019 property alias power: stepup.power 0020 property alias cloudOpacity: cloud.opacity 0021 property alias vaporAnimLoop: vapor.animLoop 0022 property alias vaporIsUp: vapor.isUp 0023 property alias cloudIsUp: cloud.isUp 0024 0025 function start() { 0026 tuxboat.state = "tuxboatRight" 0027 items.sunIsUp = false 0028 } 0029 0030 function stop() { 0031 tuxboat.state = "tuxboatRestarted" 0032 dam.started = false 0033 river.level = 0 0034 items.sunIsUp = false 0035 vapor.animLoop = false 0036 vapor.isUp = false 0037 rain.down() 0038 cloud.isUp = false 0039 stepup.started = false 0040 } 0041 0042 function stopTimer() { 0043 timer.stop(); 0044 } 0045 0046 Image { 0047 id: tuxboat 0048 source: activity.url2 + "boat.svg" 0049 width: parent.width * 0.12 0050 fillMode: Image.PreserveAspectFit 0051 sourceSize.width: width 0052 anchors{ 0053 bottom: parent.bottom 0054 bottomMargin: parent.width * 0.02 0055 left: parent.left 0056 leftMargin: 0 0057 } 0058 z: 51 0059 state: "tuxboatLeft" 0060 states: [ 0061 State { 0062 name: "tuxboatLeft" 0063 PropertyChanges { 0064 target: tuxboat 0065 anchors.leftMargin: 0 0066 opacity: 1 0067 } 0068 }, 0069 State { 0070 name: "tuxboatRight" 0071 PropertyChanges { 0072 target: tuxboat 0073 anchors.leftMargin: layoutArea.width - tuxboat.width 0074 opacity: 0 0075 } 0076 }, 0077 State { 0078 name: "tuxboatRestarted" 0079 PropertyChanges { 0080 target: tuxboat 0081 anchors.leftMargin: layoutArea.width - tuxboat.width 0082 opacity: 0 0083 } 0084 } 0085 ] 0086 0087 transitions: [ 0088 Transition { 0089 from: "tuxboatLeft"; to: "tuxboatRight"; 0090 SequentialAnimation { 0091 ScriptAction { script: items.audioEffects.play("qrc:/gcompris/src/activities/watercycle/resource/harbor1.wav") } 0092 NumberAnimation { property: "anchors.leftMargin"; easing.type: Easing.InOutSine; duration: 15000 } 0093 ScriptAction { script: items.audioEffects.play("qrc:/gcompris/src/activities/watercycle/resource/harbor2.wav") } 0094 NumberAnimation { property: "opacity"; easing.type: Easing.InOutQuad; duration: 200 } 0095 ScriptAction { script: { 0096 boatparked.opacity = 1; 0097 tux.visible = true; 0098 } 0099 } 0100 } 0101 }, 0102 Transition { 0103 from: "tuxboatRight"; to: "tuxboatLeft"; 0104 PropertyAction { properties: "anchors.leftMargin, opacity" } 0105 ScriptAction { script: boatparked.opacity = 0 } 0106 }, 0107 Transition { 0108 from: "tuxboatRight, tuxboatLeft"; to: "tuxboatRestarted" 0109 PropertyAction { properties: "anchors.leftMargin, opacity" } 0110 ScriptAction { script: { 0111 boatparked.opacity = 1; 0112 tux.visible = true; 0113 } 0114 } 0115 } 0116 ] 0117 } 0118 0119 Image { 0120 id: boatparked 0121 source: activity.url2 + "boat_parked.svg" 0122 width: parent.width * 0.12 0123 fillMode: Image.PreserveAspectFit 0124 sourceSize.width: width 0125 opacity: 0 0126 anchors { 0127 right: parent.right 0128 bottom: parent.bottom 0129 bottomMargin: tuxboat.anchors.bottomMargin 0130 } 0131 z: 51 0132 Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 200 } } 0133 } 0134 0135 Image { 0136 id: vapor 0137 opacity: 0 0138 source: activity.url2 + "vapor.svg" 0139 width: parent.width * 0.1 0140 fillMode: Image.PreserveAspectFit 0141 sourceSize.width: width 0142 property bool isUp: false 0143 property bool animLoop: false 0144 anchors { 0145 left: parent.left 0146 top: parent.top 0147 topMargin: parent.width * 0.28 0148 leftMargin: parent.width * 0.056 0149 } 0150 z: 31 0151 0152 onIsUpChanged: { 0153 if(isUp) 0154 state = "vaporUp" 0155 else 0156 state = "vaporDown" 0157 } 0158 0159 state: "vaporDown" 0160 states: [ 0161 State { 0162 name: "vaporDown" 0163 PropertyChanges { 0164 target: vapor 0165 opacity: 0 0166 anchors.topMargin: parent.width * 0.28 0167 } 0168 }, 0169 State { 0170 name: "vaporUp" 0171 PropertyChanges { 0172 target: vapor 0173 opacity: 1 0174 anchors.topMargin: parent.width * 0.1 0175 } 0176 } 0177 ] 0178 0179 transitions: [ 0180 Transition { 0181 from: "vaporDown"; to: "vaporUp"; 0182 SequentialAnimation { 0183 NumberAnimation { property: "opacity"; duration: 200 } 0184 NumberAnimation { property: "anchors.topMargin"; duration: 5000 } 0185 ScriptAction { script: vapor.isUp = false } 0186 } 0187 }, 0188 Transition { 0189 from: "vaporUp"; to: "vaporDown"; 0190 SequentialAnimation { 0191 NumberAnimation { property: "opacity"; duration: 200 } 0192 PropertyAction { property: "anchors.topMargin" } 0193 ScriptAction { script: { 0194 if(vapor.animLoop === true) { 0195 vapor.animLoop = false; 0196 vapor.isUp = true; 0197 } 0198 } 0199 } 0200 } 0201 } 0202 ] 0203 } 0204 0205 Image { 0206 id: cloud 0207 opacity: 0 0208 source: activity.url2 + "cloud.svg" 0209 sourceSize.width: parent.width * 0.256 0210 fillMode: Image.PreserveAspectFit 0211 width: 0 0212 property bool isUp: false 0213 property double originMargin: parent.width * 0.05 0214 property double upMargin: parent.width * 0.38 0215 anchors { 0216 top: parent.top 0217 topMargin: originMargin 0218 left: parent.left 0219 leftMargin: originMargin 0220 } 0221 z: 32 0222 MouseArea { 0223 id: cloud_area 0224 anchors.fill: cloud 0225 enabled: cloud.width > cloud.sourceSize.width * 0.8 && !rain.isRaining 0226 onClicked: { 0227 items.sunIsUp = false 0228 rain.up() 0229 } 0230 } 0231 0232 onIsUpChanged: { 0233 if(isUp) 0234 state = "cloudIsUp" 0235 else 0236 state = "cloudIsDown" 0237 } 0238 state: "cloudIsDown" 0239 states: [ 0240 State { 0241 name: "cloudIsDown" 0242 PropertyChanges { 0243 target: cloud 0244 opacity: 0 0245 width: 0 0246 anchors.leftMargin: cloud.originMargin 0247 } 0248 }, 0249 State { 0250 name: "cloudIsUp" 0251 PropertyChanges { 0252 target: cloud 0253 opacity: 1 0254 width: cloud.sourceSize.width 0255 anchors.leftMargin: cloud.upMargin 0256 } 0257 } 0258 ] 0259 0260 transitions: [ 0261 Transition { 0262 from: "cloudIsDown"; to: "cloudIsUp"; 0263 NumberAnimation { property: "opacity"; easing.type: Easing.InOutQuad; duration: 5000 } 0264 NumberAnimation { properties: "width, anchors.leftMargin"; easing.type: Easing.InOutQuad; duration: 15000 } 0265 }, 0266 Transition { 0267 from: "cloudIsUp"; to: "cloudIsDown"; 0268 PropertyAction { properties: "opacity, width, anchors.leftMargin" } 0269 } 0270 ] 0271 } 0272 0273 Image { 0274 id: rain 0275 source: activity.url2 + "rain.svg" 0276 width: parent.width * 0.146 0277 fillMode: Image.PreserveAspectFit 0278 sourceSize.width: width 0279 opacity: 0 0280 property bool isRaining: false 0281 anchors { 0282 top: parent.top 0283 topMargin: parent.width * 0.123 0284 left: cloud.left 0285 leftMargin: cloud.width * 0.25 0286 } 0287 z: 35 0288 Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 300 } } 0289 SequentialAnimation{ 0290 id: rainAnim 0291 running: false 0292 loops: 10 0293 NumberAnimation { 0294 target: rain 0295 property: "scale" 0296 duration: 500 0297 to: 0.95 0298 } 0299 NumberAnimation { 0300 target: rain 0301 property: "scale" 0302 duration: 500 0303 to: 1 0304 } 0305 onRunningChanged: { 0306 if(!running) { 0307 rain.down() 0308 cloud.isUp = false 0309 } 0310 } 0311 } 0312 function up() { 0313 isRaining = true; 0314 items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/water.wav'); 0315 opacity = 1; 0316 rainAnim.start(); 0317 } 0318 function down() { 0319 isRaining = false; 0320 scale = 0; 0321 opacity = 0 0322 } 0323 } 0324 0325 Image { 0326 id: river 0327 source: activity.url2 + "river.svg" 0328 width: parent.width * 0.431 0329 sourceSize.width: width 0330 fillMode: Image.PreserveAspectFit 0331 opacity: level > 0 ? 1 : 0 0332 anchors { 0333 top: parent.top 0334 left: parent.left 0335 topMargin: parent.width * 0.3309 0336 leftMargin: parent.width * 0.292 0337 } 0338 z: 40 0339 Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 5000 } } 0340 property double level: 0 0341 } 0342 0343 Image { 0344 id: reservoir1 0345 source: activity.url2 + "reservoir1.svg" 0346 width: layoutArea.width * 0.112 0347 fillMode: Image.PreserveAspectFit 0348 sourceSize.width: width 0349 anchors { 0350 top: parent.top 0351 left: parent.left 0352 topMargin: parent.width * 0.3309 0353 leftMargin: parent.width * 0.2948 0354 } 0355 opacity: river.level > 0.2 ? 1 : 0 0356 z: 40 0357 Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 5000 } } 0358 } 0359 0360 Image { 0361 id: reservoir2 0362 source: activity.url2 + "reservoir2.svg" 0363 width: layoutArea.width * 0.1604 0364 fillMode: Image.PreserveAspectFit 0365 sourceSize.width: width 0366 anchors { 0367 top: parent.top 0368 left: parent.left 0369 topMargin: parent.width * 0.3309 0370 leftMargin: parent.width * 0.2691 0371 } 0372 opacity: river.level > 0.5 ? 1 : 0 0373 z: 40 0374 Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 5000 } } 0375 } 0376 0377 Image { 0378 id: reservoir3 0379 source: activity.url2 + "reservoir3.svg" 0380 width: layoutArea.width * 0.1965 0381 fillMode: Image.PreserveAspectFit 0382 sourceSize.width: width 0383 anchors { 0384 top: parent.top 0385 left: parent.left 0386 topMargin: parent.width * 0.3309 0387 leftMargin: parent.width * 0.2532 0388 } 0389 opacity: river.level > 0.8 ? 1 : 0 0390 z: 40 0391 Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 5000 } } 0392 } 0393 0394 0395 Rectangle { 0396 z: 100 0397 width: stepup_power.width * 1.1 0398 height: stepup_power.height * 1.1 0399 border.color: items.produceColorBorder 0400 radius: 5 0401 color: items.produceColor 0402 anchors { 0403 bottom: stepup.top 0404 right: stepup.horizontalCenter 0405 } 0406 GCText { 0407 fontSize: smallSize * 0.5 0408 id: stepup_power 0409 anchors.centerIn: parent 0410 text: stepup.power.toString() + "W" 0411 } 0412 } 0413 0414 Image { 0415 id: dam 0416 source: activity.url + "hydroelectric/dam_off.svg" 0417 width: parent.width * 0.102 0418 sourceSize.width: width 0419 fillMode: Image.PreserveAspectFit 0420 z: 45 0421 anchors { 0422 left: parent.left 0423 top: parent.top 0424 leftMargin: parent.width * 0.299 0425 topMargin: parent.width * 0.383 0426 } 0427 MouseArea { 0428 id: dam_area 0429 anchors.centerIn: parent 0430 // Size the area for a touch screen 0431 width: parent.width * 1.2 0432 height: parent.width * 1.2 0433 enabled: river.opacity > 0 0434 onClicked: parent.started = !parent.started 0435 } 0436 property bool started: false 0437 property int power: started && river.level > 0.1 ? 1000 : 0 0438 } 0439 0440 Image { 0441 id: damOn 0442 source: activity.url + "hydroelectric/dam_on.svg" 0443 anchors.fill: dam 0444 sourceSize.width: width 0445 fillMode: Image.PreserveAspectFit 0446 visible: dam.started 0447 z: 45 0448 } 0449 0450 Image { 0451 id: damWire 0452 source: activity.url + "hydroelectric/damwire_off.svg" 0453 width: parent.width * 0.095 0454 sourceSize.width: width 0455 fillMode: Image.PreserveAspectFit 0456 anchors { 0457 left: parent.left 0458 top: parent.top 0459 leftMargin: parent.width * 0.372 0460 topMargin: parent.width * 0.45 0461 } 0462 z: 44 0463 } 0464 0465 Image { 0466 id: damWireOn 0467 source: activity.url + "hydroelectric/damwire_on.svg" 0468 anchors.fill: damWire 0469 sourceSize.width: width 0470 fillMode: Image.PreserveAspectFit 0471 z: 44 0472 visible: dam.power > 0 0473 } 0474 0475 Image { 0476 id: stepup 0477 source: activity.url + "transformer_off.svg" 0478 width: parent.width * 0.07 0479 sourceSize.width: width 0480 fillMode: Image.PreserveAspectFit 0481 z: 46 0482 anchors { 0483 top: parent.top 0484 left: parent.left 0485 topMargin: parent.width * 0.399 0486 leftMargin: parent.width * 0.445 0487 } 0488 property bool started: false 0489 property int power: started && dam.power ? dam.power : 0 0490 MouseArea { 0491 id: stepup_area 0492 anchors.centerIn: parent 0493 // Size the area for a touch screen 0494 width: parent.width * 1.2 0495 height: parent.width * 1.2 0496 onClicked: { 0497 parent.started = !parent.started 0498 } 0499 } 0500 } 0501 0502 Image { 0503 id: stepupOn 0504 source: activity.url + "transformer_on.svg" 0505 anchors.fill: stepup 0506 sourceSize.width: width 0507 fillMode: Image.PreserveAspectFit 0508 visible: stepup.started 0509 z: 46 0510 } 0511 0512 Image { 0513 id: stepupWire 0514 source: activity.url + "hydroelectric/stepupwire_off.svg" 0515 width: parent.width * 0.265 0516 sourceSize.width: width 0517 fillMode: Image.PreserveAspectFit 0518 anchors { 0519 top: parent.top 0520 left: parent.left 0521 topMargin: parent.width * 0.387 0522 leftMargin: parent.width * 0.478 0523 } 0524 z: 44 0525 } 0526 0527 Image { 0528 id: stepupWireOn 0529 source: activity.url + "hydroelectric/stepupwire_on.svg" 0530 anchors.fill: stepupWire 0531 sourceSize.width: width 0532 fillMode:Image.PreserveAspectFit 0533 visible: stepup.power > 0 0534 z: 44 0535 } 0536 0537 // Manage stuff that changes periodically 0538 Timer { 0539 id: timer 0540 interval: 100 0541 running: true 0542 repeat: true 0543 onTriggered: { 0544 if(rain.opacity > 0.2 && river.level < 1) { 0545 river.level += 0.01 0546 } else if(river.level > 0) { 0547 // Make the river level dependent on whether the dam runs 0548 river.level -= (dam.power > 0 ? 0.001 : 0.0005) 0549 } else { 0550 dam.started = false 0551 } 0552 } 0553 } 0554 }