Warning, /education/gcompris/src/core/AnswerButton.qml is written in an unsupported language. File is not indexed.

0001 /*
0002   Copied in GCompris from Touch'n'learn
0003     Touch'n'learn - Fun and easy mobile lessons for kids
0004     SPDX-FileCopyrightText: 2010, 2011 Alessandro Portale <alessandro@casaportale.de>
0005     http://touchandlearn.sourceforge.net / https://github.com/aportale/qtouchandlearn/blob/master/src/qml/touchandlearn/AnswerButton.qml
0006     This file is part of Touch'n'learn
0007 
0008     SPDX-License-Identifier: GPL-3.0-or-later
0009 */
0010 
0011 import QtQuick 2.12
0012 import GCompris 1.0
0013 
0014 /**
0015  * A QML component to display an answer button.
0016  *
0017  * AnswerButton consists of a text (@ref textLabel)
0018  * and animations on pressed.
0019  * Mostly used to present more than one option to select from
0020  * consisting of both good and bad answers.
0021  *
0022  * @inherit QtQuick.Item
0023  */
0024 Item {
0025     id: button
0026 
0027     /**
0028      * type:string
0029      * Text to display on the button.
0030      *
0031      * @sa label.text
0032      */
0033     property string textLabel
0034 
0035     /**
0036      * type:boolean
0037      *
0038      * Set to true when this element contains good answer.
0039      */
0040     property bool isCorrectAnswer: false
0041 
0042     /**
0043      * type:color
0044      *
0045      * Color of the container in normal state.
0046      */
0047     property color normalStateColor: "#fff"
0048 
0049     /**
0050      * type:color
0051      *
0052      * Color of the container on good answer selection.
0053      */
0054     property color correctStateColor: "#09f"
0055 
0056     /**
0057      * type:color
0058      *
0059      * Color of the container on bad answer selection.
0060      */
0061     property color wrongStateColor: "#f66"
0062 
0063     /**
0064      * type: bool
0065      *
0066      * Set the external conditions to this variable during which the clicks on button are to be blocked.
0067      */
0068     property bool blockAllButtonClicks: false
0069 
0070     /**
0071      * type:bool
0072      *
0073      * This variable holds the overall events during which the clicks on button will be blocked.
0074      */
0075     readonly property bool blockClicks: correctAnswerAnimation.running || wrongAnswerAnimation.running || blockAllButtonClicks
0076 
0077     /**
0078      * type:int
0079      *
0080      * Amplitude of the shake animation on wrong answer selection.
0081      */
0082     property int wrongAnswerShakeAmplitudeCalc: width * 0.2
0083 
0084     /**
0085      * type:int
0086      *
0087      * Minimum amplitude of the shake animation on wrong answer selection.
0088      */
0089     property int wrongAnswerShakeAmplitudeMin: 45
0090 
0091     /**
0092      * type:int
0093      *
0094      * Amplitude of the shake animation on wrong answer.
0095      * Selects min. from wrongAnswerShakeAmplitudeMin && wrongAnswerShakeAmplitudeCalc.
0096      */
0097     property int wrongAnswerShakeAmplitude: wrongAnswerShakeAmplitudeCalc < wrongAnswerShakeAmplitudeMin ? wrongAnswerShakeAmplitudeMin : wrongAnswerShakeAmplitudeCalc
0098 
0099     // If you want the sound effects just pass the audioEffects
0100     property GCSfx audioEffects
0101 
0102     /**
0103      * Emitted after button is pressed as a good answer.
0104      *
0105      * Triggered at the end of correctAnswerAnimation.
0106      */
0107     signal correctlyPressed
0108 
0109     /**
0110      * Emitted after button is pressed as a bad answer.
0111      *
0112      * Triggered at the end of wrongAnswerAnimation.
0113      */
0114     signal incorrectlyPressed
0115 
0116     /**
0117      * Emitted when answer button is clicked.
0118      */
0119     signal pressed
0120     onPressed: {
0121         if (isCorrectAnswer) {
0122             if(audioEffects)
0123                 audioEffects.play("qrc:/gcompris/src/core/resource/sounds/completetask.wav")
0124             correctAnswerAnimation.start();
0125         } else {
0126             if(audioEffects)
0127                 audioEffects.play("qrc:/gcompris/src/core/resource/sounds/crash.wav")
0128             wrongAnswerAnimation.start();
0129         }
0130     }
0131 
0132     Rectangle {
0133         id: rect
0134         anchors.fill: parent
0135         color: normalStateColor
0136         opacity: 0.5
0137     }
0138     ParticleSystemStarLoader {
0139         id: particles
0140     }
0141     Image {
0142         source: "qrc:/gcompris/src/core/resource/button.svg"
0143         sourceSize { height: parent.height; width: parent.width }
0144         width: sourceSize.width
0145         height: sourceSize.height
0146         smooth: false
0147     }
0148     GCText {
0149         id: label
0150         anchors.centerIn: parent
0151         anchors.horizontalCenterOffset: 0
0152         horizontalAlignment: Text.AlignHCenter
0153         width: button.width
0154         fontSizeMode: Text.Fit
0155         font.bold: true
0156         text: textLabel
0157         color: "#373737"
0158     }
0159 
0160     MouseArea {
0161         id: mouseArea
0162         anchors.fill: parent
0163         enabled: !blockClicks
0164         onPressed: button.pressed()
0165     }
0166 
0167     SequentialAnimation {
0168         id: correctAnswerAnimation
0169         onStopped: correctlyPressed()
0170         ScriptAction {
0171             script: {
0172                 if (typeof(feedback) === "object")
0173                     feedback.playCorrectSound();
0174                 if (typeof(particles) === "object")
0175                     particles.burst(40);
0176             }
0177         }
0178         PropertyAction {
0179             target: rect
0180             property: "color"
0181             value: correctStateColor
0182         }
0183         PropertyAnimation {
0184             target: rect
0185             property: "color"
0186             to: normalStateColor
0187             duration: 700
0188         }
0189         PauseAnimation {
0190             duration: 300 // Wait for particles to finish
0191         }
0192     }
0193 
0194     SequentialAnimation {
0195         id: wrongAnswerAnimation
0196         onStopped: incorrectlyPressed()
0197         ParallelAnimation {
0198             SequentialAnimation {
0199                 PropertyAction {
0200                     target: rect
0201                     property: "color"
0202                     value: wrongStateColor
0203                 }
0204                 ScriptAction {
0205                     script: {
0206                         if (typeof(feedback) === "object")
0207                             feedback.playIncorrectSound();
0208                     }
0209                 }
0210                 PropertyAnimation {
0211                     target: rect
0212                     property: "color"
0213                     to: normalStateColor
0214                     duration: 600
0215                 }
0216             }
0217             SequentialAnimation {
0218                 PropertyAnimation {
0219                     target: label
0220                     property: "anchors.horizontalCenterOffset"
0221                     to: -wrongAnswerShakeAmplitude
0222                     easing.type: Easing.InCubic
0223                     duration: 120
0224                 }
0225                 PropertyAnimation {
0226                     target: label
0227                     property: "anchors.horizontalCenterOffset"
0228                     to: wrongAnswerShakeAmplitude
0229                     easing.type: Easing.InOutCubic
0230                     duration: 220
0231                 }
0232                 PropertyAnimation {
0233                     target: label
0234                     property: "anchors.horizontalCenterOffset"
0235                     to: 0
0236                     easing { type: Easing.OutBack; overshoot: 3 }
0237                     duration: 180
0238                 }
0239             }
0240         }
0241         PropertyAnimation {
0242             target: rect
0243             property: "color"
0244             to: normalStateColor
0245             duration: 450
0246         }
0247     }
0248 }