Warning, /education/gcompris/src/activities/missing-letter/MissingLetter.qml is written in an unsupported language. File is not indexed.
0001 /* GCompris - missing-letter.qml 0002 * 0003 * Copyright (C) 2014 "Amit Tomar" <a.tomar@outlook.com> 0004 * 0005 * Authors: 0006 * "Pascal Georges" <pascal.georgis1.free.fr> (GTK+ version) 0007 * "Amit Tomar" <a.tomar@outlook.com> (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 "qrc:/gcompris/src/core/core.js" as Core 0016 import "missing-letter.js" as Activity 0017 0018 ActivityBase { 0019 id: activity 0020 0021 onStart: focus = true 0022 onStop: {} 0023 0024 // When going on configuration, it steals the focus and re set it to the activity. 0025 // We need to set it back to the textinput item in order to have key events. 0026 onFocusChanged: { 0027 if(focus) { 0028 Activity.focusTextInput() 0029 } 0030 } 0031 pageComponent: Image { 0032 id: background 0033 source: Activity.url + "background.svg" 0034 sourceSize.width: width 0035 sourceSize.height: height 0036 fillMode: Image.PreserveAspectCrop 0037 0038 // system locale by default 0039 property string locale: "system" 0040 0041 property bool englishFallback: false 0042 property bool downloadWordsNeeded: false 0043 0044 signal start 0045 signal stop 0046 0047 Component.onCompleted: { 0048 dialogActivityConfig.initialize() 0049 activity.start.connect(start) 0050 activity.stop.connect(stop) 0051 } 0052 0053 // Add here the QML items you need to access in javascript 0054 QtObject { 0055 id: items 0056 property Item main: activity.main 0057 property alias background: background 0058 property int currentLevel: activity.currentLevel 0059 property alias bonus: bonus 0060 property alias score: score 0061 property alias questionImage: questionImage 0062 property alias questionText: questionText 0063 property alias questionAnim: questionAnim 0064 property alias answers: answers 0065 property GCAudio audioVoices: activity.audioVoices 0066 property alias englishFallbackDialog: englishFallbackDialog 0067 property alias parser: parser 0068 property alias locale: background.locale 0069 property string answer 0070 property alias textinput: textinput 0071 property bool isGoodAnswer: false 0072 property bool buttonsBlocked: false 0073 } 0074 0075 onStart: { 0076 Activity.init(items) 0077 Activity.focusTextInput() 0078 Activity.start() 0079 } 0080 onStop: { 0081 Activity.stop() 0082 } 0083 0084 function goodAnswer() { 0085 items.buttonsBlocked = true; 0086 score.currentSubLevel++; 0087 score.playWinAnimation(); 0088 questionAnim.start(); 0089 Activity.showAnswer(); 0090 } 0091 0092 TextInput { 0093 // Helper element to capture composed key events like french รด which 0094 // are not available via Keys.onPressed() on linux. Must be 0095 // disabled on mobile! 0096 id: textinput 0097 anchors.centerIn: background 0098 enabled: !ApplicationInfo.isMobile 0099 focus: true 0100 visible: false 0101 0102 onTextChanged: { 0103 if (text != '') { 0104 var typedText = text 0105 var answerText = Activity.getCurrentQuestion().answer 0106 if(ApplicationSettings.fontCapitalization === Font.AllUppercase) 0107 typedText = text.toLocaleUpperCase() 0108 else if(ApplicationSettings.fontCapitalization === Font.AllLowercase) 0109 typedText = text.toLocaleLowerCase() 0110 0111 if(!items.isGoodAnswer && (typedText === answerText)) { 0112 background.goodAnswer(); 0113 } 0114 text = ''; 0115 } 0116 } 0117 0118 Keys.onTabPressed: bar.repeatClicked(); 0119 } 0120 0121 Item { 0122 id: layoutArea 0123 anchors.top: score.bottom 0124 anchors.bottom: bar.top 0125 anchors.bottomMargin: bar.height * 0.4 0126 anchors.left: background.left 0127 anchors.right: background.right 0128 anchors.margins: 10 * ApplicationInfo.ratio 0129 } 0130 0131 Item { 0132 id: questionArea 0133 width: Math.min(layoutArea.width, layoutArea.height) 0134 height: width 0135 anchors.centerIn: layoutArea 0136 } 0137 0138 // Buttons with possible answers shown on the left of screen 0139 Column { 0140 id: buttonHolder 0141 spacing: 10 * ApplicationInfo.ratio 0142 anchors.left: questionArea.left 0143 anchors.top: questionArea.top 0144 0145 add: Transition { 0146 NumberAnimation { properties: "y"; from: holder.y; duration: 500 } 0147 } 0148 0149 Repeater { 0150 id: answers 0151 0152 AnswerButton { 0153 width: questionArea.width - holder.width - 10 * ApplicationInfo.ratio 0154 height: (holder.height 0155 - buttonHolder.spacing * answers.model.length) / answers.model.length 0156 textLabel: modelData 0157 blockAllButtonClicks: items.buttonsBlocked 0158 isCorrectAnswer: modelData === items.answer 0159 onPressed: { 0160 items.buttonsBlocked = true 0161 if(!items.isGoodAnswer) { 0162 modelData == items.answer ? background.goodAnswer() : '' 0163 } 0164 } 0165 onIncorrectlyPressed: items.buttonsBlocked = false 0166 } 0167 } 0168 } 0169 0170 // Picture holder for different images being shown 0171 Rectangle { 0172 id: holder 0173 width: questionArea.width * 0.7 0174 height: questionArea.height 0175 anchors.top: questionArea.top 0176 anchors.right: questionArea.right 0177 color: "white" 0178 radius: 10 0179 border.width: 2 0180 border.color: "#373737" 0181 gradient: Gradient { 0182 GradientStop { position: 0.0; color: "#80FFFFFF" } 0183 GradientStop { position: 0.9; color: "#80EEEEEE" } 0184 GradientStop { position: 1.0; color: "#80AAAAAA" } 0185 } 0186 0187 Image { 0188 id: questionImage 0189 anchors.horizontalCenter: holder.horizontalCenter 0190 anchors.top: holder.top 0191 width: holder.width 0192 height: width 0193 fillMode: Image.PreserveAspectFit 0194 } 0195 0196 Rectangle { 0197 id: questionTextBg 0198 width: holder.width 0199 height: holder.height - questionImage.height 0200 anchors.horizontalCenter: holder.horizontalCenter 0201 anchors.top: questionImage.bottom 0202 radius: 10 0203 color: "#373737" 0204 0205 GCText { 0206 id: questionText 0207 horizontalAlignment: Text.AlignHCenter 0208 verticalAlignment: Text.AlignVCenter 0209 color: "#f2f2f2" 0210 anchors.centerIn: parent 0211 width: parent.width * 0.9 0212 height: parent.height * 0.9 0213 font.pointSize: NaN // need to clear font.pointSize explicitly 0214 fontSizeMode: Text.Fit 0215 minimumPixelSize: 10 0216 font.pixelSize: width * 0.2 0217 0218 SequentialAnimation { 0219 id: questionAnim 0220 NumberAnimation { 0221 target: questionText 0222 property: 'scale' 0223 to: 1.05 0224 duration: 500 0225 easing.type: Easing.OutQuad 0226 } 0227 NumberAnimation { 0228 target: questionText 0229 property: 'scale' 0230 to: 0.95 0231 duration: 1000 0232 easing.type: Easing.OutQuad 0233 } 0234 NumberAnimation { 0235 target: questionText 0236 property: 'scale' 0237 to: 1.0 0238 duration: 500 0239 easing.type: Easing.OutQuad 0240 } 0241 ScriptAction { 0242 script: Activity.nextSubLevel() 0243 } 0244 } 0245 } 0246 } 0247 } 0248 0249 Score { 0250 id: score 0251 anchors.bottom: undefined 0252 anchors.bottomMargin: 10 * ApplicationInfo.ratio 0253 anchors.right: parent.right 0254 anchors.rightMargin: 10 * ApplicationInfo.ratio 0255 anchors.top: parent.top 0256 } 0257 0258 DialogChooseLevel { 0259 id: dialogActivityConfig 0260 currentActivity: activity.activityInfo 0261 onClose: { 0262 home() 0263 } 0264 onSaveData: { 0265 levelFolder = dialogActivityConfig.chosenLevels 0266 currentActivity.currentLevels = dialogActivityConfig.chosenLevels 0267 ApplicationSettings.setCurrentLevels(currentActivity.name, dialogActivityConfig.chosenLevels) 0268 } 0269 onLoadData: { 0270 if(activityData && activityData["locale"]) { 0271 background.locale = Core.resolveLocale(activityData["locale"]); 0272 } 0273 else { 0274 background.locale = Core.resolveLocale(background.locale); 0275 } 0276 } 0277 onStartActivity: { 0278 background.stop() 0279 background.start() 0280 } 0281 } 0282 0283 DialogHelp { 0284 id: dialogHelp 0285 onClose: home() 0286 } 0287 0288 Bar { 0289 id: bar 0290 level: items.currentLevel + 1 0291 content: BarEnumContent { value: help | home | level | repeat | activityConfig } 0292 onHelpClicked: displayDialog(dialogHelp) 0293 onPreviousLevelClicked: Activity.previousLevel() 0294 onNextLevelClicked: Activity.nextLevel() 0295 onHomeClicked: activity.home() 0296 onRepeatClicked: { 0297 if(!audioVoices.isPlaying() && !items.buttonsBlocked) { 0298 Activity.playCurrentWord() 0299 } 0300 } 0301 onActivityConfigClicked: { 0302 displayDialog(dialogActivityConfig) 0303 } 0304 } 0305 0306 Bonus { 0307 id: bonus 0308 onStart: items.buttonsBlocked = true 0309 onStop: items.buttonsBlocked = false 0310 Component.onCompleted: win.connect(Activity.nextLevel) 0311 } 0312 0313 JsonParser { 0314 id: parser 0315 onError: console.error("missing letter: Error parsing json: " + msg); 0316 } 0317 0318 Loader { 0319 id: englishFallbackDialog 0320 sourceComponent: GCDialog { 0321 parent: activity 0322 isDestructible: false 0323 message: qsTr("We are sorry, we don't have yet a translation for your language.") + " " + 0324 qsTr("GCompris is developed by the KDE community, you can translate GCompris by joining a translation team on <a href=\"%2\">%2</a>").arg("https://l10n.kde.org/") + 0325 "<br /> <br />" + 0326 qsTr("We switched to English for this activity but you can select another language in the configuration dialog.") 0327 onClose: background.englishFallback = false 0328 } 0329 anchors.fill: parent 0330 focus: true 0331 active: background.englishFallback 0332 onStatusChanged: if (status == Loader.Ready) item.start() 0333 } 0334 0335 } 0336 }