Warning, /education/gcompris/src/activities/digital_electricity/DigitalElectricity.qml is written in an unsupported language. File is not indexed.
0001 /* GCompris - DigitalElectricity.qml 0002 * 0003 * SPDX-FileCopyrightText: 2016 Pulkit Gupta <pulkitnsit@gmail.com> 0004 * 0005 * Authors: 0006 * Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version) 0007 * Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port) 0008 * Rudra Nil Basu <rudra.nil.basu.1996@gmail.com> (Qt Quick port) 0009 * Timothée Giet <animtim@gmail.com> (mouse drag refactoring) 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 "digital_electricity.js" as Activity 0018 0019 ActivityBase { 0020 id: activity 0021 0022 onStart: focus = true 0023 onStop: {} 0024 0025 pageComponent: Image { 0026 id: background 0027 anchors.fill: parent 0028 source: Activity.url + "texture02.webp" 0029 fillMode: Image.Tile 0030 signal start 0031 signal stop 0032 0033 property bool hori: background.width >= background.height 0034 0035 Component.onCompleted: { 0036 dialogActivityConfig.initialize() 0037 activity.start.connect(start) 0038 activity.stop.connect(stop) 0039 } 0040 0041 // Needed to get keyboard focus on IntroMessage 0042 Keys.forwardTo: tutorialInstruction 0043 0044 Keys.onPressed: { 0045 if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && okButton.enabled) { 0046 Activity.checkAnswer() 0047 } 0048 if (event.key === Qt.Key_Plus) { 0049 Activity.zoomIn() 0050 } 0051 if (event.key === Qt.Key_Minus) { 0052 Activity.zoomOut() 0053 } 0054 if (event.key === Qt.Key_Right) { 0055 playArea.x -= 200; 0056 } 0057 if (event.key === Qt.Key_Left) { 0058 playArea.x += 200 0059 } 0060 if (event.key === Qt.Key_Up) { 0061 playArea.y += 200 0062 } 0063 if (event.key === Qt.Key_Down) { 0064 playArea.y -= 200 0065 } 0066 if (playArea.x >= mousePan.drag.maximumX) { 0067 playArea.x = mousePan.drag.maximumX 0068 } 0069 if (playArea.y >= mousePan.drag.maximumY) { 0070 playArea.y = mousePan.drag.maximumY 0071 } 0072 if (playArea.x <= mousePan.drag.minimumX) { 0073 playArea.x = mousePan.drag.minimumX 0074 } 0075 if (playArea.y <= mousePan.drag.minimumY) { 0076 playArea.y = mousePan.drag.minimumY 0077 } 0078 } 0079 0080 onHoriChanged: { 0081 if (hori == true) { 0082 playArea.x += items.toolsMargin 0083 playArea.y -= items.toolsMargin 0084 } else { 0085 playArea.x -= items.toolsMargin 0086 playArea.y += items.toolsMargin 0087 } 0088 } 0089 0090 // Add here the QML items you need to access in javascript 0091 QtObject { 0092 id: items 0093 property Item main: activity.main 0094 property alias playArea: playArea 0095 property alias mousePan: mousePan 0096 property int currentLevel: activity.currentLevel 0097 property alias bonus: bonus 0098 property alias availablePieces: availablePieces 0099 property alias toolTip: toolTip 0100 property alias infoTxt: infoTxt 0101 property alias truthTablesModel: truthTablesModel 0102 property alias displayTruthTable: inputOutputTxt.displayTruthTable 0103 property alias dataset: dataset 0104 property alias tutorialDataset: tutorialDataset 0105 property string mode: "tutorial" 0106 property bool isTutorialMode: mode == "tutorial" ? true : false 0107 property alias infoImage: infoImage 0108 property alias tutorialInstruction: tutorialInstruction 0109 property real toolsMargin: 90 * ApplicationInfo.ratio 0110 property real zoomLvl: 0.25 0111 } 0112 0113 Loader { 0114 id: dataset 0115 asynchronous: false 0116 } 0117 0118 TutorialDataset { 0119 id: tutorialDataset 0120 } 0121 0122 IntroMessage { 0123 id: tutorialInstruction 0124 intro: [] 0125 textContainerWidth: background.hori ? parent.width - inputComponentsContainer.width - items.toolsMargin : 0.9 * background.width 0126 textContainerHeight: background.hori ? 0.5 * parent.height : parent.height - inputComponentsContainer.height - (bar.height * 2) - items.toolsMargin 0127 anchors { 0128 fill: undefined 0129 top: background.hori ? parent.top : inputComponentsContainer.bottom 0130 topMargin: 10 0131 right: parent.right 0132 rightMargin: 5 0133 left: background.hori ? inputComponentsContainer.right : parent.left 0134 leftMargin: 5 0135 } 0136 z: 5 0137 } 0138 0139 onStart: { Activity.start(items) } 0140 onStop: { Activity.stop() } 0141 0142 Rectangle { 0143 id: visibleArea 0144 color: "#00000000" 0145 width: background.hori ? background.width - items.toolsMargin - 10 : background.width - 10 0146 height: background.hori ? background.height - bar.height - items.toolsMargin - 10 : background.height - bar.height - 10 0147 anchors { 0148 fill: undefined 0149 top: background.hori ? parent.top : inputComponentsContainer.bottom 0150 topMargin: 5 0151 right: parent.right 0152 rightMargin: 5 0153 left: background.hori ? inputComponentsContainer.right : parent.left 0154 leftMargin: 5 0155 bottom: bar.top 0156 bottomMargin: 20 0157 } 0158 z: 6 0159 0160 GCText { 0161 id: infoTxt 0162 anchors { 0163 horizontalCenter: parent.horizontalCenter 0164 top: parent.top 0165 topMargin: 2 0166 } 0167 fontSizeMode: Text.Fit 0168 minimumPixelSize: 10 0169 font.pixelSize: 150 0170 color: "white" 0171 horizontalAlignment: Text.AlignHLeft 0172 width: Math.min(implicitWidth, 0.90 * parent.width) 0173 height: inputOutputTxt.visible == false ? Math.min(implicitHeight, 0.7 * parent.height) : 0174 Math.min(implicitHeight, (inputOutputTxt.inputs > 2 ? 0.3 : 0.4) * parent.height) 0175 wrapMode: TextEdit.WordWrap 0176 visible: false 0177 z: 4 0178 } 0179 0180 Rectangle { 0181 id: infoTxtContainer 0182 anchors.fill: parent 0183 opacity: 1 0184 radius: 10 0185 color: "#373737" 0186 border.width: 2 0187 border.color: "#F2F2F2" 0188 visible: infoTxt.visible 0189 MouseArea { 0190 anchors.fill: parent 0191 onClicked: infoTxt.visible = false 0192 } 0193 z: 3 0194 } 0195 0196 Image { 0197 id: infoImage 0198 property bool imgVisible: false 0199 height: source == "" ? 0 : parent.height * 0.3 - 10 0200 width: source == "" ? 0 : parent.width - 10 0201 fillMode: Image.PreserveAspectFit 0202 visible: infoTxt.visible && imgVisible 0203 anchors { 0204 top: infoTxt.bottom 0205 horizontalCenter: infoTxtContainer.horizontalCenter 0206 } 0207 z: 5 0208 } 0209 0210 ListModel { 0211 id: truthTablesModel 0212 property int rows 0213 property int columns 0214 property int inputs 0215 property int outputs 0216 } 0217 0218 Row { 0219 id: inputOutputTxt 0220 z: 5 0221 property bool displayTruthTable 0222 visible: infoTxt.visible && displayTruthTable 0223 property int inputs: truthTablesModel.inputs 0224 property int outputs: truthTablesModel.outputs 0225 property int cellSize: (inputs > 2 ? 0.65 : 0.5) * parent.height / (truthTablesModel.rows + 1) 0226 property int maxWidth: Math.min(cellSize, parent.width * 0.95 / truthTablesModel.columns) 0227 property int minSize: 2.5 * cellSize 0228 height: cellSize 0229 anchors { 0230 top: infoTxt.bottom 0231 horizontalCenter: parent.horizontalCenter 0232 } 0233 Rectangle { 0234 color: "#A7D9F9" 0235 width: inputOutputTxt.inputs > 1 ? inputOutputTxt.maxWidth * inputOutputTxt.inputs : inputOutputTxt.minSize 0236 height: inputOutputTxt.cellSize 0237 border.color: "#373737" 0238 border.width: 1 0239 GCText { 0240 anchors.centerIn: parent 0241 fontSizeMode: Text.Fit 0242 minimumPixelSize: 10 0243 color: "#353535" 0244 horizontalAlignment: Text.AlignHCenter 0245 verticalAlignment: Text.AlignVCenter 0246 height: parent.height 0247 width: parent.width 0248 text: qsTr("Input") 0249 } 0250 } 0251 Rectangle { 0252 color: "#A7F9DD" 0253 width: inputOutputTxt.outputs > 1 ? inputOutputTxt.maxWidth * inputOutputTxt.outputs : inputOutputTxt.minSize 0254 height: inputOutputTxt.cellSize 0255 border.color: "#373737" 0256 border.width: 1 0257 GCText { 0258 anchors.centerIn: parent 0259 fontSizeMode: Text.Fit 0260 minimumPixelSize: 10 0261 color: "#353535" 0262 horizontalAlignment: Text.AlignHCenter 0263 verticalAlignment: Text.AlignVCenter 0264 height: parent.height 0265 width: parent.width 0266 text: qsTr("Output") 0267 } 0268 } 0269 } 0270 0271 Grid { 0272 id: truthTable 0273 rows: truthTablesModel.rows 0274 columns: truthTablesModel.columns 0275 height: rows * inputOutputTxt.cellSize 0276 z: 5 0277 visible: inputOutputTxt.visible 0278 anchors { 0279 top: inputOutputTxt.bottom 0280 horizontalCenter: parent.horizontalCenter 0281 } 0282 Repeater { 0283 id: repeater 0284 model: truthTablesModel 0285 delegate: blueSquare 0286 Component { 0287 id: blueSquare 0288 Rectangle { 0289 width: ((index % truthTable.columns) / (truthTablesModel.inputs - 1)) <= 1 ? 0290 (inputOutputTxt.inputs > 1 ? inputOutputTxt.maxWidth : inputOutputTxt.minSize) : 0291 (inputOutputTxt.outputs > 1 ? inputOutputTxt.maxWidth : inputOutputTxt.minSize) 0292 height: inputOutputTxt.cellSize 0293 border.color: "#373737" 0294 border.width: 1 0295 color: { 0296 if(truthTablesModel.inputs == 1) { 0297 return index%2 == 0 ? "#A7D9F9" : "#A7F9DD" 0298 } 0299 else { 0300 return ((index % truthTable.columns) / (truthTablesModel.inputs - 1)) <= 1 ? "#A7D9F9" : "#A7F9DD" 0301 } 0302 } 0303 0304 GCText { 0305 id: truthTableValue 0306 anchors.centerIn: parent 0307 fontSizeMode: Text.Fit 0308 minimumPixelSize: 10 0309 color: "#353535" 0310 horizontalAlignment: Text.AlignHCenter 0311 height: parent.height 0312 width: parent.width 0313 text: value 0314 } 0315 } 0316 } 0317 } 0318 } 0319 0320 } 0321 0322 Rectangle { 0323 id: playArea 0324 color: "#10000000" 0325 x: background.hori ? items.toolsMargin : 0 0326 y: background.hori ? 0 : items.toolsMargin 0327 width: background.hori ? 0328 background.width * 4 - items.toolsMargin : background.width * 4 0329 height: background.hori ? 0330 background.height * 4 - (bar.height * 1.1) : 0331 background.height * 4 - (bar.height * 1.1) - items.toolsMargin 0332 0333 PinchArea { 0334 id: pinchZoom 0335 anchors.fill: parent 0336 onPinchFinished: { 0337 if (pinch.scale < 1) { 0338 Activity.zoomOut() 0339 } 0340 if (pinch.scale > 1) { 0341 Activity.zoomIn() 0342 } 0343 } 0344 MouseArea { 0345 id: mousePan 0346 anchors.fill: parent 0347 scrollGestureEnabled: false //needed for pinchZoom 0348 drag.target: playArea 0349 drag.axis: Drag.XandYAxis 0350 drag.minimumX: - playArea.width * items.zoomLvl 0351 drag.maximumX: background.hori ? items.toolsMargin : 0 0352 drag.minimumY: - playArea.height * items.zoomLvl 0353 drag.maximumY: background.hori ? 0 : items.toolsMargin 0354 onClicked: { 0355 Activity.disableToolDelete(); 0356 Activity.deselect(); 0357 availablePieces.hideToolbar(); 0358 } 0359 } 0360 } 0361 } 0362 0363 Rectangle { 0364 id: inputComponentsContainer 0365 width: background.hori ? 0366 items.toolsMargin : 0367 background.width 0368 height: background.hori ? 0369 background.height : 0370 items.toolsMargin 0371 color: "#4A3823" 0372 anchors.left: parent.left 0373 Image { 0374 anchors.fill: parent 0375 anchors.rightMargin: background.hori ? 3 * ApplicationInfo.ratio : 0 0376 anchors.bottomMargin: background.hori ? 0 : 3 * ApplicationInfo.ratio 0377 source: Activity.url + "texture01.webp" 0378 fillMode: Image.Tile 0379 ListWidget { 0380 id: availablePieces 0381 hori: background.hori 0382 } 0383 } 0384 z: 10 0385 } 0386 0387 Rectangle { 0388 id: toolTip 0389 anchors { 0390 bottom: bar.top 0391 bottomMargin: 10 0392 left: inputComponentsContainer.left 0393 leftMargin: 5 0394 } 0395 width: toolTipTxt.width + 10 0396 height: toolTipTxt.height + 5 0397 color: "#373737" 0398 opacity: 1 0399 radius: 10 0400 z: 100 0401 border.width: 2 0402 border.color: "#F2F2F2" 0403 property alias text: toolTipTxt.text 0404 Behavior on opacity { NumberAnimation { duration: 120 } } 0405 0406 function show(newText) { 0407 if(newText) { 0408 text = newText 0409 opacity = 1 0410 } else { 0411 opacity = 0 0412 } 0413 } 0414 0415 GCText { 0416 id: toolTipTxt 0417 anchors.centerIn: parent 0418 fontSize: regularSize 0419 color: "white" 0420 horizontalAlignment: Text.AlignHCenter 0421 wrapMode: TextEdit.WordWrap 0422 } 0423 } 0424 0425 DialogChooseLevel { 0426 id: dialogActivityConfig 0427 currentActivity: activity.activityInfo 0428 onClose: { 0429 home(); 0430 } 0431 onLoadData: { 0432 if(activityData && activityData["mode"]) { 0433 items.mode = activityData["mode"]; 0434 } 0435 } 0436 } 0437 0438 DialogHelp { 0439 id: dialogHelp 0440 onClose: home() 0441 } 0442 0443 BarButton { 0444 id: okButton 0445 visible: items.isTutorialMode 0446 anchors { 0447 bottom: bar.top 0448 right: parent.right 0449 rightMargin: 10 * ApplicationInfo.ratio 0450 bottomMargin: height * 0.5 0451 } 0452 source: "qrc:/gcompris/src/core/resource/bar_ok.svg" 0453 sourceSize.width: 60 * ApplicationInfo.ratio 0454 enabled: !tutorialInstruction.visible && !bonus.isPlaying 0455 onClicked: Activity.checkAnswer() 0456 } 0457 0458 Bar { 0459 id: bar 0460 level: items.currentLevel + 1 0461 content: BarEnumContent { value: help | home | (items.isTutorialMode ? level : 0) | reload | activityConfig} 0462 onHelpClicked: {displayDialog(dialogHelp)} 0463 onPreviousLevelClicked: Activity.previousLevel() 0464 onNextLevelClicked: Activity.nextLevel() 0465 onHomeClicked: home() 0466 onReloadClicked: Activity.reset() 0467 onActivityConfigClicked: { 0468 displayDialog(dialogActivityConfig) 0469 } 0470 } 0471 0472 Bonus { 0473 id: bonus 0474 Component.onCompleted: win.connect(Activity.nextLevel) 0475 } 0476 } 0477 0478 }