Warning, /education/gcompris/src/activities/watercycle/Watercycle.qml is written in an unsupported language. File is not indexed.

0001 /* GCompris - watercycle.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 
0014 import QtQuick 2.12
0015 import GCompris 1.0
0016 
0017 import "../../core"
0018 import "."
0019 
0020 ActivityBase {
0021     id: activity
0022 
0023     onStart: focus = true
0024     onStop: {}
0025 
0026     property string url: "qrc:/gcompris/src/activities/watercycle/resource/"
0027 
0028     pageComponent: Image {
0029         id: background
0030         anchors.fill: parent
0031         source: "qrc:/gcompris/src/activities/chess/resource/background-wood.svg"
0032         sourceSize.width: width
0033         sourceSize.height: height
0034 
0035         signal start
0036         signal stop
0037 
0038         Component.onCompleted: {
0039             activity.start.connect(start)
0040             activity.stop.connect(stop)
0041         }
0042 
0043         // Needed to get keyboard focus on IntroMessage
0044         Keys.forwardTo: message
0045 
0046         onStart: {}
0047         onStop: {
0048             timer.stop()
0049             activity.audioEffects.stop()
0050         }
0051 
0052         function initLevel() {
0053             if(message.visible)
0054                 return;
0055             timer.stop();
0056             items.cycleDone = false;
0057             river.level = 0;
0058             sun_area.enabled = true;
0059             sun.state = "sunDown";
0060             sun.hasRun = false;
0061             vapor.animLoop = false;
0062             vapor.state = "vaporDownRestarted";
0063             rainAnim.stop();
0064             rain.down();
0065             cloud.isUp = false;
0066             tuxboat.state = "tuxboatRestarted";
0067             boatparked.opacity = 1;
0068             shower.stop();
0069             waterplant.running = false;
0070             sewageplant.running = false;
0071             tower.level = 0;
0072             info.visible = true;
0073             info.setKey('start');
0074             timer.restart();
0075         }
0076 
0077         QtObject {
0078             id: items
0079             property var dataset: {
0080                 "none": "",
0081                 "start": qsTr("The sun is the main component of the water cycle. Click on the sun to start the water cycle."),
0082                 "sun": qsTr("As the sun rises, the water of the sea starts heating and evaporates."),
0083                 "cloud": qsTr("Water vapor condenses to form clouds and when clouds become heavy, it rains. Click on the cloud."),
0084                 "rain": qsTr("The rain causes rivers to swell up and this water is transported to us via motor pumps through water-towers." +
0085                              " Click on the motor pump to supply water to residents."),
0086                 "tower": qsTr("See the tower filled with water. Activate the sewage treatment station by clicking on it."),
0087                 "shower": qsTr("Great, click on the shower, as Tux arrives home."),
0088                 "done":  qsTr("Fantastic, you have completed the water cycle. You can continue playing.")
0089             }
0090 
0091             property bool cycleDone: false
0092             property bool isVertical: background.width < background.height - bar.height * 1.2
0093             property bool textOnSide: background.width > layoutArea.width * 1.5
0094             property GCSfx audioEffects: activity.audioEffects
0095         }
0096 
0097         IntroMessage {
0098             id: message
0099             anchors {
0100                 top: parent.top
0101                 topMargin: 10
0102                 right: parent.right
0103                 rightMargin: 5
0104                 left: parent.left
0105                 leftMargin: 5
0106             }
0107             z: 100
0108             onIntroDone: {
0109                 tuxboat.state = "tuxboatRight";
0110                 sun.state = "sunDown";
0111                 info.visible = true;
0112                 sun_area.enabled = true;
0113             }
0114             intro: [
0115                 qsTr("The water cycle (also known as the hydrologic cycle) is the journey water takes"
0116                      +" as it circulates from the land to the sky and back again."
0117                      +" The sun's heat provides energy to evaporate water from water bodies like oceans."),
0118                 qsTr("Plants also lose water to the air through transpiration. The water vapor "
0119                      +"cools down forming tiny droplets in clouds. When the clouds meet cool air over the land, "
0120                      +"precipitation is triggered and falls down as rain.") ,
0121                 qsTr("Some of the water is trapped between rock or clay layers, called groundwater. "
0122                      +"But most of the water flows as runoff, eventually returning to the seas via rivers."),
0123                 qsTr("Your goal is to complete the water cycle before Tux reaches home. "
0124                      +"Click on the different components which make up the water cycle. "
0125                      +"First click on the sun, then on the cloud, the water pumping station near the river, "
0126                      +"the sewage treatment, and at last regulate the switch to provide water to Tux's shower.")
0127             ]
0128         }
0129 
0130         Item {
0131             id: layoutArea
0132             width: parent.height - bar.height * 1.2
0133             height: width
0134             anchors.left: background.left
0135             states: [
0136                 State {
0137                     name: "verticalLayout"
0138                     when: items.isVertical
0139                     PropertyChanges {
0140                         target: layoutArea
0141                         width: parent.width
0142                         anchors.bottomMargin: bar.height * 0.2
0143                         anchors.leftMargin: 0
0144                     }
0145                     AnchorChanges {
0146                         target: layoutArea
0147                         anchors.top: undefined
0148                         anchors.bottom: bar.top
0149                     }
0150                 },
0151                 State {
0152                     name: "horizontalLayout"
0153                     when: !items.isVertical
0154                     PropertyChanges {
0155                         target: layoutArea
0156                         width: parent.height - bar.height * 1.2
0157                         anchors.bottomMargin: 0
0158                         anchors.leftMargin: 10 * ApplicationInfo.ratio
0159                     }
0160                     AnchorChanges {
0161                         target: layoutArea
0162                         anchors.top: parent.top
0163                         anchors.bottom: undefined
0164                     }
0165                 }
0166             ]
0167         }
0168 
0169         Image {
0170             id: sky
0171             anchors.top: layoutArea.top
0172             anchors.left: layoutArea.left
0173             width: layoutArea.width
0174             height: layoutArea.height * 0.305
0175             sourceSize.width: width
0176             sourceSize.height: height
0177             source: activity.url + "sky.svg"
0178             z: 1
0179         }
0180 
0181         Image {
0182             id: sea
0183             anchors.left: layoutArea.left
0184             anchors.bottom: layoutArea.bottom
0185             width: layoutArea.width
0186             height: layoutArea.height * 0.7
0187             sourceSize.width: width
0188             sourceSize.height: height
0189             source: activity.url + "sea.svg"
0190             z:3
0191         }
0192 
0193         Image {
0194             id: landscape
0195             anchors.fill: layoutArea
0196             sourceSize.width: width
0197             sourceSize.height: height
0198             source: activity.url + "landscape.svg"
0199             z: 6
0200         }
0201 
0202         Image {
0203             id: tuxboat
0204             opacity: 1
0205             source: activity.url + "boat.svg"
0206             width: layoutArea.width * 0.12
0207             fillMode: Image.PreserveAspectFit
0208             sourceSize.width: width
0209             anchors{
0210                 bottom: layoutArea.bottom
0211                 bottomMargin: layoutArea.height * 0.02
0212                 left: layoutArea.left
0213                 leftMargin: 0
0214             }
0215             z:30
0216             state: "tuxboatLeft"
0217 
0218             states: [
0219                 State {
0220                     name: "tuxboatLeft"
0221                     PropertyChanges {
0222                         target: tuxboat
0223                         anchors.leftMargin: 0
0224                         opacity: 1
0225                     }
0226                 },
0227                 State {
0228                     name: "tuxboatRight"
0229                     PropertyChanges {
0230                         target: tuxboat
0231                         anchors.leftMargin: layoutArea.width - tuxboat.width
0232                         opacity: 0
0233                     }
0234                 },
0235                 State {
0236                     name: "tuxboatRestarted"
0237                     PropertyChanges {
0238                         target: tuxboat
0239                         anchors.leftMargin: layoutArea.width - tuxboat.width
0240                         opacity: 0
0241                     }
0242                 }
0243             ]
0244 
0245             transitions: [
0246                 Transition {
0247                     from: "tuxboatLeft"; to: "tuxboatRight";
0248                     SequentialAnimation {
0249                         ScriptAction { script: items.audioEffects.play("qrc:/gcompris/src/activities/watercycle/resource/harbor1.wav") }
0250                         NumberAnimation { property: "anchors.leftMargin"; easing.type: Easing.InOutSine; duration: 15000 }
0251                         ScriptAction { script: items.audioEffects.play("qrc:/gcompris/src/activities/watercycle/resource/harbor2.wav") }
0252                         NumberAnimation { property: "opacity"; easing.type: Easing.InOutQuad; duration: 200 }
0253                         ScriptAction { script: {
0254                                 boatparked.opacity = 1;
0255                                 shower.stop();
0256                                 if(!sun.hasRun)
0257                                     info.setKey('start');
0258                             }
0259                         }
0260                     }
0261                 },
0262                 Transition {
0263                     from: "tuxboatRight"; to: "tuxboatLeft";
0264                     PropertyAction { properties: "anchors.leftMargin, opacity" }
0265                     ScriptAction { script: boatparked.opacity = 0 }
0266                 },
0267                 Transition {
0268                     from: "tuxboatRight, tuxboatLeft"; to: "tuxboatRestarted"
0269                     PropertyAction { properties: "anchors.leftMargin, opacity" }
0270                 }
0271             ]
0272         }
0273 
0274         Image {
0275             id: boatparked
0276             source: activity.url + "boat_parked.svg"
0277             width: layoutArea.width * 0.12
0278             fillMode: Image.PreserveAspectFit
0279             sourceSize.width: width
0280             opacity: 0
0281             anchors {
0282                 right: layoutArea.right
0283                 bottom: layoutArea.bottom
0284                 bottomMargin: tuxboat.anchors.bottomMargin
0285             }
0286             z: 29
0287             Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 200 } }
0288         }
0289 
0290         Image {
0291             id: sun
0292             source: activity.url + "sun.svg"
0293             width: layoutArea.width * 0.1
0294             fillMode: Image.PreserveAspectFit
0295             sourceSize.width: width
0296             anchors {
0297                 left: layoutArea.left
0298                 top: layoutArea.top
0299                 leftMargin: layoutArea.width * 0.056
0300                 topMargin: layoutArea.height * 0.056
0301             }
0302             z: 2
0303             property bool hasRun: false
0304             MouseArea {
0305                 id: sun_area
0306                 anchors.fill: sun
0307                 onClicked: {
0308                     if(cloud.opacity == 0)
0309                         sun.state = "sunUp";
0310                 }
0311             }
0312             state: "sunUp"
0313 
0314             states: [
0315                 State {
0316                     name: "sunDown"
0317                     PropertyChanges {
0318                         target: sun
0319                         anchors.topMargin: layoutArea.height * 0.256
0320                     }
0321                 },
0322                 State {
0323                     name: "sunUp"
0324                     PropertyChanges {
0325                         target: sun
0326                         anchors.topMargin: layoutArea.height * 0.056
0327                     }
0328                 }
0329             ]
0330 
0331             transitions: [
0332                 Transition {
0333                     from: "sunUp"; to: "sunDown";
0334                     NumberAnimation { property: "anchors.topMargin"; easing.type: Easing.InOutQuad; duration: 5000 }
0335                 },
0336                 Transition {
0337                     from: "sunDown"; to: "sunUp";
0338                     ScriptAction { script: {
0339                             items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/bleep.wav');
0340                             info.setKey('sun');
0341                             sun.hasRun = true;
0342                             vapor.animLoop = true;
0343                             vapor.state = "vaporUp";
0344                             cloud.isUp = true;
0345                         }
0346                     }
0347                     NumberAnimation { property: "anchors.topMargin"; easing.type: Easing.InOutQuad; duration: 5000 }
0348                 }
0349             ]
0350         }
0351 
0352         Image {
0353             id: vapor
0354             opacity: 0
0355             source: activity.url + "vapor.svg"
0356             width: layoutArea.width * 0.1
0357             fillMode: Image.PreserveAspectFit
0358             sourceSize.width: width
0359             property bool animLoop: false
0360             anchors {
0361                 left: sun.left
0362                 top: layoutArea.top
0363                 topMargin: layoutArea.height * 0.28
0364             }
0365             z: 10
0366             state: "vaporDown"
0367 
0368             states: [
0369                 State {
0370                     name: "vaporDown"
0371                     PropertyChanges {
0372                         target: vapor
0373                         opacity: 0
0374                         anchors.topMargin: layoutArea.height * 0.28
0375                     }
0376                 },
0377                 State {
0378                     name: "vaporUp"
0379                     PropertyChanges {
0380                         target: vapor
0381                         opacity: 1
0382                         anchors.topMargin: layoutArea.height * 0.1
0383                     }
0384                 },
0385                 State {
0386                     name: "vaporDownRestarted"
0387                     PropertyChanges {
0388                         target: vapor
0389                         opacity: 0
0390                         anchors.topMargin: layoutArea.height * 0.28
0391                     }
0392                 }
0393             ]
0394 
0395             transitions: [
0396                 Transition {
0397                     from: "vaporDown, vaporDownRestarted"; to: "vaporUp";
0398                     SequentialAnimation {
0399                         NumberAnimation { property: "opacity"; duration: 200 }
0400                         NumberAnimation { property: "anchors.topMargin"; duration: 5000 }
0401                         ScriptAction { script: vapor.state = "vaporDown" }
0402                     }
0403                 },
0404                 Transition {
0405                     from: "vaporUp"; to: "vaporDown";
0406                     SequentialAnimation {
0407                         NumberAnimation { property: "opacity"; duration: 200 }
0408                         PropertyAction { property: "anchors.topMargin" }
0409                         ScriptAction { script: {
0410                                 if(vapor.animLoop === true) {
0411                                     vapor.animLoop = false;
0412                                     vapor.state = "vaporUp";
0413                                 } else {
0414                                     info.setKey("cloud");
0415                                 }
0416                             }
0417                         }
0418                     }
0419                 },
0420                 Transition {
0421                     from: "vaporUp, vaporDown"; to: "vaporDownRestarted";
0422                     ScriptAction { script: vapor.animLoop = false }
0423                     PropertyAction { properties: "anchors.topMargin, opacity" }
0424                 }
0425             ]
0426         }
0427 
0428         Image {
0429             id: cloud
0430             opacity: 0
0431             source: activity.url + "cloud.svg"
0432             sourceSize.width: layoutArea.width * 0.256
0433             fillMode: Image.PreserveAspectFit
0434             width: 0
0435             property bool isUp: false
0436             property double originMargin: layoutArea.width * 0.05
0437             property double upMargin: layoutArea.width * 0.38
0438             anchors {
0439                 top: layoutArea.top
0440                 topMargin: originMargin
0441                 left: layoutArea.left
0442                 leftMargin: originMargin
0443             }
0444             z: 11
0445 
0446             states: [
0447                 State {
0448                     name: "cloudIsDown"
0449                     when: !cloud.isUp
0450                     PropertyChanges {
0451                         target: cloud
0452                         opacity: 0
0453                         width: 0
0454                         anchors.leftMargin: cloud.originMargin
0455                     }
0456                 },
0457                 State {
0458                     name: "cloudIsUp"
0459                     when: cloud.isUp
0460                     PropertyChanges {
0461                         target: cloud
0462                         opacity: 1
0463                         width: cloud.sourceSize.width
0464                         anchors.leftMargin: cloud.upMargin
0465                     }
0466                 }
0467             ]
0468 
0469             transitions: [
0470                 Transition {
0471                     from: "cloudIsDown"; to: "cloudIsUp";
0472                     NumberAnimation { property: "opacity"; easing.type: Easing.InOutQuad; duration: 5000 }
0473                     NumberAnimation { properties: "width, anchors.leftMargin"; easing.type: Easing.InOutQuad; duration: 15000 }
0474                 },
0475                 Transition {
0476                     from: "cloudIsUp"; to: "cloudIsDown";
0477                     PropertyAction { properties: "opacity, width, anchors.leftMargin" }
0478                 }
0479             ]
0480 
0481             MouseArea {
0482                 id: cloud_area
0483                 anchors.fill: cloud
0484                 enabled: info.newKey === 'cloud'
0485                 onClicked: {
0486                     sun.state = "sunDown";
0487                     rain.up();
0488                 }
0489             }
0490         }
0491 
0492         Image {
0493             id: rain
0494             source: activity.url + "rain.svg"
0495             width: layoutArea.height * 0.146
0496             fillMode: Image.PreserveAspectFit
0497             sourceSize.width: width
0498             opacity: 0
0499             anchors {
0500                 top: layoutArea.top
0501                 topMargin: layoutArea.width * 0.123
0502                 left: cloud.left
0503                 leftMargin: cloud.width * 0.25
0504             }
0505             z: 12
0506             Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 300 } }
0507             SequentialAnimation{
0508                 id: rainAnim
0509                 running: false
0510                 loops: 10
0511                 NumberAnimation {
0512                     target: rain
0513                     property: "scale"
0514                     duration: 500
0515                     to: 0.95
0516                 }
0517                 NumberAnimation {
0518                     target: rain
0519                     property: "scale"
0520                     duration: 500
0521                     to: 1
0522                 }
0523                 onRunningChanged: {
0524                     if(!running) {
0525                         rain.down();
0526                         cloud.isUp = false;
0527                     }
0528                 }
0529             }
0530             function up() {
0531                 items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/water.wav');
0532                 info.setKey('rain');
0533                 opacity = 1;
0534                 rainAnim.start();
0535             }
0536             function down() {
0537                 scale = 0;
0538                 opacity = 0;
0539             }
0540         }
0541 
0542         Image {
0543             id: river
0544             source: activity.url + "river.svg"
0545             width: layoutArea.width * 0.431
0546             sourceSize.width: width
0547             fillMode: Image.PreserveAspectFit
0548             opacity: level > 0 ? 1 : 0
0549             anchors {
0550                 top: layoutArea.top
0551                 left: layoutArea.left
0552                 topMargin: layoutArea.height * 0.3309
0553                 leftMargin: layoutArea.width * 0.292
0554             }
0555             z: 10
0556             Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 5000 } }
0557             property double level: 0
0558         }
0559 
0560         Image {
0561             id: reservoir1
0562             source: activity.url + "reservoir1.svg"
0563             width: layoutArea.width * 0.112
0564             fillMode: Image.PreserveAspectFit
0565             sourceSize.width: width
0566             anchors {
0567                 top: layoutArea.top
0568                 left: layoutArea.left
0569                 topMargin: layoutArea.height * 0.3309
0570                 leftMargin: layoutArea.width * 0.2948
0571             }
0572             opacity: river.level > 0.2 ? 1 : 0
0573             z: 10
0574             Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 5000 } }
0575         }
0576 
0577         Image {
0578             id: reservoir2
0579             source: activity.url + "reservoir2.svg"
0580             width: layoutArea.width * 0.1604
0581             fillMode: Image.PreserveAspectFit
0582             sourceSize.width: width
0583             anchors {
0584                 top: layoutArea.top
0585                 left: layoutArea.left
0586                 topMargin: layoutArea.height * 0.3309
0587                 leftMargin: layoutArea.width * 0.2691
0588             }
0589             opacity: river.level > 0.5 ? 1 : 0
0590             z: 10
0591             Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 5000 } }
0592         }
0593 
0594         Image {
0595             id: reservoir3
0596             source: activity.url + "reservoir3.svg"
0597             width: layoutArea.width * 0.1965
0598             fillMode: Image.PreserveAspectFit
0599             sourceSize.width: width
0600             anchors {
0601                 top: layoutArea.top
0602                 left: layoutArea.left
0603                 topMargin: layoutArea.height * 0.3309
0604                 leftMargin: layoutArea.width * 0.2532
0605             }
0606             opacity: river.level > 0.8 ? 1 : 0
0607             z: 10
0608             Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 5000 } }
0609         }
0610 
0611         Image {
0612             id: waterplant
0613             source: activity.url + "motor.svg"
0614             width: layoutArea.width * 0.083
0615             fillMode: Image.PreserveAspectFit
0616             sourceSize.width: width
0617             anchors {
0618                 top: layoutArea.top
0619                 left: layoutArea.left
0620                 topMargin: layoutArea.height * 0.367
0621                 leftMargin: layoutArea.width * 0.371
0622             }
0623             z: 20
0624             property bool running: false
0625             MouseArea {
0626                 id: motor_area
0627                 enabled: river.level > 0.2
0628                 anchors.fill: parent
0629                 onClicked: {
0630                     items.audioEffects.play('qrc:/gcompris/src/activities/watercycle/resource/bubble.wav');
0631                     info.setKey('tower');
0632                     waterplant.running = true;
0633                 }
0634             }
0635         }
0636 
0637         Image {
0638             id: fillpipe
0639             width: layoutArea.width * 0.354
0640             sourceSize.width: width
0641             fillMode: Image.PreserveAspectFit
0642             source: activity.url + "fillwater.svg"
0643             opacity: waterplant.running ? 1 : 0.2
0644             anchors {
0645                 top: layoutArea.top
0646                 left: layoutArea.left
0647                 topMargin: layoutArea.height * 0.405
0648                 leftMargin: layoutArea.width * 0.422
0649             }
0650             z: 9
0651             Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 300 } }
0652         }
0653 
0654         Image {
0655             id: sewageplant
0656             source: activity.url + "waste.svg"
0657             height: layoutArea.height * 0.144
0658             sourceSize.height: height
0659             fillMode: Image.PreserveAspectFit
0660             anchors {
0661                 top: layoutArea.top
0662                 left: layoutArea.left
0663                 topMargin: layoutArea.height * 0.778
0664                 leftMargin: layoutArea.width * 0.682
0665             }
0666             z: 11
0667             property bool running: false
0668             MouseArea {
0669                 id: waste_area
0670                 enabled: river.opacity == 1
0671                 anchors.fill: parent
0672                 onClicked: {
0673                     items.audioEffects.play('qrc:/gcompris/src/activities/watercycle/resource/bubble.wav');
0674                     info.setKey('shower');
0675                     sewageplant.running = true;
0676                 }
0677             }
0678         }
0679 
0680         Image {
0681             id: wastepipe
0682             width: layoutArea.width * 0.275
0683             sourceSize.width: width
0684             fillMode: Image.PreserveAspectFit
0685             source: activity.url + "wastewater.svg"
0686             opacity: sewageplant.running ? 1 : 0.2
0687             anchors {
0688                 top: layoutArea.top
0689                 left: layoutArea.left
0690                 topMargin: layoutArea.height * 0.597
0691                 leftMargin: layoutArea.width * 0.536
0692             }
0693             z: 10
0694             Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 300 } }
0695         }
0696 
0697         Image {
0698             id: tower
0699             source: activity.url + "watertower.svg"
0700             width: layoutArea.width * 0.135
0701             sourceSize.width: width
0702             fillMode: Image.PreserveAspectFit
0703             anchors {
0704                 top: layoutArea.top
0705                 left: layoutArea.left
0706                 topMargin: layoutArea.height * 0.226
0707                 leftMargin: layoutArea.width * 0.686
0708             }
0709             z: 10
0710             property double level: 0
0711 
0712             Image {
0713                 id: towerfill
0714                 scale: tower.level
0715                 source: activity.url + "watertowerfill.svg"
0716                 width: tower.width * 0.5
0717                 sourceSize.width: width
0718                 fillMode: Image.PreserveAspectFit
0719                 anchors {
0720                     top: tower.top
0721                     topMargin: tower.height * 0.085
0722                     horizontalCenter: tower.horizontalCenter
0723                 }
0724                 Behavior on scale { PropertyAnimation { duration: timer.interval } }
0725             }
0726         }
0727 
0728         Image {
0729             id: shower
0730             source: activity.url + "shower.svg"
0731             width: layoutArea.width * 0.184
0732             sourceSize.width: width
0733             fillMode: Image.PreserveAspectFit
0734             anchors {
0735                 top: layoutArea.top
0736                 left: layoutArea.left
0737                 topMargin: layoutArea.height * 0.557
0738                 leftMargin: layoutArea.width * 0.791
0739             }
0740             z: 10
0741             visible: false
0742             property bool on: false
0743 
0744             MouseArea {
0745                 id: shower_area
0746                 anchors.fill: parent
0747                 onClicked: {
0748                     if(!shower.on &&
0749                             wastepipe.opacity > 0.8 &&
0750                             fillpipe.opacity > 0.8 && tower.level > 0.5)
0751                         shower.start();
0752                     else
0753                         shower.stop();
0754                 }
0755             }
0756 
0757             function start() {
0758                 shower.on = true;
0759                 shower.visible = true;
0760                 tuxbath.visible = true;
0761 
0762                 if(!items.cycleDone) {
0763                     info.setKey('done');
0764                     bonus.good('smiley');
0765                     items.cycleDone = true;
0766                 }
0767                 items.audioEffects.play('qrc:/gcompris/src/activities/watercycle/resource/apert.wav');
0768             }
0769 
0770             function stop() {
0771                 shower.on = false;
0772                 shower.visible = true;
0773                 tuxbath.visible = false;
0774             }
0775             function hide() {
0776                 shower.visible = false;
0777                 shower.on = false;
0778                 tuxbath.visible = false;
0779             }
0780         }
0781 
0782         Image {
0783             id: tuxbath
0784             source: activity.url + "tuxbath.svg"
0785             width: shower.width
0786             sourceSize.width: width
0787             fillMode: Image.PreserveAspectFit
0788             anchors.centerIn: shower
0789             z: 10
0790             visible: false
0791         }
0792 
0793         Image {
0794             id: city
0795             source: activity.url + "city.svg"
0796             width: layoutArea.width * 0.202
0797             sourceSize.width: width
0798             fillMode: Image.PreserveAspectFit
0799             anchors {
0800                 top: layoutArea.top
0801                 left: layoutArea.left
0802                 topMargin: layoutArea.height * 0.465
0803                 leftMargin: layoutArea.width * 0.44
0804             }
0805             z: 10
0806         }
0807 
0808         Image {
0809             id: tuxHouse
0810             source: activity.url + "tuxHouse.svg"
0811             width: layoutArea.width * 0.036
0812             sourceSize.width: width
0813             fillMode: Image.PreserveAspectFit
0814             anchors {
0815                 top: layoutArea.top
0816                 left: layoutArea.left
0817                 topMargin: layoutArea.height * 0.638
0818                 leftMargin: layoutArea.width * 0.765
0819             }
0820             z: 10
0821         }
0822 
0823         // Manage stuff that changes periodically
0824         Timer {
0825             id: timer
0826             interval: 100
0827             running: true
0828             repeat: true
0829             onTriggered: {
0830                 if(rain.opacity > 0.9 && river.level < 1) {
0831                     river.level += 0.01;
0832                 }
0833                 if(river.level > 0 && fillpipe.opacity > 0.9 && tower.level < 1 && !shower.on) {
0834                     river.level -= 0.02;
0835                     tower.level += 0.05;
0836                 }
0837                 if(tower.level > 0 && shower.on) {
0838                     tower.level -= 0.02;
0839                 }
0840                 if(tower.level <= 0 && boatparked.opacity) {
0841                     shower.stop();
0842                 }
0843             }
0844         }
0845 
0846         GCText {
0847             id: info
0848             visible: false
0849             fontSize: smallSize
0850             font.weight: Font.DemiBold
0851             horizontalAlignment: Text.AlignHCenter
0852             anchors {
0853                 top: parent.top
0854                 topMargin: 5 * ApplicationInfo.ratio
0855                 right: parent.right
0856                 rightMargin: 5 * ApplicationInfo.ratio
0857                 left: parent.left
0858             }
0859             width: parent.width
0860             wrapMode: Text.WordWrap
0861             z: 100
0862             onTextChanged: textanim.start();
0863             property string newKey
0864 
0865             states: [
0866                 State {
0867                     name: "verticalInfo"
0868                     when: items.isVertical
0869                     PropertyChanges {
0870                         target: info
0871                         anchors.leftMargin: 5 * ApplicationInfo.ratio
0872                     }
0873                 },
0874                 State {
0875                     name: "horizontalInfoSide"
0876                     when: !items.isVertical && items.textOnSide
0877                     PropertyChanges {
0878                         target: info
0879                         anchors.leftMargin: layoutArea.width + 15 * ApplicationInfo.ratio
0880                     }
0881                 },
0882                 State {
0883                     name: "horizontalInfoOver"
0884                     when: !items.isVertical && !items.textOnSide
0885                     PropertyChanges {
0886                         target: info
0887                         anchors.leftMargin: parent.width * 0.5
0888                     }
0889                 }
0890             ]
0891 
0892             SequentialAnimation {
0893                 id: textanim
0894                 NumberAnimation {
0895                     target: info
0896                     property: "opacity"
0897                     duration: 200
0898                     from: 1
0899                     to: 0
0900                 }
0901                 ScriptAction {
0902                     script: if(items.cycleDone && info.newKey != "done") info.visible = false;
0903                 }
0904                 PropertyAction {
0905                     target: info
0906                     property: 'text'
0907                     value: items.dataset[info.newKey]
0908                 }
0909                 NumberAnimation {
0910                     target: info
0911                     property: "opacity"
0912                     duration: 200
0913                     from: 0
0914                     to: 1
0915                 }
0916             }
0917 
0918             function setKey(key) {
0919                 if(newKey != key) {
0920                     newKey = key;
0921                     textanim.start();
0922                 }
0923             }
0924         }
0925 
0926         Rectangle {
0927             id: infoBg
0928             z: 99
0929             anchors.fill: info
0930             color: '#D2D2D2'
0931             radius: width * 0.01
0932             opacity: info.text ? 0.7 : 0
0933             visible: info.visible
0934             Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 200 } }
0935         }
0936 
0937         DialogHelp {
0938             id: dialogHelp
0939             onClose: home();
0940         }
0941 
0942         Bar {
0943             id: bar
0944             content: BarEnumContent { value: help | home | reload}
0945             onHelpClicked: {
0946                 displayDialog(dialogHelp);
0947             }
0948             onHomeClicked: home()
0949             onReloadClicked: initLevel();
0950         }
0951 
0952         Bonus {
0953             id:bonus
0954         }
0955 
0956     }
0957 }