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

0001 /* GCompris - Tutorial.qml
0002  *
0003  * SPDX-FileCopyrightText: 2017 Divyam Madaan <divyam3897@gmail.com>
0004  *
0005  * Authors:
0006  *   Divyam Madaan <divyam3897@gmail.com>
0007  *
0008  *   SPDX-License-Identifier: GPL-3.0-or-later
0009  */
0010 
0011 /*
0012  * A QML component for tutorial in activity in GCompris.
0013  *
0014  * Use Tutorial when you want to add a tutorial section which contains instructions and images.
0015  *
0016  * Contains the following basic layout elements: text (instructions), a Skip,
0017  * a Next and a Previous button to leave the tutorial or navigate through it.
0018  * The skipPressed, nextPressed, previousPressed signals are emitted when user clicks on skip, next and previous button respectively.
0019  *
0020  */
0021 
0022 /* To use the component add:
0023  * Tutorial {
0024  * id: tutorialSection
0025  * source: "sourceForTutorialBackgroundImage"
0026  * tutorialDetails: Activity.tutorialInstructions
0027  * onSkipPressed: {
0028  *      Activity.initLevel()
0029  *   }
0030  * }
0031  */
0032 import QtQuick 2.12
0033 import GCompris 1.0
0034 import "core.js" as Core
0035 
0036 Item {
0037     id: tutorialSection
0038     anchors.fill: parent
0039     focus: true
0040 
0041     /* type: int
0042      * Counter for tutorial instructions
0043      */
0044     property int tutorialNumber: 0
0045 
0046     /* Container for all the tutorial instructions */
0047     property var tutorialDetails
0048 
0049     /* Do we use image or qml files for illustrations */
0050     property bool useImage: true
0051 
0052     // Emitted when skipButton is clicked
0053     signal skipPressed
0054 
0055     // Emitted when nextButton is clicked
0056     signal nextPressed
0057 
0058     // Emitted when previousButton is clicked
0059     signal previousPressed
0060 
0061     Keys.onPressed: {
0062         if(event.key === Qt.Key_Left && previousButton.visible) {
0063             previousButton.clicked();
0064         } else if(event.key === Qt.Key_Right && nextButton.visible) {
0065             nextButton.clicked();
0066         } else if(event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
0067             skipButton.clicked();
0068         } else if(event.key === Qt.Key_Space) {
0069             if(nextButton.visible) {
0070                 nextButton.clicked();
0071             } else {
0072                 skipButton.clicked();
0073             }
0074         }
0075         event.accepted = true;
0076     }
0077 
0078     Keys.onEscapePressed: {
0079         skipButton.clicked();
0080         event.accepted = true;
0081     }
0082 
0083     Keys.onReleased: {
0084         if(event.key === Qt.Key_Back) {
0085             skipButton.clicked();
0086             event.accepted = true;
0087         }
0088     }
0089 
0090     // Tutorial instructions
0091     GCText {
0092         id: tutorialText
0093         anchors.verticalCenter: tutorialTextContainer.verticalCenter
0094         anchors.left: Core.isLeftToRightLocale(ApplicationSettings.locale) ? tutorialTextContainer.left : undefined
0095         anchors.right: Core.isLeftToRightLocale(ApplicationSettings.locale) ? undefined : tutorialTextContainer.right
0096         anchors.leftMargin: 10 * ApplicationInfo.ratio
0097         anchors.rightMargin: 10 * ApplicationInfo.ratio
0098         text: tutorialDetails ? tutorialDetails[tutorialNumber].instruction : ""
0099         fontSizeMode: Text.Fit
0100         minimumPixelSize: 10
0101         horizontalAlignment: Core.isLeftToRightLocale(ApplicationSettings.locale) ? Text.AlignLeft : Text.AlignRight
0102         verticalAlignment: Text.AlignVCenter
0103         width: parent.width - 40 * ApplicationInfo.ratio
0104         height: 0.25 * parent.height
0105         wrapMode: Text.WordWrap
0106         z: 2
0107     }
0108 
0109     MouseArea {
0110         anchors.fill: parent
0111     }
0112 
0113     Rectangle {
0114         id: tutorialTextContainer
0115         anchors.top: parent.top
0116         anchors.topMargin: 10 * ApplicationInfo.ratio
0117         anchors.horizontalCenter: parent.horizontalCenter
0118         width: tutorialText.paintedWidth + 20 * ApplicationInfo.ratio
0119         height: tutorialText.paintedHeight + 10 * ApplicationInfo.ratio
0120         opacity: 0.8
0121         radius: 10
0122         border.width: 6
0123         color: "white"
0124         border.color: "#87A6DD"
0125     }
0126 
0127     // previousButton: It emits skipPressed and navigates to previous tutorial when clicked
0128     IntroButton {
0129         id: previousButton
0130         width: parent.width / 4
0131         height: 90
0132         z: 5
0133         anchors.right: nextButton.left
0134         anchors.topMargin: 15
0135         anchors.rightMargin: 15
0136             anchors.top: tutorialTextContainer.bottom
0137         visible: tutorialNumber != 0
0138 
0139         text: qsTr("Previous")
0140 
0141         onClicked: {
0142             --tutorialNumber
0143             previousPressed()
0144         }
0145     }
0146 
0147     // nextButton: It emits nextPressed which navigates to next tutorial when clicked
0148     IntroButton {
0149         id: nextButton
0150         width: parent.width / 4
0151         height: 90
0152         z: 5
0153         anchors.right: skipButton.left
0154         anchors.topMargin: 15
0155         anchors.rightMargin: 15
0156             anchors.top: tutorialTextContainer.bottom
0157         visible: tutorialNumber != (tutorialDetails.length - 1)
0158 
0159         text: qsTr("Next")
0160 
0161         onClicked: {
0162                 ++tutorialNumber
0163             nextPressed()
0164         }
0165     }
0166 
0167     // skipButton: It emits the skipPressed signal which calls the initLevel to close the tutorial when clicked.
0168     IntroButton {
0169         id: skipButton
0170         width: parent.width / 4
0171         height: 90
0172         z: 5
0173         anchors.right: parent.right
0174         anchors.rightMargin: 15
0175         anchors.topMargin: 15
0176             anchors.top: tutorialTextContainer.bottom
0177 
0178         text: nextButton.visible ? qsTr("Skip") : qsTr("Start")
0179 
0180         onClicked: {
0181             tutorialSection.visible = false
0182                 skipPressed()
0183             }
0184     }
0185 
0186     // Image component for tutorial instructions
0187     Image {
0188         id: tutorialImage
0189         visible: useImage
0190         width: parent.width * 0.8
0191         height: (parent.height - nextButton.height) * 0.48
0192         sourceSize.height: height
0193         sourceSize.width: width
0194         fillMode: Image.PreserveAspectFit
0195         mipmap: true
0196         source: tutorialDetails && useImage ? tutorialDetails[tutorialNumber].instructionImage : ""
0197         anchors {
0198             top: previousButton.bottom
0199             topMargin: 10
0200             horizontalCenter: parent.horizontalCenter
0201         }
0202     }
0203 
0204     // Alternative QML component for tutorial instructions
0205     Loader {
0206         id: tutorialQml
0207         enabled: !tutorialImage.visible
0208         width: parent.width * 0.8
0209         height: (parent.height - nextButton.height) * 0.48
0210         source: tutorialDetails && !useImage ? tutorialDetails[tutorialNumber].instructionQml : ""
0211         anchors {
0212             top: previousButton.bottom
0213             topMargin: 10
0214             horizontalCenter: parent.horizontalCenter
0215         }
0216     }
0217 }