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

0001 /* GCompris - LandSafe.qml
0002  *
0003  * SPDX-FileCopyrightText: 2016 Holger Kaelberer <holger.k@elberer.de>
0004  *
0005  * Authors:
0006  *   Matilda Bernard <serah4291@gmail.com> (GTK+ version)
0007  *   Holger Kaelberer <holger.k@elberer.de> (Qt Quick port)
0008  *
0009  *   SPDX-License-Identifier: GPL-3.0-or-later
0010  */
0011 import QtQuick 2.12
0012 import Box2D 2.0
0013 import QtQuick.Particles 2.12
0014 import GCompris 1.0
0015 
0016 import "../../core"
0017 import "land_safe.js" as Activity
0018 
0019 ActivityBase {
0020     id: activity
0021 
0022     property bool inForeground: false   // to avoid unneeded reconfigurations
0023 
0024     onStart: {
0025         inForeground = true;
0026         focus = true;
0027     }
0028     onStop: inForeground = false;
0029 
0030     Keys.onPressed: Activity.processKeyPress(event);
0031     Keys.onReleased: Activity.processKeyRelease(event);
0032 
0033     onWidthChanged: if (inForeground)
0034                         Activity.initLevel();
0035 
0036     onHeightChanged: if (inForeground)
0037                          Activity.initLevel();
0038 
0039     pageComponent: Image {
0040         id: background
0041 
0042         source: Activity.baseUrl + "/background.svg";
0043         anchors.centerIn: parent
0044         anchors.fill: parent
0045         fillMode: Image.PreserveAspectCrop
0046         sourceSize.height: height
0047 
0048         signal start
0049         signal stop
0050 
0051         function changeZoom(newZoom)
0052         {
0053             var dZoom = newZoom / items.zoom;
0054             var curAltReal = Activity.getAltitudeReal();
0055             items.world.pixelsPerMeter *= dZoom;
0056             var altPx = curAltReal * items.world.pixelsPerMeter;
0057             var rdy;
0058             var rdx;
0059             var ldx;
0060             if (dZoom < 1) {
0061                 rdy = items.rocket.height*dZoom;
0062                 rdx = items.rocket.width*dZoom/2;
0063                 ldx = items.landing.width*dZoom/2;
0064             } else {
0065                 rdy = -items.rocket.height/dZoom*2;
0066                 rdx = -items.rocket.width/dZoom;
0067                 ldx = -items.landing.width/dZoom;
0068             }
0069             items.rocket.y = Activity.pxAltitudeToY(altPx) + rdy;
0070             items.rocket.x += rdx;
0071             items.landing.anchors.leftMargin += ldx;
0072             items.zoom = newZoom;
0073             if (dZoom < 1)
0074                 Activity.zoomStack.unshift(curAltReal);
0075             else
0076                 Activity.zoomStack.shift();
0077         }
0078 
0079         Component.onCompleted: {
0080             dialogActivityConfig.initialize();
0081             activity.start.connect(start);
0082             activity.stop.connect(stop);
0083         }
0084 
0085         // Needed to get keyboard focus on IntroMessage
0086         Keys.forwardTo: intro
0087 
0088         // Add here the QML items you need to access in javascript
0089         QtObject {
0090             id: items
0091             property Item main: activity.main
0092             property alias background: background
0093             property alias bar: bar
0094             property int currentLevel: activity.currentLevel
0095             property alias bonus: bonus
0096             property alias rocket: rocket
0097             property alias leftEngine: leftEngine
0098             property alias rightEngine: rightEngine
0099             property alias bottomEngine: bottomEngine
0100             property alias explosion: explosion
0101             property alias world: physicsWorld
0102             property alias landing: landing
0103             property alias ground: ground
0104             property alias intro: intro
0105             property alias ok: ok
0106             property alias leftRightControl: leftRightControl
0107             property alias upDownControl: upDownControl
0108             property alias accelerometer: accelerometer
0109             property string accelerometerText: "<font color=\"#00FFFFFF\">-0</font>0.00"
0110             property var rocketCategory: Fixture.Category1
0111             property var groundCategory: Fixture.Category2
0112             property var landingCategory: Fixture.Category3
0113             readonly property var levels: activity.datasetLoader.data
0114             property string mode: "rotate"  // "simple"
0115             property double velocity: 0.0
0116             property string velocityText: "<font color=\"#00FFFFFF\">-0</font>0.0"
0117             property double altitude: 0.0
0118             property string altitudeText: "<font color=\"#00FFFFFF\">00</font>0"
0119             property double fuel: 100
0120             property string fuelText: "100"
0121             property double lastVelocity: 0.0
0122             property double gravity: 0.0
0123             property double scale: background.height / 400
0124             property double zoom: 1.0
0125             property bool onScreenControls: /* items.world.running && */ ApplicationInfo.isMobile
0126         }
0127 
0128         onStart: { Activity.start(items) }
0129         onStop: {
0130             timer0.stop()
0131             Activity.stop()
0132         }
0133         onVisibleChanged: visible ? physicsWorld.running = true : physicsWorld.running = false
0134 
0135         World {
0136             id: physicsWorld
0137 
0138             running: false;
0139             gravity: Qt.point(0, items.gravity)
0140             autoClearForces: false
0141             //timeStep: 1.0/60.0 // default: 60Hz
0142 
0143             onStepped: {
0144                 if(intro.visible) return;
0145                 if (Math.abs(rocket.body.linearVelocity.y) > 0.01)  // need to store velocity before it is aaaalmost 0 because of ground/landing contact
0146                     items.lastVelocity = items.velocity;
0147                 items.velocity = rocket.body.linearVelocity.y;
0148                 items.velocityText = Activity.fixedSizeString(items.velocity, 10, 5, ".0");
0149 
0150                 if (rocket.body.linearVelocity.y > Activity.maxLandingVelocity)
0151                     landing.overlayColor = "-r";  // redish
0152                 else if (explosion.visible == true)
0153                     landing.overlayColor = "-r";
0154                 else if (rocket.body.linearVelocity.y > Activity.maxLandingVelocity - 2)
0155                     landing.overlayColor = "-y";  // yellowish
0156                 else
0157                     landing.overlayColor = "-g";  // greenish
0158                 items.altitude = Math.max(0, Math.round(Activity.getAltitudeReal()));
0159                 items.altitudeText = Activity.minimum3Chars(items.altitude);
0160 
0161                 if (Activity.maxFuel != -1) {
0162                     // update fuel:
0163                     var dt = timeStep;
0164                     var dFuel = -(dt * (items.rocket.accel + items.rocket.leftAccel
0165                                         + items.rocket.rightAccel));
0166                     Activity.currentFuel = Math.max(0, Activity.currentFuel + dFuel);
0167                     items.fuel = Math.round(Activity.currentFuel / Activity.maxFuel * 100);
0168                     if (Activity.currentFuel === 0) // fuel consumed
0169                         items.rocket.accel = items.rocket.leftAccel = items.rocket.rightAccel = 0;
0170                 } else
0171                     items.fuel = 100;
0172                 items.fuelText = Activity.minimum3Chars(items.fuel);
0173                 if (items.rocket.x > background.width)
0174                     items.rocket.x = -items.rocket.width;
0175                 if (items.rocket.x < -items.rocket.width)
0176                     items.rocket.x = background.width;
0177 
0178                 if (items.rocket.y < 0)
0179                     background.changeZoom(items.zoom / 2);
0180                 else if (Activity.zoomStack.length > 0 && items.altitude < Activity.zoomStack[0]-1)
0181                     background.changeZoom(items.zoom * 2);
0182             }
0183         }
0184 
0185         MouseArea {
0186             id: mouse
0187             anchors.fill: parent
0188             onClicked: debugDraw.visible = !debugDraw.visible;
0189             enabled: Activity.debugDraw
0190         }
0191 
0192         Item {
0193             id: rocket
0194             property double accel: 0.0
0195             property double leftAccel: 0.0
0196             property double rightAccel: 0.0
0197             property alias body: rocketBody
0198 
0199             function show() {
0200                 opacity = 100;
0201             }
0202             function hide() {
0203                 opacity = 0;
0204             }
0205 
0206             Behavior on opacity {
0207                 NumberAnimation {
0208                     duration: 500
0209                     easing.type: Easing.OutExpo
0210                 }
0211             }
0212 
0213             //property float rotate
0214 
0215             rotation: 0
0216             width: items.scale * 28 * items.zoom// * ApplicationInfo.ratio
0217             height: width / 232 * 385
0218             x: 300
0219             y: 50
0220             z: 4
0221 
0222 //            Component.onCompleted: rocket.body.applyForceToCenter(Qt.point(0, 5));
0223 
0224             onAccelChanged: applyForces();
0225             onLeftAccelChanged: applyForces();
0226             onRightAccelChanged: applyForces();
0227             onRotationChanged: if (accel > 0)       // should only happen in
0228                                    applyForces();   // "rotation" mode
0229 
0230             // decompose a force/acceleration vector v using angle into x/y components
0231             function decomposeVector(v, angle) {
0232                 return Qt.point(v * Math.sin(Activity.degToRad(angle)), // x-component
0233                                 v * Math.cos(Activity.degToRad(items.rocket.rotation)));  // y-component
0234             }
0235 
0236             // map acceleration to box2d forces applying appropriate factors:
0237             function applyForces()
0238             {
0239                 var totForce = (accel / 0.5 * 5);
0240                 var v;
0241 
0242                 if (items.mode === "simple")
0243                     v = Qt.point((leftAccel-rightAccel)
0244                                  * 10 /* base of 10 m/s^2 */
0245                                  * 5,  /* factor to make movement smooth */
0246                                  -totForce
0247                                  );
0248                 else { // "rotation"
0249                     v = decomposeVector(totForce, rotation);
0250                     v.y = -v.y;
0251                 }
0252                 v.x *= items.rocket.body.getMass();
0253                 v.y *= items.rocket.body.getMass();
0254 
0255                 physicsWorld.clearForces();
0256                 items.rocket.body.applyForceToCenter(v);
0257 //                console.log("XXX rocket.acc=" + rocket.accel + " acc.current=" + items.accelerometer.current + " bottomMargin=" + items.accelerometer.currentRect.bottomMargin);
0258             }
0259 
0260             Image {
0261                 id: rocketImage
0262 
0263                 sourceSize.width: 1024
0264                 source: Activity.baseUrl + "/rocket.svg"
0265                 anchors.centerIn: parent
0266                 anchors.fill: parent
0267                 z: 4
0268                 mipmap: true
0269             }
0270 
0271             Body {
0272                 id: rocketBody
0273 
0274                 target: rocket
0275                 bodyType: Body.Dynamic
0276                 sleepingAllowed: false
0277                 fixedRotation: true
0278                 linearDamping: 0
0279                 property double rotation: Activity.degToRad(rocket.rotation % 360)
0280 
0281                 fixtures: Box {
0282                     id: rocketFixture
0283                     categories: items.rocketCategory
0284                     collidesWith: items.groundCategory | items.landingCategory
0285                     density: 1
0286                     friction: 0
0287                     restitution: 0
0288                     width: rocket.width
0289                     height: rocket.height
0290                     rotation: rocketBody.rotation
0291 
0292                     onBeginContact: {
0293                         //console.log("XXX beginning contact with " + other.getBody().target.collisionName + " abs v=" + Math.abs(items.lastVelocity) + + " maxV=" + Activity.maxLandingVelocity);
0294                         if (other.getBody().target === landing &&
0295                                 Math.abs(items.lastVelocity) <= Activity.maxLandingVelocity &&
0296                                 (items.mode === "simple" || rocket.rotation%360 === 0))
0297                             Activity.finishLevel(true);
0298                         else // ground
0299                             Activity.finishLevel(false); // crash
0300                     }
0301 //                    onEndContact: console.log("XXX ending contact with " + other.getBody().target.collisionName);
0302                 }
0303             }
0304 
0305             Image {
0306                 id: softLeftEngine
0307                 source: Activity.baseUrl + "/engine.svg"
0308                 rotation: 90
0309                 anchors.right: parent.left
0310                 anchors.verticalCenter: parent.verticalCenter
0311                 width:  rocket.leftAccel > 0 ?
0312                             rocket.width * 0.2 + rocket.width * rocket.leftAccel : 0
0313                 height:  width * 2 + width * rocket.leftAccel
0314                 sourceSize.width: width
0315                 sourceSize.height: height
0316                 visible: ApplicationInfo.useOpenGL ? false : true
0317             }
0318 
0319             ParticleSystem {
0320                 id: leftEngine
0321 
0322                 anchors.left: parent.left
0323                 anchors.leftMargin: 10
0324                 anchors.verticalCenter: parent.verticalCenter
0325                 height: 30
0326 
0327                 ImageParticle {
0328                     groups: ["flameLeft"]
0329                     source: "qrc:///particleresources/glowdot.png"
0330                     color: "#11ff400f"
0331                     colorVariation: 0.1
0332                 }
0333                 Emitter {
0334                     anchors.centerIn: parent
0335                     group: "flameLeft"
0336 
0337                     emitRate: (rocket.leftAccel > 0 ? 50 * items.scale / 1.9 : 0) * items.zoom // 50
0338                     lifeSpan: (rocket.leftAccel > 0 ? 600 * items.scale / 1.9 : 0) * items.zoom // 600
0339                     size: rocket.leftAccel > 0 ? leftEngine.height : 0
0340                     endSize: 5
0341                     sizeVariation: 3
0342                     acceleration: PointDirection { x: -40 }
0343                     velocity: PointDirection { x: -40 }
0344                 }
0345             }
0346 
0347             Image {
0348                 id: softRightEngine
0349                 source: Activity.baseUrl + "/engine.svg"
0350                 rotation: -90
0351                 anchors.left: parent.right
0352                 anchors.verticalCenter: parent.verticalCenter
0353                 width:  rocket.rightAccel > 0 ?
0354                             rocket.width * 0.2 + rocket.width * rocket.rightAccel : 0
0355                 height:  width * 2 + width * rocket.rightAccel
0356                 sourceSize.width: width
0357                 sourceSize.height: height
0358                 visible: ApplicationInfo.useOpenGL ? false : true
0359             }
0360 
0361             ParticleSystem {
0362                 id: rightEngine
0363 
0364                 anchors.right: parent.right
0365                 anchors.rightMargin: 10
0366                 anchors.verticalCenter: parent.verticalCenter
0367                 height: 30
0368 
0369                 ImageParticle {
0370                     groups: ["flameRight"]
0371                     source: "qrc:///particleresources/glowdot.png"
0372                     color: "#11ff400f"
0373                     colorVariation: 0.1
0374                 }
0375                 Emitter {
0376                     anchors.centerIn: parent
0377                     group: "flameRight"
0378 
0379                     emitRate: (rocket.rightAccel > 0 ? 50 * items.scale / 1.9 : 0) * items.zoom  // 50
0380                     lifeSpan: (rocket.rightAccel > 0 ? 600 * items.scale / 1.9 : 0) * items.zoom // 600
0381                     size: rocket.rightAccel > 0 ? rightEngine.height : 0
0382                     endSize: 5
0383                     sizeVariation: 3
0384                     acceleration: PointDirection { x: 40 }
0385                     velocity: PointDirection { x: 40 }
0386                 }
0387             }
0388 
0389             Image {
0390                 id: softBottomEngine
0391                 source: Activity.baseUrl + "/engine.svg"
0392                 anchors.top: parent.bottom
0393                 anchors.topMargin: -5 * ApplicationInfo.ratio
0394                 anchors.horizontalCenter: parent.horizontalCenter
0395                 width:  rocket.width * 0.5 + rocket.width * rocket.accel
0396                 height: rocket.accel > 0 ? width * 2 : 0
0397                 sourceSize.width: width
0398                 sourceSize.height: height
0399                 visible: ApplicationInfo.useOpenGL ? false : true
0400             }
0401 
0402             ParticleSystem {
0403                 id: bottomEngine
0404                 anchors.top: parent.bottom
0405                 anchors.topMargin: 5
0406                 anchors.horizontalCenter: parent.horizontalCenter
0407                 width: rocket.width
0408 
0409                 ImageParticle {
0410                     groups: ["flame"]
0411                     source: "qrc:///particleresources/glowdot.png"
0412                     color: "#11ff400f"
0413                     colorVariation: 0.1
0414                 }
0415                 Emitter {
0416                     anchors.centerIn: parent
0417                     group: "flame"
0418 
0419                     emitRate: (rocket.accel > 0 ? (80 + 60 * rocket.accel) : 0) * items.zoom // 75-150
0420                     lifeSpan: ((700 + 450 * rocket.accel) * items.scale / 2.5) * items.zoom // 500 - 1000
0421                     size: rocket.width/1.8 + rocket.width/2*rocket.accel // width*-0.5 - width
0422                     endSize: size/1.85
0423                     sizeVariation: 5
0424                     acceleration: PointDirection { y: 80 }
0425                     velocity: PointDirection { y: 80 }
0426                 }
0427             }
0428 
0429          }
0430 
0431         ParticleSystem {
0432             id: explosion
0433             anchors.centerIn: rocket
0434             width: rocket.width
0435             z: 5
0436 
0437             ImageParticle {
0438                 groups: ["flame"]
0439                 source: "qrc:///particleresources/glowdot.png"
0440                 color: "#11ff400f"
0441                 colorVariation: 0.1
0442             }
0443             Emitter {
0444                 anchors.centerIn: parent
0445                 group: "flame"
0446                 emitRate: 75 // 75-150
0447                 lifeSpan: 300 // 500 - 1000
0448                 size: rocket.width * 3 // width*-0.5 - width
0449                 endSize: 0
0450                 sizeVariation: 5
0451                 acceleration: PointDirection { x: 0 }
0452                 velocity: PointDirection { x: 0 }
0453             }
0454 
0455             Timer {
0456                 id: timer0
0457                 interval: 600; running: false; repeat: false
0458                 onTriggered: explosion.opacity = 0
0459             }
0460 
0461             function show() {
0462                 visible = true;
0463                 opacity = 100
0464                 scale = 1;
0465                 timer0.running = true
0466             }
0467             function hide() {
0468                 visible = false;
0469                 scale = 0;
0470                 timer0.running = false
0471             }
0472 
0473             Behavior on opacity {
0474                 NumberAnimation {
0475                     duration: 300
0476                     easing.type: Easing.InExpo
0477                 }
0478             }
0479 
0480         }
0481 
0482         Image {
0483             id: ground
0484 
0485             z: 1
0486             width: parent.width
0487             height: parent.height/7
0488             sourceSize.width: width
0489             sourceSize.height: height
0490             source: Activity.baseUrl + "/ground.svg"
0491             anchors.left: parent.left
0492             anchors.right: parent.right
0493             anchors.bottom: parent.bottom
0494 
0495             readonly property string collisionName: "ground"
0496             property int surfaceOffset: height/2
0497 
0498             Body {
0499                 id: groundBody
0500 
0501                 target: ground
0502                 bodyType: Body.Static
0503                 sleepingAllowed: true
0504                 fixedRotation: true
0505                 linearDamping: 0
0506 
0507                 fixtures: Box {
0508                     id: groundFixture
0509 
0510                     categories: items.groundCategory
0511                     collidesWith: items.rocketCategory
0512                     density: 1
0513                     friction: 0
0514                     restitution: 0
0515                     width: ground.width
0516                     height: ground.height - ground.surfaceOffset
0517                     x: 0
0518                     y: ground.surfaceOffset
0519                 }
0520             }
0521         }
0522 
0523 
0524         Image {
0525             id: landing
0526 
0527             readonly property string collisionName: "landing"
0528             property int surfaceOffset: landing.height * 0.8
0529             property string overlayColor: "-g"
0530 
0531             z: 2
0532             source: Activity.baseUrl + "/landing" + overlayColor + ".svg";
0533             anchors.left: ground.left
0534             anchors.leftMargin: 270
0535             anchors.top: ground.top
0536             anchors.topMargin: ground.surfaceOffset - height
0537             width: 66 * items.scale * items.zoom
0538             height: width / 7 * 2
0539 
0540             Body {
0541                 id: landingBody
0542 
0543                 target: landing
0544                 bodyType: Body.Static
0545                 sleepingAllowed: true
0546                 fixedRotation: true
0547                 linearDamping: 0
0548 
0549                 fixtures: Box {
0550                     id: landingFixture
0551 
0552                     categories: items.landingCategory
0553                     collidesWith: items.rocketCategory
0554                     density: 1
0555                     friction: 0
0556                     restitution: 0
0557                     width: landing.width
0558                     height: landing.height - landing.surfaceOffset
0559                     y: landing.surfaceOffset
0560                 }
0561             }
0562         }
0563 
0564         Item {
0565             id: osdWrapper
0566 
0567             anchors.right: background.right
0568             anchors.rightMargin: 10 * ApplicationInfo.ratio
0569             anchors.bottom: bar.top
0570             anchors.bottomMargin: 20 * ApplicationInfo.ratio
0571             anchors.top: background.top
0572             width: 200
0573             height: background.height
0574             z: 2
0575             property int itemsMargin: 6 * ApplicationInfo.ratio
0576 
0577             GCText {
0578                 id: fuelText
0579                 anchors.right: parent.right
0580                 anchors.bottom: altitudeText.top
0581                 anchors.bottomMargin: osdWrapper.itemsMargin
0582                 color: "white"
0583                 fontSize: tinySize
0584                 horizontalAlignment: Text.AlignRight
0585                 text: qsTr("Fuel: %1").arg(items.fuelText)
0586             }
0587             GCText {
0588                 id: altitudeText
0589                 anchors.right: parent.right
0590                 anchors.bottom: velocityText.top
0591                 anchors.bottomMargin: osdWrapper.itemsMargin
0592                 color: "white"
0593                 fontSize: tinySize
0594                 horizontalAlignment: Text.AlignRight
0595                 text: qsTr("Altitude: %1").arg(items.altitudeText)
0596             }
0597             GCText {
0598                 id: velocityText
0599                 anchors.right: parent.right
0600                 anchors.bottom: accelText.top
0601                 anchors.bottomMargin: osdWrapper.itemsMargin
0602                 color: "white"
0603                 fontSize: tinySize
0604                 horizontalAlignment: Text.AlignRight
0605                 text: qsTr("Velocity: %1").arg(items.velocityText)
0606             }
0607 
0608             GCText {
0609                 id: accelText
0610                 anchors.bottom: accelerometer.top
0611                 anchors.bottomMargin: osdWrapper.itemsMargin
0612                 anchors.right: parent.right
0613                 fontSize: tinySize
0614                 color: "white"
0615                 horizontalAlignment: Text.AlignRight
0616                 text: qsTr("Acceleration: %1").arg(items.accelerometerText)
0617             }
0618 
0619             Accelerometer {
0620                 id: accelerometer
0621                 current: rocket.decomposeVector(rocket.accel, rocket.rotation).y * 10 - items.gravity
0622                 anchors.right: parent.right
0623                 anchors.bottom: planetText.top
0624                 anchors.bottomMargin: osdWrapper.itemsMargin
0625                 width: 15 + 3 * items.scale * ApplicationInfo.ratio
0626                 height: upDownControl.height
0627                 z: 2 // on top of rocket and ground
0628                 opacity: 1
0629                 onCurrentChanged: {
0630                     items.accelerometerText = Activity.fixedSizeString(accelerometer.current, 100, 6, ".00");
0631                 }
0632             }
0633             GCText {
0634                 id: planetText
0635                 anchors.right: parent.right
0636                 anchors.bottom: gravityText.top
0637                 anchors.bottomMargin: osdWrapper.itemsMargin
0638                 color: "white"
0639                 fontSize: tinySize
0640                 horizontalAlignment: Text.AlignRight
0641                 text: (items.levels && items.levels[bar.level-1]) ? items.levels[bar.level-1].planet : ""
0642             }
0643             GCText {
0644                 id: gravityText
0645                 anchors.bottom: parent.bottom
0646                 anchors.right: parent.right
0647                 horizontalAlignment: Text.AlignRight
0648                 fontSize: tinySize
0649                 color: "white"
0650                 text: qsTr("Gravity: %1").arg(Math.round(items.gravity * 100) / 100);
0651             }
0652         }
0653 
0654         Column {
0655             id: upDownControl
0656             anchors.right: background.right
0657             anchors.rightMargin: accelerometer.width
0658             anchors.bottom: bar.top
0659             anchors.bottomMargin: 32 * ApplicationInfo.ratio + gravityText.height + planetText.height
0660             width: upButton.width + 20 * ApplicationInfo.ratio
0661             height: upButton.height + downButton.height + 20 * ApplicationInfo.ratio
0662             visible: items.onScreenControls
0663 
0664             z: 19 // below intro, above the rest
0665             opacity: 0.4
0666             spacing: 20 * ApplicationInfo.ratio
0667 
0668             ControlButton {
0669                 id: upButton
0670                 source: "qrc:/gcompris/src/core/resource/arrow_up.svg"
0671                 onPressed: Activity.processKeyPress({key: Qt.Key_Up});
0672                 exceed: upDownControl.spacing / 2
0673             }
0674 
0675             ControlButton {
0676                 id: downButton
0677                 source: "qrc:/gcompris/src/core/resource/arrow_down.svg"
0678                 onPressed: Activity.processKeyPress({key: Qt.Key_Down});
0679                 exceed: upDownControl.spacing / 2
0680             }
0681         }
0682 
0683         Row {
0684             id: leftRightControl
0685             anchors.left: parent.left
0686             anchors.leftMargin: 10 * ApplicationInfo.ratio
0687             anchors.bottom: upDownControl.bottom
0688             width: leftButton.width + rightButton.width + 20 * ApplicationInfo.ratio
0689             height: leftButton.height + 10 * ApplicationInfo.ratio
0690             visible: items.onScreenControls
0691 
0692             z: 19 // below intro, on top of the rest
0693             opacity: 0.4
0694             spacing: 20 * ApplicationInfo.ratio
0695 
0696             ControlButton {
0697                 id: leftButton
0698                 source: "qrc:/gcompris/src/core/resource/arrow_left.svg"
0699                 onPressed: Activity.processKeyPress({key: Qt.Key_Left});
0700                 onReleased: Activity.processKeyRelease({key: Qt.Key_Left});
0701                 exceed: leftRightControl.spacing / 2
0702             }
0703 
0704             ControlButton {
0705                 id: rightButton
0706                 source: "qrc:/gcompris/src/core/resource/arrow_right.svg"
0707                 onPressed: Activity.processKeyPress({key: Qt.Key_Right});
0708                 onReleased: Activity.processKeyRelease({key: Qt.Key_Right});
0709                 exceed: leftRightControl.spacing / 2
0710             }
0711         }
0712 
0713         DebugDraw {
0714             id: debugDraw
0715             world: physicsWorld
0716             visible: false
0717             z: 1
0718         }
0719 
0720         DialogHelp {
0721             id: dialogHelp
0722             onClose: home();
0723         }
0724 
0725         DialogChooseLevel {
0726             id: dialogActivityConfig
0727             currentActivity: activity.activityInfo
0728 
0729             onSaveData: {
0730                 levelFolder = dialogActivityConfig.chosenLevels;
0731                 currentActivity.currentLevels = dialogActivityConfig.chosenLevels;
0732                 ApplicationSettings.setCurrentLevels(currentActivity.name, dialogActivityConfig.chosenLevels);
0733             }
0734             onClose: {
0735                 home();
0736             }
0737             onStartActivity: {
0738                 background.stop();
0739                 background.start();
0740             }
0741         }
0742 
0743         Bar {
0744             id: bar
0745             level: items.currentLevel + 1
0746             z: 21
0747             content: BarEnumContent { value: help | home | level | reload | activityConfig }
0748             onHelpClicked: displayDialog(dialogHelp);
0749             onPreviousLevelClicked: Activity.previousLevel();
0750             onNextLevelClicked: Activity.nextLevel();
0751             onHomeClicked: home();
0752             onReloadClicked: Activity.initLevel();
0753             onActivityConfigClicked: {
0754                 displayDialog(dialogActivityConfig);
0755             }
0756         }
0757 
0758         Bonus {
0759             id: bonus
0760             Component.onCompleted: {
0761                 loose.connect(Activity.initLevel);
0762                 win.connect(Activity.nextLevel);
0763             }
0764         }
0765 
0766         IntroMessage {
0767             id: intro
0768             onIntroDone: {
0769                 items.world.running = true;
0770             }
0771             z: 20
0772             anchors {
0773                 top: parent.top
0774                 topMargin: 10
0775                 right: parent.right
0776                 rightMargin: 5
0777                 left: parent.left
0778                 leftMargin: 5
0779             }
0780         }
0781 
0782         BarButton {
0783             id: ok
0784             source: "qrc:/gcompris/src/core/resource/bar_ok.svg";
0785             sourceSize.width: 75 * ApplicationInfo.ratio
0786             visible: false
0787             anchors.centerIn: background
0788             onClicked: {
0789                 visible = false;
0790                 items.world.running = true;
0791             }
0792         }
0793     }
0794 
0795 }