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 }