Warning, /education/gcompris/src/core/Bar.qml is written in an unsupported language. File is not indexed.
0001 /* GCompris - Bar.qml 0002 * 0003 * SPDX-FileCopyrightText: 2014-2016 Bruno Coudoin <bruno.coudoin@gcompris.net> 0004 * 0005 * Authors: 0006 * Bruno Coudoin <bruno.coudoin@gcompris.net> 0007 * 0008 * SPDX-License-Identifier: GPL-3.0-or-later 0009 */ 0010 import QtQuick 2.12 0011 import GCompris 1.0 0012 import "qrc:/gcompris/src/core/core.js" as Core 0013 0014 /** 0015 * A QML component for GCompris' navigation bar. 0016 * @ingroup components 0017 * 0018 * The Bar is visible in all activities and the main menu screen. It can be 0019 * hidden by clicking on the 'toggle' region. 0020 * 0021 * It can consist of a couple of child-elements, mostly buttons, defined 0022 * in the BarEnumContent container. An activity can define which elements its bar should 0023 * present using the content property. In most cases it contains at least 0024 * BarEnumContent.help, BarEnumContent.home and BarEnumContent.level. 0025 * 0026 * Cf. the BarEnumContent container for a full list of available Bar elements. 0027 * 0028 * Cf. the Bar object used in Template.qml as an example of how a minimal 0029 * Bar implementation should look like. 0030 * 0031 * @sa BarButton, BarEnumContent 0032 * @inherit QtQuick.Item 0033 */ 0034 Item { 0035 id: bar 0036 0037 /** 0038 * type: real 0039 * Minimum size for BarZoom 0040 */ 0041 readonly property real minWidth: (parent.width - 20 - 0042 10 * ApplicationInfo.ratio) / (totalWidth + textLength) 0043 0044 /** 0045 * type: real 0046 * Maximum size for barZoom 0047 */ 0048 readonly property real maxWidth: 1.2 * ApplicationInfo.ratio 0049 0050 /** 0051 * type: real 0052 * Length of level String 0053 */ 0054 property real textLength 0055 0056 /** 0057 * type: real 0058 * The maximum size allowed for the bar 0059 */ 0060 readonly property real maxBarWidth: (totalWidth+textLength) * maxWidth + 0061 (numberOfButtons - 1) * 5 + 10 * ApplicationInfo.ratio 0062 /** 0063 * type: real 0064 * Font size for text level 0065 */ 0066 readonly property real textSize: (parent.width<maxBarWidth) ? 32 * minWidth / maxWidth : 32 0067 0068 /** 0069 * type:real 0070 * Zoom factor of the bar and its children. 0071 */ 0072 property real barZoom: (parent.width<maxBarWidth) ? minWidth : maxWidth 0073 0074 /** 0075 * type: real 0076 * Keeps track of the number of buttons that are displayed 0077 */ 0078 property int numberOfButtons: 0 0079 0080 //totalWidth has 66 as initial value because it will always have the "hideBar" button 0081 /** 0082 * type: real 0083 * Width of all the buttons 0084 */ 0085 property real totalWidth: 66 0086 0087 readonly property int fullButton: 66 0088 readonly property int halfButton: 30 0089 0090 readonly property int fullButtonScaled: fullButton * barZoom 0091 readonly property int halfButtonScaled: halfButton * barZoom 0092 0093 /** 0094 * type:BarEnumContent 0095 * Defines the content/children of the bar. 0096 * 0097 * @sa BarEnumContent 0098 */ 0099 property BarEnumContent content 0100 0101 /** 0102 * type:int 0103 * Current level to be shown in the level child. 0104 * 0105 * Set this to the current level of your activity. 0106 */ 0107 property int level: 0 0108 0109 /** 0110 * Emitted when the about button was clicked. 0111 */ 0112 signal aboutClicked 0113 0114 /** 0115 * Emitted when the help button was clicked. 0116 * 0117 * Show help dialog upon this signal. 0118 */ 0119 signal helpClicked 0120 0121 /** 0122 * Emitted when the config button was clicked. 0123 * 0124 * Should be implemented if an activity provides per-activity 0125 * configuration. 0126 */ 0127 signal configClicked 0128 0129 /** 0130 * Emitted when the next level button was clicked. 0131 * 0132 * Switch to the next level upon this signal. 0133 */ 0134 signal nextLevelClicked 0135 0136 /** 0137 * Emitted when the previous level button was clicked. 0138 * 0139 * Switch to the previous level upon this signal. 0140 */ 0141 signal previousLevelClicked 0142 0143 /** 0144 * Emitted when the repeat button was clicked. 0145 * 0146 * Implement if your activity needs to repeat audio voices. 0147 */ 0148 signal repeatClicked 0149 0150 /** 0151 * Emitted when the reload button was clicked. 0152 * 0153 * Implement if you want to support repeating a level from the beginning. 0154 */ 0155 signal reloadClicked 0156 0157 /** 0158 * Emitted when the hint button was clicked. 0159 * 0160 * Implement if your activity needs a hint to help children. 0161 */ 0162 signal hintClicked 0163 0164 /** 0165 * Emitted when the activity configuration button was clicked. 0166 * 0167 * Only in menu to change the activity configuration. 0168 */ 0169 signal activityConfigClicked 0170 0171 /** 0172 * Emitted when the home button was clicked. 0173 * 0174 * Should always be connected to the ActivityBase.home signal and thus 0175 * return to the home/main menu. 0176 */ 0177 signal homeClicked 0178 0179 /// @cond INTERNAL_DOCS 0180 0181 /* 0182 * A list of all our possible buttons. 0183 * 0184 * bid = Button ID. And references the Component object of the button 0185 * This way we can have any visual object in the bar. 0186 */ 0187 property var buttonList: [ 0188 { 0189 'bid': exit, 0190 'contentId': content.exit, 0191 'allowed': !ApplicationSettings.isKioskMode 0192 }, 0193 { 0194 'bid': about, 0195 'contentId': content.about, 0196 'allowed': true 0197 }, 0198 { 0199 'bid': help, 0200 'contentId': content.help, 0201 'allowed': true 0202 }, 0203 { 0204 'bid': home, 0205 'contentId': content.home, 0206 'allowed': true 0207 }, 0208 { 0209 'bid': previous, 0210 'contentId': content.level, 0211 'allowed': true 0212 }, 0213 { 0214 'bid': levelText, 0215 'contentId': content.level, 0216 'allowed': true 0217 }, 0218 { 0219 'bid': next, 0220 'contentId': content.level, 0221 'allowed': true 0222 }, 0223 { 0224 'bid': repeat, 0225 'contentId': content.repeat, 0226 'allowed': true 0227 }, 0228 { 0229 'bid': reload, 0230 'contentId': content.reload, 0231 'allowed': true 0232 }, 0233 { 0234 'bid': config, 0235 'contentId': content.config, 0236 'allowed': !ApplicationSettings.isKioskMode 0237 }, 0238 { 0239 'bid': hint, 0240 'contentId': content.hint, 0241 'allowed': true 0242 }, 0243 { 0244 'bid': activityConfigImage, 0245 'contentId': content.activityConfig, 0246 'allowed': !ApplicationSettings.isKioskMode 0247 }, 0248 { 0249 'bid': downloadImage, 0250 'contentId': content.download, 0251 'allowed': true 0252 } 0253 ] 0254 0255 /* internal? */ 0256 property var buttonModel 0257 0258 x: 0 0259 anchors.bottom: parent.bottom 0260 width: openBar.width 0261 height: openBar.height 0262 z: 1000 0263 0264 function show(newContent) { 0265 content.value = newContent 0266 } 0267 0268 Connections { 0269 target: DownloadManager 0270 0271 onDownloadStarted: content.value |= content.download 0272 onAllDownloadsFinished: content.value &= ~content.download 0273 onError: content.value &= ~content.download 0274 } 0275 0276 Image { 0277 id: openBar 0278 source: "qrc:/gcompris/src/core/resource/bar_open.svg"; 0279 anchors.bottom: parent.bottom 0280 anchors.left: parent.left 0281 sourceSize.width: fullButtonScaled 0282 MouseArea { 0283 anchors.fill: parent 0284 0285 onClicked: { 0286 ApplicationSettings.isBarHidden = !ApplicationSettings.isBarHidden; 0287 } 0288 } 0289 } 0290 0291 function computeWidth(bid) { 0292 if (bid===levelText) { 0293 return 0 0294 } 0295 else if (bid===previous||bid===next) 0296 return halfButton 0297 else return fullButton 0298 } 0299 0300 function updateContent() { 0301 var newButtonModel = new Array() 0302 numberOfButtons = 0 0303 totalWidth = 66; 0304 for(var def in buttonList) { 0305 if((content.value & buttonList[def].contentId) && 0306 buttonList[def].allowed) { 0307 newButtonModel.push(buttonList[def]) 0308 totalWidth += computeWidth(buttonList[def].bid) 0309 numberOfButtons++ 0310 } 0311 } 0312 buttonModel = newButtonModel 0313 } 0314 0315 Connections { 0316 target: content 0317 onValueChanged: updateContent() 0318 } 0319 0320 onContentChanged: { 0321 updateContent() 0322 } 0323 0324 Row { 0325 id: barRow 0326 spacing: 5 0327 anchors.bottom: parent.bottom 0328 anchors.bottomMargin: 10 0329 anchors.left: openBar.right 0330 anchors.leftMargin: 10 * ApplicationInfo.ratio 0331 property bool isHidden: false 0332 Repeater { 0333 model: buttonModel 0334 Loader { 0335 sourceComponent: modelData.bid 0336 } 0337 } 0338 0339 state: ApplicationSettings.isBarHidden ? "hidden" : "shown" 0340 0341 states: [ 0342 State { 0343 name: "shown" 0344 0345 AnchorChanges { 0346 target: barRow 0347 anchors.top: undefined 0348 anchors.bottom: parent.bottom 0349 } 0350 }, 0351 State { 0352 name: "hidden" 0353 0354 AnchorChanges { 0355 target: barRow 0356 anchors.bottom: undefined 0357 anchors.top: parent.bottom 0358 } 0359 } 0360 ] 0361 0362 transitions: Transition { 0363 SequentialAnimation { 0364 ScriptAction { script: if(barRow.state === "shown") barRow.isHidden = false } 0365 AnchorAnimation { duration: 800; easing.type: Easing.OutBounce } 0366 ScriptAction { script: if(barRow.state === "hidden") barRow.isHidden = true } 0367 } 0368 } 0369 populate: Transition { 0370 NumberAnimation { 0371 properties: "x,y"; from: 200; 0372 duration: 1500; easing.type: Easing.OutBounce 0373 } 0374 } 0375 add: Transition { 0376 NumberAnimation { 0377 properties: "x,y"; from: 200; 0378 duration: 1500; easing.type: Easing.OutBounce 0379 } 0380 } 0381 move: Transition { 0382 NumberAnimation { 0383 properties: "x,y" 0384 duration: 1500; easing.type: Easing.OutBounce 0385 } 0386 } 0387 } 0388 0389 // All the possible bar buttons are defined here 0390 // --------------------------------------------- 0391 Component { 0392 id: exit 0393 BarButton { 0394 source: "qrc:/gcompris/src/core/resource/bar_exit.svg"; 0395 sourceSize.width: fullButtonScaled 0396 visible: barRow.isHidden === false 0397 onClicked: Core.quit(bar.parent); 0398 } 0399 } 0400 Component { 0401 id: about 0402 BarButton { 0403 source: "qrc:/gcompris/src/core/resource/bar_about.svg"; 0404 sourceSize.width: fullButtonScaled 0405 visible: barRow.isHidden === false 0406 onClicked: bar.aboutClicked() 0407 } 0408 } 0409 Component { 0410 id: help 0411 BarButton { 0412 source: "qrc:/gcompris/src/core/resource/bar_help.svg"; 0413 sourceSize.width: fullButtonScaled 0414 visible: barRow.isHidden === false 0415 onClicked: bar.helpClicked() 0416 } 0417 } 0418 Component { 0419 id: previous 0420 BarButton { 0421 source: "qrc:/gcompris/src/core/resource/bar_previous.svg"; 0422 sourceSize.width: halfButtonScaled 0423 visible: barRow.isHidden === false 0424 onClicked: { 0425 if(typeof bonus !== "undefined") 0426 bonus.haltBonus(); 0427 bar.previousLevelClicked(); 0428 } 0429 } 0430 } 0431 Component { 0432 id: levelText 0433 GCText { 0434 id: levelTextId 0435 text: "" + level 0436 fontSize: textSize 0437 font.weight: Font.DemiBold 0438 style: Text.Outline 0439 styleColor: "black" 0440 color: "white" 0441 visible: content.level & content.value && barRow.isHidden === false 0442 onTextChanged: { 0443 if (level>9) 0444 textLength = fullButtonScaled 0445 else textLength = halfButtonScaled 0446 } 0447 } 0448 } 0449 Component { 0450 id: next 0451 BarButton { 0452 source: "qrc:/gcompris/src/core/resource/bar_next.svg"; 0453 sourceSize.width: halfButtonScaled 0454 visible: barRow.isHidden === false 0455 onClicked: { 0456 if(typeof bonus !== "undefined") 0457 bonus.haltBonus(); 0458 bar.nextLevelClicked(); 0459 } 0460 } 0461 } 0462 Component { 0463 id: repeat 0464 BarButton { 0465 source: "qrc:/gcompris/src/core/resource/bar_repeat.svg"; 0466 sourceSize.width: fullButtonScaled 0467 visible: barRow.isHidden === false 0468 onClicked: bar.repeatClicked() 0469 } 0470 } 0471 Component { 0472 id: hint 0473 BarButton { 0474 source: "qrc:/gcompris/src/core/resource/bar_hint.svg"; 0475 sourceSize.width: fullButtonScaled 0476 visible: barRow.isHidden === false 0477 onClicked: bar.hintClicked() 0478 } 0479 } 0480 Component { 0481 id: activityConfigImage 0482 BarButton { 0483 source: "qrc:/gcompris/src/core/resource/bar_activity_config.svg"; 0484 sourceSize.width: fullButtonScaled 0485 visible: barRow.isHidden === false 0486 onClicked: bar.activityConfigClicked() 0487 } 0488 } 0489 Component { 0490 id: reload 0491 BarButton { 0492 source: "qrc:/gcompris/src/core/resource/bar_reload.svg"; 0493 sourceSize.width: fullButtonScaled 0494 visible: barRow.isHidden === false 0495 onClicked: bar.reloadClicked() 0496 } 0497 } 0498 Component { 0499 id: config 0500 BarButton { 0501 source: "qrc:/gcompris/src/core/resource/bar_config.svg"; 0502 sourceSize.width: fullButtonScaled 0503 visible: barRow.isHidden === false 0504 onClicked: bar.configClicked() 0505 } 0506 } 0507 Component { 0508 id: home 0509 BarButton { 0510 // Replace home icon with exit icon in case activity is started as standalone 0511 source: ActivityInfoTree.startingActivity != "" ? 0512 "qrc:/gcompris/src/core/resource/bar_exit.svg" : 0513 "qrc:/gcompris/src/core/resource/bar_home.svg"; 0514 sourceSize.width: fullButtonScaled 0515 visible: barRow.isHidden === false 0516 onClicked: { 0517 bar.homeClicked(); 0518 } 0519 } 0520 } 0521 Component { 0522 id: downloadImage 0523 AnimatedImage { 0524 source: "qrc:/gcompris/src/core/resource/loader.gif" 0525 visible: barRow.isHidden === false 0526 MouseArea { 0527 id: mouseArea 0528 anchors.fill: parent 0529 hoverEnabled: true 0530 onClicked: { 0531 var downloadDialog = Core.showDownloadDialog(activity, {}); 0532 } 0533 } 0534 } 0535 } 0536 0537 /// @endcond 0538 } 0539