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 }