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

0001 /* gcompris - CardItem.qml
0002  *
0003  * SPDX-FileCopyrightText: 2014 JB BUTET <ashashiwa@gmail.com>
0004  * SPDX-FileCopyrightText: 2023 Timothée Giet <animtim@gmail.com>
0005  *
0006  * Authors:
0007  *   Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
0008  *   JB BUTET <ashashiwa@gmail.com> (Qt Quick port)
0009  *   Timothée Giet <animtim@gmail.com>
0010  *
0011  *   SPDX-License-Identifier: GPL-3.0-or-later
0012  */
0013 import QtQuick 2.12
0014 import GCompris 1.0
0015 
0016 import "../../core"
0017 import "memory.js" as Activity
0018 
0019 Flipable {
0020     id: card
0021 
0022     property var pairData
0023     property bool isBack: true
0024     property bool isShown: false
0025     property bool isFound: false
0026 
0027     property bool tuxTurn
0028 
0029     property GCAudio audioVoices
0030     property GCSfx audioEffects
0031 
0032     signal stop
0033 
0034     Component.onCompleted: {
0035         activity.stop.connect(stop);
0036     }
0037 
0038     onStop: {
0039         timer.stop();
0040         animationTimer.stop();
0041     }
0042 
0043     onIsFoundChanged: {
0044         opacity = 0
0045         timer.start()
0046     }
0047 
0048     Timer {
0049         id: timer
0050         interval: 100
0051         running: false
0052         repeat: false
0053         onTriggered: particles.burst(50)
0054     }
0055 
0056     ParticleSystemStarLoader {
0057         id: particles
0058         clip: false
0059     }
0060 
0061     Timer {
0062         id: animationTimer
0063         interval: 1500
0064         running: false
0065         repeat: false
0066         onTriggered: selectionReady()
0067     }
0068 
0069     back: Image {
0070         source: card.pairData.emptyCard
0071         width: parent.width
0072         sourceSize.width: width
0073         fillMode: Image.PreserveAspectFit
0074         anchors.centerIn: parent
0075         anchors.fill: parent
0076         Image {
0077             id: contentImage
0078             source: card.pairData.image
0079             width: parent.paintedWidth * 0.9
0080             height: parent.paintedHeight * 0.9
0081             sourceSize.width: width
0082             sourceSize.height: height
0083             anchors.centerIn: parent
0084             fillMode: Image.PreserveAspectFit
0085         }
0086         GCText {
0087             anchors.centerIn: parent
0088             width: parent.paintedWidth * 0.9
0089             height: parent.paintedHeight * 0.9
0090             fontSizeMode: Text.Fit
0091             fontSize: 64
0092             horizontalAlignment: Text.AlignHCenter
0093             verticalAlignment: Text.AlignVCenter
0094             color: "#202020"
0095             font.bold: true
0096             text: card.pairData.text
0097         }
0098         // repeater for memory-enumerate
0099         Repeater {
0100             model: card.pairData.repeaterModel
0101             Image {
0102                 source: modelData.itemSource
0103                 x: contentImage.x + contentImage.width * modelData.itemX
0104                 y: contentImage.y + contentImage.height * modelData.itemY
0105                 width: contentImage.width * modelData.itemSize
0106                 height: width
0107                 sourceSize.width: width
0108                 rotation: modelData.itemRotation
0109             }
0110         }
0111     }
0112 
0113     // Warning front and back property are reversed. Could not find
0114     // a way to display back at start time without this trick
0115     front: Image {
0116         fillMode: Image.PreserveAspectFit
0117         source: card.pairData.back
0118         sourceSize.width: parent.width
0119         anchors.centerIn: parent
0120         anchors.fill: parent
0121     }
0122 
0123     transform: Rotation {
0124         id: rotation
0125         origin.x: card.width / 2
0126         origin.y: card.height / 2
0127         axis.x: 0; axis.y: 1; axis.z: 0
0128         angle: 0
0129     }
0130 
0131     transitions: Transition {
0132         SequentialAnimation {
0133             NumberAnimation { target: rotation; property: "angle"; duration: 750 }
0134             ScriptAction { script: {
0135                 if(card.pairData.sound && !card.isBack)
0136                     audioVoices.play(card.pairData.sound)
0137                 }
0138             }
0139         }
0140     }
0141 
0142     MouseArea {
0143         anchors.fill: parent
0144         enabled: card.isBack && !card.isFound && !card.tuxTurn && items.selectionCount < 2
0145         onClicked: selected()
0146     }
0147 
0148     function selected() {
0149         card.isBack = false
0150         card.isShown = true
0151         items.selectionCount++
0152         animationTimer.start()
0153         audioEffects.play(Activity.url + "card_flip.wav")
0154     }
0155 
0156     function selectionReady() {
0157         var pairs = Activity.addPlayQueue(card)
0158         var win = Activity.reverseCardsIfNeeded()
0159         if(tuxTurn && win || tuxTurn && !pairs)
0160             Activity.tuxPlay()
0161     }
0162 
0163     Behavior on opacity { NumberAnimation { duration: 1000 } }
0164 
0165     states: [
0166         State {
0167             name: "front"
0168             PropertyChanges { target: rotation; angle: 180 }
0169             when: !card.isBack
0170         }
0171     ]
0172 }