diff --git a/src/activities/digital_electricity/Component.qml b/src/activities/digital_electricity/Component.qml index ab7eb09c8..f89a6441c 100644 --- a/src/activities/digital_electricity/Component.qml +++ b/src/activities/digital_electricity/Component.qml @@ -1,165 +1,138 @@ /* GCompris - Component.qml * * Copyright (C) 2016 Pulkit Gupta * * Authors: * Bruno Coudoin (GTK+ version) * Pulkit Gupta (Qt Quick port) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ import QtQuick 2.3 import "digital_electricity.js" as Activity import GCompris 1.0 Image { id: electricalComponent property QtObject pieceParent property string imgSrc property double posX property double posY property double imgWidth property double imgHeight property int index property string toolTipTxt property int rotationAngle: 0 property int initialAngle: 0 property int startingAngle: 0 property int output property double terminalSize property variant inputs: [] property variant outputs: [] property alias rotateComponent: rotateComponent x: posX * parent.width y: posY * parent.height width: imgWidth * parent.width height: imgHeight * parent.height fillMode: Image.PreserveAspectFit opacity: 1.0 source: Activity.url + imgSrc z: 2 mipmap: true antialiasing: true onPaintedWidthChanged: { updateDragConstraints() Activity.updateWires(index) } - //SequentialAnimation { - //id: rotateComponent - //loops: Animation.Infinite - PropertyAnimation { - id: rotateComponent - //loops: 90 - target: electricalComponent - property: "rotation" - from: initialAngle; to: initialAngle + rotationAngle - duration: 1 - onStarted:{Activity.animationInProgress = true} - onStopped: { - initialAngle = initialAngle + rotationAngle - //console.log("initialAngle",initialAngle) - Activity.updateWires(index) - if(initialAngle == startingAngle + rotationAngle * 45) { - if(initialAngle == 360 || initialAngle == -360) - initialAngle = 0 - startingAngle = initialAngle - Activity.animationInProgress = false - updateDragConstraints() - } - else rotateComponent.start() + PropertyAnimation { + id: rotateComponent + target: electricalComponent + property: "rotation" + from: initialAngle; to: initialAngle + rotationAngle + duration: 1 + onStarted:{Activity.animationInProgress = true} + onStopped: { + initialAngle = initialAngle + rotationAngle + //console.log("initialAngle",initialAngle) + Activity.updateWires(index) + if(initialAngle == startingAngle + rotationAngle * 45) { + if(initialAngle == 360 || initialAngle == -360) + initialAngle = 0 + startingAngle = initialAngle + Activity.animationInProgress = false + updateDragConstraints() } - easing.type: Easing.InOutQuad + else rotateComponent.start() } - //} + easing.type: Easing.InOutQuad + } function updateDragConstraints() { if(rotationAngle == 0 || rotationAngle == 180 || rotationAngle == 360 || rotationAngle == -360 || rotationAngle == -180) { mouseArea.drag.minimumX = (electricalComponent.paintedWidth - electricalComponent.width)/2 mouseArea.drag.minimumY = (electricalComponent.paintedHeight - electricalComponent.height)/2 mouseArea.drag.maximumX = electricalComponent.parent.width - (electricalComponent.width + electricalComponent.paintedWidth)/2 mouseArea.drag.maximumY = electricalComponent.parent.height - (electricalComponent.height + electricalComponent.paintedHeight)/2 } else { mouseArea.drag.minimumX = (electricalComponent.paintedHeight - electricalComponent.width)/2 mouseArea.drag.minimumY = (electricalComponent.paintedWidth - electricalComponent.height)/2 mouseArea.drag.maximumX = electricalComponent.parent.width - (electricalComponent.width + electricalComponent.paintedHeight)/2 mouseArea.drag.maximumY = electricalComponent.parent.height - (electricalComponent.height + electricalComponent.paintedWidth)/2 } //console.log("mouseArea",mouseArea.drag.minimumX,mouseArea.drag.minimumY) } MouseArea { id: mouseArea //anchors.fill: parent width: parent.paintedWidth height: parent.paintedHeight anchors.centerIn: parent drag.target: electricalComponent - //drag.minimumX: 0 - //drag.maximumX: electricalComponent.parent.width - (electricalComponent.width + electricalComponent.paintedWidth)/2 - //drag.minimumY: 0 - //drag.maximumY: (!parent && !parent.parent) ? (parent.parent.height - parent.height) : 0 onPressed: { console.log("Component index",index) if(Activity.toolDelete) { Activity.updateToolTip("") Activity.removeComponent(index) } else { Activity.updateToolTip(toolTipTxt) Activity.componentSelected(index) } } onPositionChanged: { Activity.updateWires(index) } onReleased: { - /* - console.log(parent.y, parent.height,parent.width,parent.height - parent.width/2) - console.log(parent.paintedHeight,parent.paintedWidth) - console.log("mouseArea",mouseArea.drag.minimumX,mouseArea.drag.minimumY) - if(initialAngle == 0 || initialAngle == 180) { - if ((parent.parent.height - parent.y > parent.paintedHeight) && - (parent.parent.width - parent.x > parent.paintedWidth) && parent.x > 0 && parent.y > 0) { - parent.posX = parent.x / parent.parent.width - parent.posY = parent.y / parent.parent.height - } - } - else if ((parent.parent.height - parent.y > parent.paintedHeight/2) && - (parent.parent.width - parent.x > parent.paintedWidth/2) && - parent.x > (parent.paintedHeight/2 - parent.paintedWidth/2) && parent.y > 0) { - parent.posX = parent.x / parent.parent.width - parent.posY = parent.y / parent.parent.height - } - */ parent.posX = parent.x / parent.parent.width parent.posY = parent.y / parent.parent.height parent.x = Qt.binding(function() { return parent.posX * parent.parent.width }) parent.y = Qt.binding(function() { return parent.posY * parent.parent.height }) Activity.updateToolTip("") } } } diff --git a/src/activities/digital_electricity/DigitalElectricity.qml b/src/activities/digital_electricity/DigitalElectricity.qml index 553f14716..fb15a76e4 100644 --- a/src/activities/digital_electricity/DigitalElectricity.qml +++ b/src/activities/digital_electricity/DigitalElectricity.qml @@ -1,227 +1,346 @@ /* GCompris - DigitalElectricity.qml * * Copyright (C) 2016 Pulkit Gupta * * Authors: * Bruno Coudoin (GTK+ version) * Pulkit Gupta (Qt Quick port) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ import QtQuick 2.1 +//import QtQuick.Controls 1.4 import GCompris 1.0 import "../../core" import "digital_electricity.js" as Activity ActivityBase { id: activity onStart: focus = true onStop: {} pageComponent: Rectangle { id: background anchors.fill: parent color: "#ffffb3" signal start signal stop property bool vert: background.width > background.height Component.onCompleted: { activity.start.connect(start) activity.stop.connect(stop) } // Add here the QML items you need to access in javascript QtObject { id: items property Item main: activity.main property alias backgroundContainer: backgroundContainer property alias bar: bar property alias bonus: bonus property alias availablePieces: availablePieces property alias toolTip: toolTip property alias infoTxt: infoTxt - property alias infoImage: infoImage + property alias truthTablesModel: truthTablesModel + property alias displayTruthTable: inputOutputTxt.displayTruthTable + property alias dataset: dataset + //property alias infoImage: infoImage + } + + Loader { + id: dataset + asynchronous: false } onStart: { Activity.start(items) } onStop: { Activity.stop() } Rectangle { id: backgroundContainer color: "#ffffb3" x: background.vert ? 90 * ApplicationInfo.ratio : 0 y: background.vert ? 0 : 90 * ApplicationInfo.ratio width: background.vert ? background.width - 90 * ApplicationInfo.ratio : background.width height: background.vert ? background.height - (bar.height * 1.1) : background.height - (bar.height * 1.1) - 90 * ApplicationInfo.ratio - //onHeightChanged: Activity.updateAllWires() - //onWidthChanged: Activity.updateAllWires() MouseArea { anchors.fill: parent onClicked: Activity.deselect() } GCText { id: infoTxt anchors { horizontalCenter: parent.horizontalCenter top: infoTxtContainer.top topMargin: 2 } fontSizeMode: Text.Fit minimumPixelSize: 10 color: "white" style: Text.Outline styleColor: "black" horizontalAlignment: Text.AlignHLeft - width: Math.min(implicitWidth, 0.90 * parent.width) //background.vert ? Math.min(implicitWidth, 0.95 * parent.width) : - //Math.min(implicitWidth, 0.85 * parent.width) - height: infoImage.source == "" ? Math.min(implicitHeight, 0.9 * parent.height) : + width: Math.min(implicitWidth, 0.90 * parent.width) + height: inputOutputTxt.visible == false ? Math.min(implicitHeight, 0.9 * parent.height) : Math.min(implicitHeight, 0.4 * parent.height) wrapMode: TextEdit.WordWrap visible: false z: 4 } Rectangle { id: infoTxtContainer anchors.centerIn: parent width: infoTxt.width + 20 - height: infoTxt.height + infoImage.height + 8 + height: inputOutputTxt.visible == false ? infoTxt.height : + infoTxt.height + inputOutputTxt.height + truthTable.height + 8 opacity: 0.8 radius: 10 border.width: 2 border.color: "black" visible: infoTxt.visible gradient: Gradient { GradientStop { position: 0.0; color: "#000" } GradientStop { position: 0.9; color: "#666" } GradientStop { position: 1.0; color: "#AAA" } } MouseArea { anchors.fill: parent onClicked: infoTxt.visible = false } z: 3 } - Image { + /*Image { id: infoImage property int heightNeed: parent.height - infoTxt.height height: source == "" ? 0 : parent.height - infoTxt.height - 10 width: source == "" ? 0 : parent.width - 10 fillMode: Image.PreserveAspectFit visible: infoTxt.visible anchors { top: infoTxt.bottom horizontalCenter: parent.horizontalCenter } z: 5 + }*/ + + + ListModel { + id: truthTablesModel + property int rows + property int columns + property int inputs + property int outputs } + Row { + id: inputOutputTxt + z: 5 + property bool displayTruthTable + visible: infoTxt.visible && displayTruthTable + property int cellSize: Math.min(parent.height - infoTxt.height - 10, 0.45 * parent.height) / + truthTablesModel.rows + property int inputs: truthTablesModel.inputs + property int outputs: truthTablesModel.outputs + property int minSize: 2 * cellSize + //width: truthTable.width + height: cellSize + anchors { + top: infoTxt.bottom + horizontalCenter: parent.horizontalCenter + } + Rectangle { + color: "#c7ecfb" + width: Math.max(inputOutputTxt.minSize, inputOutputTxt.cellSize * inputOutputTxt.inputs) + height: inputOutputTxt.cellSize + border.color: "black" + border.width: 1 + GCText { + anchors.centerIn: parent + fontSizeMode: Text.Fit + minimumPixelSize: 10 + color: "white" + style: Text.Outline + styleColor: "black" + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + height: parent.height + width: parent.width + text: qsTr("Input") + } + } + Rectangle { + color: "#c7ecfb" + width: Math.max(inputOutputTxt.minSize, inputOutputTxt.cellSize * inputOutputTxt.outputs) + height: inputOutputTxt.cellSize + border.color: "black" + border.width: 1 + GCText { + anchors.centerIn: parent + fontSizeMode: Text.Fit + minimumPixelSize: 10 + color: "white" + style: Text.Outline + styleColor: "black" + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + height: parent.height + width: parent.width + text: qsTr("Output") + } + } + } + + Grid { + id: truthTable + rows: truthTablesModel.rows + columns: truthTablesModel.columns + //width: columns * inputOutputTxt.cellSize + height: rows * inputOutputTxt.cellSize + z: 5 + visible: inputOutputTxt.visible + anchors { + top: inputOutputTxt.bottom + horizontalCenter: parent.horizontalCenter + } + //spacing: 1 + Repeater { + id: repeater + model: truthTablesModel //15//pieces + delegate: blueSquare + Component { + id: blueSquare + Rectangle { + width: ((index % truthTable.columns) / (truthTablesModel.inputs - 1)) <= 1 ? + (inputOutputTxt.inputs > 1 ? inputOutputTxt.cellSize : inputOutputTxt.minSize) : + (inputOutputTxt.outputs > 1 ? inputOutputTxt.cellSize : inputOutputTxt.minSize) + height: inputOutputTxt.cellSize + border.color: "black" + border.width: 1 + //radius: 1 + color: "#c7ecfb" + GCText { + id: truthTableValue + anchors.centerIn: parent + fontSizeMode: Text.Fit + minimumPixelSize: 10 + color: "white" + style: Text.Outline + styleColor: "black" + horizontalAlignment: Text.AlignHCenter + height: parent.height + width: parent.width + text: value + } + } + } + } + } } Rectangle { id: leftWidget width: background.vert ? 90 * ApplicationInfo.ratio : background.width height: background.vert ? background.height : 90 * ApplicationInfo.ratio color: "#FFFF42" border.color: "#FFD85F" border.width: 4 anchors.left: parent.left ListWidget { id: availablePieces vert: background.vert ? true : false } } Rectangle { id: toolTip anchors { bottom: bar.top bottomMargin: 10 left: leftWidget.left leftMargin: 5 } width: toolTipTxt.width + 10 height: toolTipTxt.height + 5 opacity: 1 radius: 10 z: 100 border.width: 2 border.color: "black" gradient: Gradient { GradientStop { position: 0.0; color: "#000" } GradientStop { position: 0.9; color: "#666" } GradientStop { position: 1.0; color: "#AAA" } } property alias text: toolTipTxt.text Behavior on opacity { NumberAnimation { duration: 120 } } function show(newText) { if(newText) { text = newText opacity = 0.8 } else { opacity = 0 } } GCText { id: toolTipTxt anchors.centerIn: parent fontSize: regularSize color: "white" style: Text.Outline styleColor: "black" horizontalAlignment: Text.AlignHCenter wrapMode: TextEdit.WordWrap } } DialogHelp { id: dialogHelp onClose: home() } Bar { id: bar content: BarEnumContent { value: help | home | reload} onHelpClicked: { displayDialog(dialogHelp) } onPreviousLevelClicked: Activity.previousLevel() onNextLevelClicked: Activity.nextLevel() onHomeClicked: activity.home() onReloadClicked: Activity.reset() } Bonus { id: bonus Component.onCompleted: win.connect(Activity.nextLevel) } } } diff --git a/src/activities/digital_electricity/ListWidget.qml b/src/activities/digital_electricity/ListWidget.qml index ecc484230..438bb9b5d 100644 --- a/src/activities/digital_electricity/ListWidget.qml +++ b/src/activities/digital_electricity/ListWidget.qml @@ -1,323 +1,323 @@ /* gcompris - ListWidget.qml * * Copyright (C) 2016 Pulkit Gupta * * Authors: * Bruno Coudoin (GTK+ version) * Pulkit Gupta (Qt Quick port) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ import QtQuick 2.1 import GCompris 1.0 import "../../core" import "digital_electricity.js" as Activity Item { id: listWidget anchors.fill: parent anchors.topMargin: 5 * ApplicationInfo.ratio anchors.leftMargin: 5 * ApplicationInfo.ratio z: 10 property bool vert property alias model: mymodel property alias view: view property alias repeater: repeater property alias toolDelete: toolDelete property alias rotateLeft: rotateLeft property alias rotateRight: rotateRight property alias info: info ListModel { id: mymodel } Grid { id: view width: listWidget.vert ? leftWidget.width : 2 * bar.height height: listWidget.vert ? background.height - 2 * bar.height : bar.height spacing: 5 z: 20 columns: listWidget.vert ? 1 : nbItemsByGroup + 2 property int currentDisplayedGroup: 0 property int setCurrentDisplayedGroup: 0 property int nbItemsByGroup: listWidget.vert ? parent.height / iconSize - 2 : parent.width / iconSize - 2 property int nbDisplayedGroup: Math.ceil(model.count / nbItemsByGroup) property int iconSize: 80 * ApplicationInfo.ratio property int previousNavigation: 1 property int nextNavigation: 1 onNbDisplayedGroupChanged: { view.setCurrentDisplayedGroup = 0 refreshLeftWidget() } add: Transition { NumberAnimation { property: "opacity"; from: 0; to: 1.0; duration: 400 } NumberAnimation { property: "scale"; from: 0; to: 1.0; duration: 400 } } move: Transition { NumberAnimation { properties: "x,y"; duration: 400; easing.type: Easing.OutBounce } } //For setting navigation buttons function setNextNavigation() { nextNavigation = 0 //console.log("setNextNavigation",nextNavigation) if(currentDisplayedGroup + 1 < nbDisplayedGroup) nextNavigation = 1 //console.log("setNextNavigation",nextNavigation) } function setPreviousNavigation() { previousNavigation = 0 if(currentDisplayedGroup > 0) previousNavigation = 1 //console.log("setPreviousNavigation",previousNavigation) } function refreshLeftWidget() { //console.log("refreshLeftWidget") availablePieces.view.currentDisplayedGroup = availablePieces.view.setCurrentDisplayedGroup availablePieces.view.setNextNavigation() availablePieces.view.setPreviousNavigation() } Column { id: toolButtons width: listWidget.vert ? listWidget.width : listWidget.height height: listWidget.vert ? listWidget.width : listWidget.height spacing: 10 //z: 20 Row { spacing: view.iconSize * 0.20 Image { id: toolDelete state: "notSelected" sourceSize.width: view.iconSize * 0.35 fillMode: Image.PreserveAspectFit MouseArea { anchors.fill: parent onClicked: { - toolDelete.state = "selected" - Activity.toolDelete = true + toolDelete.state = toolDelete.state == "selected" ? "notSelected" : "selected" + Activity.toolDelete = !Activity.toolDelete //true //console.log("state",toolDelete.state) } } states: [ State { name: "selected" PropertyChanges{ target: toolDelete - source: Activity.url + "tool-del_on.png" + source: Activity.url + "deleteOn.svg" } }, State { name: "notSelected" PropertyChanges { target: toolDelete - source: Activity.url + "tool-del.png" + source: Activity.url + "deleteOff.svg" } } ] } Image { id: info source: Activity.url + "Info.svg" sourceSize.width: view.iconSize * 0.35 fillMode: Image.PreserveAspectFit MouseArea { anchors.fill: parent onClicked: { if(!Activity.animationInProgress && parent.state == "canBeSelected") { //console.log("rotateLeft clicked") Activity.displayInfo() } } } states: [ State { name: "canBeSelected" PropertyChanges{ target: info source: Activity.url + "Info.svg" } }, State { name: "canNotBeSelected" PropertyChanges { target: info source: Activity.url + "InfoOff.svg" } } ] } } Row { spacing: view.iconSize * 0.20 Image { id: rotateLeft //source: Activity.url + "rotateLeft.svg" sourceSize.width: view.iconSize * 0.35 fillMode: Image.PreserveAspectFit state: "CanNotBeSelected" MouseArea { anchors.fill: parent //enabled: parent.state == "canBeSelected" onClicked: { if(!Activity.animationInProgress && parent.state == "canBeSelected") { //console.log("rotateLeft clicked") Activity.rotateLeft() } } } states: [ State { name: "canBeSelected" PropertyChanges{ target: rotateLeft source: Activity.url + "rotateLeft.svg" } }, State { name: "canNotBeSelected" PropertyChanges { target: rotateLeft source: Activity.url + "rotateLeftOff.svg" } } ] } Image { id: rotateRight //source: Activity.url + "rotateRight.svg" sourceSize.width: view.iconSize * 0.35 fillMode: Image.PreserveAspectFit state: "CanNotBeSelected" MouseArea { anchors.fill: parent //enabled: parent.state == "canBeSelected" onClicked: { if(!Activity.animationInProgress && parent.state == "canBeSelected") { //console.log("rotateRight clicked") Activity.rotateRight() } } } states: [ State { name: "canBeSelected" PropertyChanges{ target: rotateRight source: Activity.url + "rotateRight.svg" } }, State { name: "canNotBeSelected" PropertyChanges { target: rotateRight source: Activity.url + "rotateRightOff.svg" } } ] } } } Repeater { id: repeater property int currentIndex width: 100 /*onCurrentIndexChanged: { for(var i = 0; i < mymodel.count; i++) { if(currentIndex != i) repeater.itemAt(i).selected = false else repeater.itemAt(i).selected = true } if(currentIndex == -1) toolTip.opacity = 0 }*/ DragListItem { id: contactsDelegate z: 1 heightInColumn: view.iconSize * 0.75//listWidget.vert ? view.iconSize * 0.75 : view.iconSize * 0.9 widthInColumn: view.iconSize * 0.85//listWidget.vert ? view.iconSize * 0.9 : view.iconSize * 0.75 tileWidth: view.iconSize//listWidget.vert ? view.iconSize : view.iconSize * 0.85 tileHeight: view.iconSize * 0.85//listWidget.vert ? view.iconSize * 0.85 : view.iconSize visible: view.currentDisplayedGroup * view.nbItemsByGroup <= index && index <= (view.currentDisplayedGroup+1) * view.nbItemsByGroup-1 onPressed: repeater.currentIndex = index } clip: true model: mymodel onModelChanged: repeater.currentIndex = -1 } Row { spacing: view.iconSize * 0.20 Image { id: previous opacity: (model.count > view.nbItemsByGroup && view.previousNavigation != 0 && view.currentDisplayedGroup != 0) ? 1 : 0 source: "qrc:/gcompris/src/core/resource/bar_previous.svg" sourceSize.width: view.iconSize * 0.30 fillMode: Image.PreserveAspectFit MouseArea { anchors.fill: parent onClicked: { repeater.currentIndex = -1 if(previous.opacity == 1) { view.setCurrentDisplayedGroup = view.currentDisplayedGroup - view.previousNavigation view.refreshLeftWidget() } } } } Image { id: next visible: model.count > view.nbItemsByGroup && view.nextNavigation != 0 && view.currentDisplayedGroup < view.nbDisplayedGroup - 1 source: "qrc:/gcompris/src/core/resource/bar_next.svg" sourceSize.width: view.iconSize * 0.30 fillMode: Image.PreserveAspectFit MouseArea { anchors.fill: parent onClicked: { repeater.currentIndex = -1 view.setCurrentDisplayedGroup = view.currentDisplayedGroup + view.nextNavigation view.refreshLeftWidget() } } } } } } diff --git a/src/activities/digital_electricity/digital_electricity.js b/src/activities/digital_electricity/digital_electricity.js index 80416a4a4..e8ffeda3c 100644 --- a/src/activities/digital_electricity/digital_electricity.js +++ b/src/activities/digital_electricity/digital_electricity.js @@ -1,789 +1,745 @@ /* GCompris - digital_electricity.js * * Copyright (C) 2016 Pulkit Gupta * * Authors: * Bruno Coudoin (GTK+ version) * Pulkit Gupta (Qt Quick port) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ .pragma library .import QtQuick 2.0 as Quick var currentLevel = 0 var numberOfLevel = 4 var items var url = "qrc:/gcompris/src/activities/digital_electricity/resource/" //var componentIndex = 0 var toolDelete var selectedIndex var animationInProgress var selectedTerminal +var mapSrc = {} var terminals = [] var deletedIndex = [] var components = [] +var componentsInfo = [] var wires = [] var connected = [] var deletedWireIndex = [] var colors = ["red","green","blue","blueviolet","silver"] function start(items_) { items = items_ currentLevel = 0 - items.availablePieces.model.append( { + var filename = url + "Components.qml" + items.dataset.source = filename + var componentsData = items.dataset.item + var componentsDataLength = componentsData.components.length + + for(var i = 0 ; i < componentsDataLength ; ++i) { + var component = componentsData.components[i] + + items.availablePieces.model.append( { + "imgName": component.imgName, + "imgWidth": component.imgWidth, + "imgHeight": component.imgHeight, + "toolTipText": component.toolTipText, + "terminalSize": component.terminalSize, + }); + + + mapSrc[component.imgName] = i + if(component.imgName == "ledOff.svg") + mapSrc["ledOn.svg"] = i + else if(component.imgName == "switchOff.svg") + mapSrc["switchOn.svg"] = i + + componentsInfo[i] = [] + componentsInfo[i][0] = component.imgWidth + componentsInfo[i][1] = component.imgHeight + componentsInfo[i][2] = component.toolTipText + componentsInfo[i][3] = component.terminalSize + + componentsInfo[i][4] = [] + var inputs = component.inputTerminals + for(var j = 0 ; j < inputs.length ; ++j) { + componentsInfo[i][4][j] = [] + var input = inputs[j] + componentsInfo[i][4][j][0] = input.posX + componentsInfo[i][4][j][1] = input.posY + componentsInfo[i][4][j][2] = input.value == undefined ? -1 : input.value + } + + componentsInfo[i][5] = [] + var outputs = component.outputTerminals + //console.log("outputs.length",outputs.length) + for(var j = 0 ; j < outputs.length ; ++j) { + componentsInfo[i][5][j] = [] + var output = outputs[j] + componentsInfo[i][5][j][0] = output.posX + componentsInfo[i][5][j][1] = output.posY + componentsInfo[i][5][j][2] = output.value == undefined ? -1 : output.value + } + + componentsInfo[i][6] = component.information + componentsInfo[i][7] = component.truthTable + } + + /*items.availablePieces.model.append( { "imgName": "zero.svg", "imgWidth": 0.12, "imgHeight": 0.2, "toolTipText": qsTr("Zero input"), "terminalSize": 0.205 }); items.availablePieces.model.append( { "imgName": "one.svg", "imgWidth": 0.12, "imgHeight": 0.2, "toolTipText": qsTr("One input"), "terminalSize": 0.218 }); /*items.availablePieces.model.append( { "imgName": "battery.svg", "imgWidth": 0.13, "imgHeight": 0.18, "toolTipText": qsTr("Battery") }); items.availablePieces.model.append( { "imgName": "comparator.svg", "imgWidth": 0.3, "imgHeight": 0.25, "toolTipText": qsTr("Comparator") - });*/ + }); items.availablePieces.model.append( { "imgName": "ledOff.svg", "imgWidth": 0.16, "imgHeight": 0.2, "toolTipText": qsTr("LED"), "terminalSize": 0.111 }); /*items.availablePieces.model.append( { "imgName": "switchOff.svg", "imgWidth": 0.18, "imgHeight": 0.15, "toolTipText": qsTr("Switch") }); items.availablePieces.model.append( { "imgName": "BCDTo7Segment.svg", "imgWidth": 0.3, "imgHeight": 0.4, "toolTipText": qsTr("BCD To 7 Segment") }); items.availablePieces.model.append( { "imgName": "sevenSegmentDisplay.svg", "imgWidth": 0.18, "imgHeight": 0.4, "toolTipText": qsTr("7 Segment Display"), "terminalSize": 0.097 }); - */ items.availablePieces.model.append( { "imgName": "gateAnd.svg", "imgWidth": 0.15, "imgHeight": 0.12, "toolTipText": qsTr("AND gate"), "terminalSize": 0.246 }); /*items.availablePieces.model.append( { "imgName": "gateNand.svg", "imgWidth": 0.15, "imgHeight": 0.12, "toolTipText": qsTr("NAND gate") }); items.availablePieces.model.append( { "imgName": "gateNor.svg", "imgWidth": 0.15, "imgHeight": 0.12, "toolTipText": qsTr("NOR gate") }); items.availablePieces.model.append( { "imgName": "gateNot.svg", "imgWidth": 0.15, "imgHeight": 0.12, "toolTipText": qsTr("Not gate") }); items.availablePieces.model.append( { "imgName": "gateOr.svg", "imgWidth": 0.15, "imgHeight": 0.12, "toolTipText": qsTr("Or gate") }); items.availablePieces.model.append( { "imgName": "gateXor.svg", "imgWidth": 0.15, "imgHeight": 0.12, "toolTipText": qsTr("Xor gate") }); //*/ //items.availablePieces.view.refreshLeftWidget() initLevel() } function stop() { for(var i = 0 ; i < components.length ; ++i) { var j for(j = 0 ; j < deletedIndex.length ; ++j) { if(deletedIndex[j] == i) break } if(j == deletedIndex.length) components[i].destroy() } /*for(var i = 0 ; i < terminals.length ; ++i) { terminals[i].destroy(); }*/ for(var i = 0 ; i < wires.length ; ++i) { var j for(j = 0 ; j < deletedWireIndex.length ; ++j) { if(deletedWireIndex[j] == i) break } if(j == deletedWireIndex.length) wires[i].destroy() } } function initLevel() { items.availablePieces.view.currentDisplayedGroup = 0 items.availablePieces.view.previousNavigation = 1 items.availablePieces.view.nextNavigation = 1 terminals = [] deletedIndex = [] components = [] wires = [] connected = [] deletedWireIndex = [] animationInProgress = false deselect() + toolDelete = false updateToolTip("") } function reset() { deselect() stop() initLevel() } function createComponent(x, y, src, imgWidth, imgHeight, toolTipTxt, terminalSize) { var electricComponent = Qt.createComponent("qrc:/gcompris/src/activities/digital_electricity/Component.qml") if (electricComponent.status == electricComponent.Error) { // Error Handling console.log("Error loading component:", electricComponent.errorString()); } //console.log("Inside createComponent") x = x / items.backgroundContainer.width y = y / items.backgroundContainer.height //console.log("x",x,"y",y) var index if(deletedIndex.length > 0) { index = deletedIndex[deletedIndex.length - 1] deletedIndex.pop() } else index = components.length + var componentInfo = componentsInfo[mapSrc[src]] components[index] = electricComponent.createObject( items.backgroundContainer, { "index": index, "posX": x, "posY": y, "imgSrc": src, - "imgWidth": imgWidth, - "imgHeight": imgHeight, - "toolTipTxt": toolTipTxt, - "terminalSize": terminalSize + "imgWidth": componentInfo[0], + "imgHeight": componentInfo[1], + "toolTipTxt": componentInfo[2], + "terminalSize": componentInfo[3] }); var electricComponentCreated = components[index] var terminalComponent = Qt.createComponent("qrc:/gcompris/src/activities/digital_electricity/TerminalPoint.qml") //console.log("Error loading component:", terminalComponent.errorString()) var terminalIndex = terminals.length //console.log("terminalIndex",terminalIndex) - if(src == "zero.svg") { - electricComponentCreated.outputs.push(terminalIndex) + + var inputs = componentInfo[4] + for(var i = 0 ; i < inputs.length ; ++i) { + var input = inputs[i] + electricComponentCreated.inputs.push(terminalIndex) terminals[terminalIndex++] = terminalComponent.createObject( electricComponentCreated, { - "posX": 0.91, - "posY": 0.5, + "posX": input[0], + "posY": input[1], "index": terminalIndex - 1, - "type": "Out", + "type": "In", "componentIndex": index, - "value": 0 + "value": input[2] }); + //console.log("posX",input[0]) } - else if(src == "one.svg") { + + var outputs = componentInfo[5] + //console.log("outputs.length",outputs.length) + for(var i = 0 ; i < outputs.length ; ++i) { + var output = outputs[i] electricComponentCreated.outputs.push(terminalIndex) terminals[terminalIndex++] = terminalComponent.createObject( electricComponentCreated, { - "posX": 0.91, - "posY": 0.5, + "posX": output[0], + "posY": output[1], "index": terminalIndex - 1, "type": "Out", "componentIndex": index, - "value": 1 - }); - } - else if(src == "gateAnd.svg") { - electricComponentCreated.inputs.push(terminalIndex) - terminals[terminalIndex++] = terminalComponent.createObject( - electricComponentCreated, { - "posX": 0.045, - "posY": 0.219, - "index": terminalIndex - 1, - "type": "In", - "componentIndex": index - }); - electricComponentCreated.inputs.push(terminalIndex) - terminals[terminalIndex++] = terminalComponent.createObject( - electricComponentCreated, { - "posX": 0.045, - "posY": 0.773, - "index": terminalIndex - 1, - "type": "In", - "componentIndex": index - }); - electricComponentCreated.outputs.push(terminalIndex) - terminals[terminalIndex++] = terminalComponent.createObject( - electricComponentCreated, { - "posX": 0.955, - "posY": 0.5, - "index": terminalIndex - 1, - "type": "Out", - "componentIndex": index - }); - } - else if(src == "ledOff.svg") { - electricComponentCreated.inputs.push(terminalIndex) - terminals[terminalIndex++] = terminalComponent.createObject( - electricComponentCreated, { - "posX": 0.319, - "posY": 0.945, - "index": terminalIndex - 1, - "type": "In", - "componentIndex": index - }); - electricComponentCreated.inputs.push(terminalIndex) - terminals[terminalIndex++] = terminalComponent.createObject( - electricComponentCreated, { - "posX": 0.776, - "posY": 0.698, - "index": terminalIndex - 1, - "type": "In", - "componentIndex": index + "value": output[2] }); } - //terminal[index] = [] - /*if(src == "sevenSegmentDisplay.svg") { - var i = 0 - terminal[0] = terminalComponent.createObject( - electricComponentCreated, { - "posX": 0.05, - "posY": 0.049 - }); - terminal[1] = terminalComponent.createObject( - electricComponentCreated, { - "posX": 0.05, - "posY": 0.196 - }); - terminalComponent.createObject( - electricComponentCreated, { - "posX": 0.05, - "posY": 0.336 - }); - terminalComponent.createObject( - electricComponentCreated, { - "posX": 0.05, - "posY": 0.484 - }); - terminalComponent.createObject( - electricComponentCreated, { - "posX": 0.05, - "posY": 0.641 - }); - terminalComponent.createObject( - electricComponentCreated, { - "posX": 0.05, - "posY": 0.796 - }); - terminalComponent.createObject( - electricComponentCreated, { - "posX": 0.05, - "posY": 0.951 - }); - }*/ - - //console.log("Error loading component:", electricComponent.errorString()); componentSelected(index) - //console.log("index",index,"toolTipTxt",toolTipTxt,components[index].toolTipTxt) - //console.log("posX",x,"posX",components[components.length-1].posX) } function terminalPointSelected(index) { if(selectedTerminal == -1 || selectedTerminal == index) selectedTerminal = index else if((terminals[index].type != terminals[selectedTerminal].type) && terminals[index].componentIndex != terminals[selectedTerminal].componentIndex) { var inIndex = terminals[index].type == "In" ? index : selectedTerminal var outIndex = terminals[index].type == "Out" ? index : selectedTerminal //console.log("in, connected[inIndex]",connected[inIndex],"inIndex",inIndex) if(connected[inIndex] == undefined || connected[inIndex] == -1) { //console.log("in2") var wireComponent = Qt.createComponent("qrc:/gcompris/src/activities/digital_electricity/Wire.qml") - //console.log("Error loading component:", wireComponent.errorString()) - /*var x1 = terminals[outIndex].xCenter - var y1 = terminals[outIndex].yCenter - var x2 = terminals[inIndex].xCenter - var y2 = terminals[inIndex].yCenter - //console.log("index",index,"selectedTerminal",selectedTerminal,"x1",x1,"x2",x2,"y1",y1,"y2",y2) - var width = Math.pow((Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)),0.5) + 2 - var angle = (180/Math.PI)*Math.atan((y2-y1)/(x2-x1)) - if(x2 - x1 < 0) angle = angle - 180 - *///console.log("angle=",angle) var index if(deletedWireIndex.length > 0) { index = deletedWireIndex[deletedWireIndex.length - 1] deletedWireIndex.pop() } else index = wires.length var colorIndex = Math.floor(Math.random() * colors.length) //console.log("colorIndex",colorIndex) wires[index] = wireComponent.createObject( items.backgroundContainer, { - //"posX1": x1, - //"posY1": y1, - //"posX2": x2, - //"posY2": y2, "from": outIndex, "to": inIndex, - //"rectWidth": width, - //"rotateAngle": angle, "wireColor": colors[colorIndex], "index": index }); terminals[inIndex].value = terminals[outIndex].value terminals[inIndex].wireIndex.push(index) terminals[outIndex].wireIndex.push(index) - //console.log("terminals[outIndex].wireIndex.length",terminals[outIndex].wireIndex.length) updateWires(terminals[inIndex].componentIndex) updateWires(terminals[outIndex].componentIndex) updateComponent(terminals[inIndex].componentIndex) connected[inIndex] = outIndex } deselect() } else { //console.log("else") deselect() selectedTerminal = index terminals[index].selected = true } } function updateComponent(index) { var visited = [] - /*for(var i = 0 ; i < components.length ; ++i) { - var j - for(j = 0 ; j < deletedIndex.length ; ++j) { - if(deletedIndex[j] == i) - break - } - if(j == deletedIndex.length) - visited[i] = false - }*/ - updateComponentUtility(index, visited) } function updateComponentUtility(index, visited) { //console.log("index",index,"components[index].imgSrc",components[index].imgSrc) if(visited[index] != undefined) // To prevent infinite loop because of bad connection return visited[index] = true var component = components[index] if(component.imgSrc == "gateAnd.svg") { var output = 1 for(var i = 0 ; i < 2 ; ++i) { var value = terminals[component.inputs[i]].value if(value == -1) { output = -1 break } output = output && value } //console.log("output",output) terminals[component.outputs[0]].value = output } else if(component.imgSrc == "ledOff.svg") { if(terminals[component.inputs[0]].value == 1 && terminals[component.inputs[1]].value == 0) component.source = url + "ledOn.svg" else component.source = url + "ledOff.svg" //console.log("component.source",component.source) return } //console.log("component index",index) for(var i = 0 ; i < component.outputs.length ; ++i) { var terminal = terminals[component.outputs[i]] for(var j = 0 ; j < terminal.wireIndex.length ; ++j) { terminals[wires[terminal.wireIndex[j]].to].value = terminal.value } } for(var i = 0 ; i < component.outputs.length ; ++i) { var terminal = terminals[component.outputs[i]] //console.log("terminal index",terminal.index) for(var j = 0 ; j < terminal.wireIndex.length ; ++j) { //console.log("wires[terminal.wireIndex[j]].to",wires[terminal.wireIndex[j]].to) updateComponentUtility(terminals[wires[terminal.wireIndex[j]].to].componentIndex,visited) } } } -/* -function updateAllWires() { - - for(var i = 0 ; i < components.length ; ++i) { - var j - for(j = 0 ; j < deletedIndex.length ; ++j) { - if(deletedIndex[j] == i) - break - } - if(j == deletedIndex.length) - updateWires(i) - } -}*/ - function updateWires(index) { var component = components[index] if(component == undefined || component.inputs == undefined || component.outputs == undefined) return var rotatedAngle = component.initialAngle * Math.PI / 180 for(var i = 0 ; i < component.inputs.length ; ++i) { var terminal = terminals[component.inputs[i]] if(terminal.wireIndex.length != 0) { var wire = wires[terminal.wireIndex[0]] var otherAngle = components[terminals[wire.from].componentIndex].initialAngle * Math.PI / 180 var x = terminals[wire.from].xCenterFromComponent var y = terminals[wire.from].yCenterFromComponent var x1 = terminals[wire.from].xCenter - x + x * Math.cos(otherAngle) - y * Math.sin(otherAngle) var y1 = terminals[wire.from].yCenter - y + x * Math.sin(otherAngle) + y * Math.cos(otherAngle) //console.log(otherComponentAngle,x,y,x1,y1) x = terminal.xCenterFromComponent y = terminal.yCenterFromComponent var x2 = terminal.xCenter - x + x * Math.cos(rotatedAngle) - y * Math.sin(rotatedAngle) var y2 = terminal.yCenter - y + x * Math.sin(rotatedAngle) + y * Math.cos(rotatedAngle) /*if((rotatedAngle > 0 && rotatedAngle <= 90) || rotatedAngle == -270) { x2 = component.x + component.width / 2 + (terminal.yCenterFromComponent * rotatedAngle) / 90 y2 = component.y + component.height / 2 - (terminal.xCenterFromComponent * rotatedAngle) / 90 } else if(rotatedAngle == 180 || rotatedAngle == -180) { x2 = x2 + terminal.xCenterFromComponent * 2 y2 = y2 + terminal.yCenterFromComponent * 2 } else if(rotatedAngle == 270 || rotatedAngle == -90) { x2 = component.x + component.width / 2 - terminal.yCenterFromComponent y2 = component.y + component.height / 2 + terminal.xCenterFromComponent }*/ var width = Math.pow((Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)),0.5) + 2 var angle = (180/Math.PI)*Math.atan((y2-y1)/(x2-x1)) if(x2 - x1 < 0) angle = angle - 180 - //wire.posX1 = x1 - //wire.posY1 = y1 - //wire.posX2 = x2 - //wire.posY2 = y2 wire.x = x1 wire.y = y1 wire.width = width wire.rotation = angle //wire.rotateAngle = angle } } //console.log("component index",component.index,"component.outputs.length",component.outputs.length) for(var i = 0 ; i < component.outputs.length ; ++i) { var terminal = terminals[component.outputs[i]] //console.log("terminal index",terminal.index,"component.outputs[i]",component.outputs[i]) for(var j = 0 ; j < terminal.wireIndex.length ; ++j) { var x = terminal.xCenterFromComponent var y = terminal.yCenterFromComponent var x1 = terminal.xCenter - x + x * Math.cos(rotatedAngle) - y * Math.sin(rotatedAngle) var y1 = terminal.yCenter - y + x * Math.sin(rotatedAngle) + y * Math.cos(rotatedAngle) var wire = wires[terminal.wireIndex[j]] var otherAngle = components[terminals[wire.to].componentIndex].initialAngle * Math.PI / 180 x = terminals[wire.to].xCenterFromComponent y = terminals[wire.to].yCenterFromComponent var x2 = terminals[wire.to].xCenter - x + x * Math.cos(otherAngle) - y * Math.sin(otherAngle) var y2 = terminals[wire.to].yCenter - y + x * Math.sin(otherAngle) + y * Math.cos(otherAngle) /*if(rotatedAngle == 90 || rotatedAngle == -270) { x1 = component.x + component.width / 2 + terminal.yCenterFromComponent y1 = component.y + component.height / 2 - terminal.xCenterFromComponent } else if(rotatedAngle == 180 || rotatedAngle == -180) { x1 = x1 + terminal.xCenterFromComponent * 2 y1 = y1 + terminal.yCenterFromComponent * 2 } else if(rotatedAngle == 270 || rotatedAngle == -90) { x1 = component.x + component.width / 2 - terminal.yCenterFromComponent y1 = component.y + component.height / 2 + terminal.xCenterFromComponent }*/ var width = Math.pow((Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)),0.5) + 2 var angle = (180/Math.PI)*Math.atan((y2-y1)/(x2-x1)) if(x2 - x1 < 0) angle = angle - 180 //wire.posX1 = x1 //wire.posY1 = y1 //wire.posX2 = x2 //wire.posY2 = y2 wire.x = x1 wire.y = y1 wire.width = width wire.rotation = angle //wire.rotateAngle = angle } } } function deselect() { - items.availablePieces.toolDelete.state = "notSelected" + //items.availablePieces.toolDelete.state = "notSelected" items.availablePieces.rotateLeft.state = "canNotBeSelected" items.availablePieces.rotateRight.state = "canNotBeSelected" items.availablePieces.info.state = "canNotBeSelected" items.infoTxt.visible = false - toolDelete = false + //toolDelete = false selectedIndex = -1 selectedTerminal = -1 for(var i = 0 ; i < terminals.length ; ++i) { terminals[i].selected = false } } function removeComponent(index) { var component = components[index] for(var i = 0 ; i < component.inputs.length ; ++i) { var terminal = terminals[component.inputs[i]] if(terminal.wireIndex.length != 0) // Input Terminal can have only 1 wire removeWire(terminal.wireIndex[0]) } for(var i = 0 ; i < component.outputs.length ; ++i) { var terminal = terminals[component.outputs[i]] //console.log("Remove terminal.wireIndex.length",terminal.wireIndex.length) while (terminal.wireIndex.length != 0) { //console.log("terminal.wireIndex[j]",terminal.wireIndex[j]) removeWire(terminal.wireIndex[0]) // Output Terminal can have more than 1 wire } } components[index].destroy() deletedIndex.push(index) + deselect() } function removeWire(index) { var wire = wires[index] var inTerminal = terminals[wire.to] var outTerminal = terminals[wire.from] var removeIndex = inTerminal.wireIndex.indexOf(index) inTerminal.wireIndex.splice(removeIndex,1) removeIndex = outTerminal.wireIndex.indexOf(index) outTerminal.wireIndex.splice(removeIndex,1) //removeIndex = connected.indexOf(wire.to) //connected.splice(wire.to,1) connected[wire.to] = -1 inTerminal.value = -1 wires[index].destroy() deletedWireIndex.push(index) updateComponent(inTerminal.componentIndex) } function componentSelected(index) { selectedIndex = index items.availablePieces.rotateLeft.state = "canBeSelected" items.availablePieces.rotateRight.state = "canBeSelected" items.availablePieces.info.state = "canBeSelected" } function rotateLeft() { components[selectedIndex].rotationAngle = -2//components[selectedIndex].initialAngle - 90 //console.log("rotationAngle",components[selectedIndex].rotationAngle) components[selectedIndex].rotateComponent.start() /*components[selectedIndex].initialAngle = components[selectedIndex].rotationAngle == -360 ? 0 : components[selectedIndex].rotationAngle*/ } function rotateRight() { components[selectedIndex].rotationAngle = 2//components[selectedIndex].initialAngle + 90 //console.log("rotationAngle",components[selectedIndex].rotationAngle) components[selectedIndex].rotateComponent.start() /*components[selectedIndex].initialAngle = components[selectedIndex].rotationAngle == 360 ? 0 : components[selectedIndex].rotationAngle*/ } function displayInfo() { - var componentName = components[selectedIndex].imgSrc + + var component = componentsInfo[mapSrc[components[selectedIndex].imgSrc]] deselect() items.infoTxt.visible = true + items.infoTxt.text = component[6] + if(component[7].length == 0) + items.displayTruthTable = false + else { + items.displayTruthTable = true + var truthTable = items.truthTablesModel + truthTable.clear() + truthTable.rows = component[7].length + truthTable.columns = component[7][0].length + truthTable.inputs = component[4].length + truthTable.outputs = component[5].length + for(var i = 0 ; i < component[7].length ; ++i) + for(var j = 0 ; j < component[7][i].length ; ++j) + truthTable.append({'value': component[7][i][j]}) + } + //console.log(componentName,componentName=="battery.svg") /*if(componentName == "battery.svg") { items.infoTxt.text = qsTr("Battery is a power source of DC voltage. In analog electronics, the positive " + "terminal gives positive voltage, equal to the rating of battery and negative " + "terminal acts as ground (zero voltage). The battery can have different values " + "depending on its rating. In digital electronics, positive voltage is represented " + "by symbol ‘1’ and ground is represented by symbol ‘0’. Therefore in digital " + "electronics, there are only two states of voltage produced by battery – ‘1’ and ‘0’.") - items.infoImage.source = "" + //items.infoImage.source = "" }*/ - if(componentName == "one.svg" || componentName == "zero.svg") { + + + /*if(componentName == "one.svg" || componentName == "zero.svg") { items.infoTxt.text = qsTr("Digital electronics is a branch of electronics that handle digital signals " + "(i.e discrete signals instead of continous signals). Therefore all values within " + "a range or band represent the same numeric value. In most cases, the number of " + "these states is two and they are represented by two voltage bands: one near a " + "reference value (typically termed as 'ground' or zero volts), and other value near " + "the supply voltage. These correspond to the 'false' ('0') and 'true' ('1') values " + "of the Boolean domain respectively (named after its inventor, George Boole). " + "In this activity, you can give '0' and '1' as input to other logical devices, " + "and see their output through an output device.") - items.infoImage.source = "" + //items.infoImage.source = "" } else if(componentName == "gateAnd.svg") { items.infoTxt.text = qsTr("AND gate takes 2 or more binary input in its input terminals and outputs a single " + "value. The output is 0 if any of the input is 0, else it is 1. In this activity, " + "a 2 input AND gate is shown. Truth table for 2 input AND gate is:") - items.infoImage.source = url + "AndTruthTable.svg" + //items.infoImage.source = url + "AndTruthTable.svg" + items.truthTablesModel.rows = 1 + items.truthTablesModel.columns = 3 + items.truthTablesModel.inputs = 2 + items.truthTablesModel.outputs = 1 + items.truthTablesModel.append({'value': "A"}) + items.truthTablesModel.append({'value': "B"}) + items.truthTablesModel.append({'value': "C"}) + } else if(componentName == "gateNand.svg") { items.infoTxt.text = qsTr("NAND gate takes 2 or more binary input in its input terminals and outputs a single " + "value. It is the complement of AND gate. In this activity, a 2 input NAND gate is " + "shown. Truth table for 2 input NAND gate is:") - items.infoImage.source = url + "NandTruthTable.svg" + //items.infoImage.source = url + "NandTruthTable.svg" } else if(componentName == "gateNor.svg") { items.infoTxt.text = qsTr("NOR gate takes 2 or more binary input in its input terminals and outputs a single " + "value. It is the complement of OR gate. In this activity, a 2 input NOR gate is " + "shown. Truth table for 2 input NOR gate is:") - items.infoImage.source = url + "NorTruthTable.svg" + //items.infoImage.source = url + "NorTruthTable.svg" } else if(componentName == "gateNot.svg") { items.infoTxt.text = qsTr("Not gate (also known as inverter) takes a binary input in its input terminal and " + "outputs a single value. The output is the complement of the input value, that is, it " + "is 0 if input is 1, and 1 if input is 0. Truth table for NOT gate is:") - items.infoImage.source = url + "NotTruthTable.svg" + //items.infoImage.source = url + "NotTruthTable.svg" } else if(componentName == "gateOr.svg") { items.infoTxt.text = qsTr("OR gate takes 2 or more binary input in its input terminals and outputs a single " + "value. The output is 1 if any of the input is 1, else it is 0. In this activity, a " + "2 input OR gate is shown. Truth table for 2 input OR gate is:") - items.infoImage.source = url + "OrTruthTable.svg" + //items.infoImage.source = url + "OrTruthTable.svg" } else if(componentName == "gateXor.svg") { items.infoTxt.text = qsTr("XOR gate takes 2 or more binary input in its input terminals and outputs a single " + "value. The output is 1 if number of '1' in input is odd, and 0 if number of '1' in " + "input is even. In this activity, a 2 input XOR gate is shown. Truth table for " + "2 input XOR gate is:") - items.infoImage.source = url + "XorTruthTable.svg" + //items.infoImage.source = url + "XorTruthTable.svg" } else if(componentName == "comparator.svg") { items.infoTxt.text = qsTr("Comparator takes 2 numbers as input, A and B. It compares them and outputs 3 " + "values. First value is true if A < B, else it is false. Second value is true " + "if A = B, else it is false. Third value is true if A > B, else it is false. " + "In digital electronics, true value is represented as 1, and false value is " + "represented as 0") } /*else if(componentName == "BCDTo7Segment.svg") { items.infoTxt.text = qsTr("BCD to 7 segment converter takes 4 binary inputs in its input terminals and gives " + "7 binary outputs. The 4 binary inputs represents a BCD number (binary-coded decimal). " + "The converter converts this BCD number to corresponding bits, which are used to " + "display the decimal number (represented by the BCD number) on the 7 segment display. " + "The truth table for BCD To 7 Segment converted is:") - items.infoImage.source = url + "BCDTo7SegmentTruthTable.svg" - }*/ + //items.infoImage.source = url + "BCDTo7SegmentTruthTable.svg" + } else if(componentName == "BCDTo7Segment.svg") { items.infoTxt.text = qsTr("BCD to 7 segment converter takes 4 binary inputs which represent a BCD number, " + "and convert them to 7 binary bits which represent corresponding number in 7 segment " + "format. The truth table is:") - items.infoImage.source = url + "BCDTo7SegmentTruthTable.svg" + //items.infoImage.source = url + "BCDTo7SegmentTruthTable.svg" } else if(componentName == "sevenSegmentDisplay.svg") { items.infoTxt.text = qsTr("7 segment display takes 7 binary inputs in its input terminals. The display " + "consists of 7 segments and each segment gets lighted according to the input. " + "By generating different combination of binary inputs, the display can be used to " + "display various different symbols. The diagram is:") - items.infoImage.source = url + "7SegmentDisplay.svg" + //items.infoImage.source = url + "7SegmentDisplay.svg" } else if(componentName == "ledOn.svg" || componentName == "ledOff.svg") { items.infoTxt.text = qsTr("LED (Light-emitting diode) is a two-lead semiconductor light source. It emits " + "light when activated. LED has 2 input terminals, the longer terminal is the " + "positive terminal (anode) and smaller terminal is the negative terminal (cathode)" + ". LED is activated when anode has a higher potential than cathode. In digital " + "electronics LED can be used to check the output of the components. Connect " + "the cathode of LED to ground ('0') and anode of LED to the output of the " + "component. If output is 1, the LED will be activated (emit light), and if " + "output is 0, the LED will be deactivated.") - items.infoImage.source = "" + //items.infoImage.source = "" } else if(componentName == "switchOn.svg" || componentName == "switchOff.svg") { items.infoTxt.text = qsTr("Switch is used to maintain easy connection between two terminals. If the switch is " + "turned on, then the two terminals are connected and current can flow through the " + "switch. If the switch is turned off, then the connection between terminal is broken, " + "and current can not flow through it.") - items.infoImage.source = "" - } + //items.infoImage.source = "" + }*/ //console.log(items.infoTxt.text) } function updateToolTip(toolTipTxt) { items.toolTip.show(toolTipTxt) } function nextLevel() { if(numberOfLevel <= ++currentLevel ) { currentLevel = 0 } initLevel(); } function previousLevel() { if(--currentLevel < 0) { currentLevel = numberOfLevel - 1 } initLevel(); } diff --git a/src/activities/digital_electricity/resource/AndTruthTable.svg b/src/activities/digital_electricity/resource/AndTruthTable.svg deleted file mode 100644 index befa60787..000000000 --- a/src/activities/digital_electricity/resource/AndTruthTable.svg +++ /dev/null @@ -1,309 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - 0 - 0 - 1 - 1 - 0 - 1 - 0 - 1 - A - B - Input - Output - 0 - 0 - 0 - 1 - A.B - - - - - - - - diff --git a/src/activities/digital_electricity/resource/BCDTo7SegmentTruthTable.svg b/src/activities/digital_electricity/resource/BCDTo7SegmentTruthTable.svg deleted file mode 100644 index a49bd760c..000000000 --- a/src/activities/digital_electricity/resource/BCDTo7SegmentTruthTable.svg +++ /dev/null @@ -1,1763 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - 0 - 1 - 0 - 1 - D - Input - Output - 1 - 1 - 0 - 1 - a - - - - - - 1 - 1 - 0 - 0 - C - - 0 - 0 - 1 - 1 - B - 0 - 0 - 0 - 0 - A - - - - - - - - - - - - 1 - 1 - 1 - 0 - b - 0 - 1 - 1 - 1 - c - 1 - 1 - 0 - 1 - d - 1 - 0 - 0 - 0 - e - 0 - 0 - 1 - 1 - f - 1 - 1 - 1 - 1 - g - - - 2 - 3 - 4 - 5 - 0 - 1 - 0 - 1 - 1 - 1 - 1 - 1 - - - - 1 - 1 - 0 - 0 - 1 - 1 - 0 - 0 - 0 - 0 - 1 - 1 - - 0 - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 1 - 0 - 1 - 0 - 1 - 0 - 1 - 1 - 1 - 0 - 1 - 1 - - 6 - 7 - 8 - 9 - - - 7 Segment - display - - 1 - 1 - 1 - 1 - 0 - 1 - 1 - 0 - - - 0 - 0 - 0 - 0 - 0 - 0 - 1 - 1 - 1 - 1 - 1 - 0 - 1 - 0 - 1 - 0 - 0 - 0 - - 0 - 1 - - - diff --git a/src/activities/digital_electricity/resource/Components.qml b/src/activities/digital_electricity/resource/Components.qml new file mode 100644 index 000000000..8cb93f346 --- /dev/null +++ b/src/activities/digital_electricity/resource/Components.qml @@ -0,0 +1,136 @@ +/* GCompris + * + * Copyright (C) 2016 Pulkit Gupta + * + * Authors: + * Bruno Coudoin (GTK+ version) + * Pulkit Gupta (Qt Quick port) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ +import QtQuick 2.0 + +QtObject { + property variant components : [ + { + "imgName": "zero.svg", + "imgWidth": 0.12, + "imgHeight": 0.2, + "toolTipText": qsTr("Zero input"), + "terminalSize": 0.205, + "inputTerminals": [], + "outputTerminals": [ + { + "posX": 0.91, + "posY": 0.5, + "value": 0 + } + ], + "information": qsTr("Digital electronics is a branch of electronics that handle digital signals " + + "(i.e discrete signals instead of continous signals). Therefore all values within " + + "a range or band represent the same numeric value. In most cases, the number of " + + "these states is two and they are represented by two voltage bands: one near a " + + "reference value (typically termed as 'ground' or zero volts), and other value near " + + "the supply voltage. These correspond to the 'false' ('0') and 'true' ('1') values " + + "of the Boolean domain respectively (named after its inventor, George Boole). " + + "In this activity, you can give '0' and '1' as input to other logical devices, " + + "and see their output through an output device."), + "truthTable": [] + + }, + { + "imgName": "one.svg", + "imgWidth": 0.12, + "imgHeight": 0.2, + "toolTipText": qsTr("One input"), + "terminalSize": 0.218, + "inputTerminals": [], + "outputTerminals": [ + { + "posX": 0.91, + "posY": 0.5, + "value": 1 + } + ], + "information": qsTr("Digital electronics is a branch of electronics that handle digital signals " + + "(i.e discrete signals instead of continous signals). Therefore all values within " + + "a range or band represent the same numeric value. In most cases, the number of " + + "these states is two and they are represented by two voltage bands: one near a " + + "reference value (typically termed as 'ground' or zero volts), and other value near " + + "the supply voltage. These correspond to the 'false' ('0') and 'true' ('1') values " + + "of the Boolean domain respectively (named after its inventor, George Boole). " + + "In this activity, you can give '0' and '1' as input to other logical devices, " + + "and see their output through an output device."), + "truthTable": [] + }, + { + "imgName": "gateAnd.svg", + "imgWidth": 0.15, + "imgHeight": 0.12, + "toolTipText": qsTr("AND gate"), + "terminalSize": 0.246, + "inputTerminals": [ + { + "posX": 0.045, + "posY": 0.219 + }, + { + "posX": 0.045, + "posY": 0.773 + } + ], + "outputTerminals": [ + { + "posX": 0.955, + "posY": 0.5 + } + ], + "information": qsTr("AND gate takes 2 or more binary input in its input terminals and outputs a single " + + "value. The output is 0 if any of the input is 0, else it is 1. In this activity, " + + "a 2 input AND gate is shown. Truth table for 2 input AND gate is:"), + "truthTable": [['A','B',"A.B"], + ['0','0','0'], + ['0','1','0'], + ['1','0','0'], + ['1','1','1']] + }, + { + "imgName": "ledOff.svg", + "imgWidth": 0.16, + "imgHeight": 0.2, + "toolTipText": qsTr("LED"), + "terminalSize": 0.111, + "inputTerminals": [ + { + "posX": 0.319, + "posY": 0.945, + }, + { + "posX": 0.776, + "posY": 0.698 + } + ], + "outputTerminals": [], + "information": qsTr("LED (Light-emitting diode) is a two-lead semiconductor light source. It emits " + + "light when activated. LED has 2 input terminals, the longer terminal is the " + + "positive terminal (anode) and smaller terminal is the negative terminal (cathode)" + + ". LED is activated when anode has a higher potential than cathode. In digital " + + "electronics LED can be used to check the output of the components. Connect " + + "the cathode of LED to ground ('0') and anode of LED to the output of the " + + "component. If output is 1, the LED will be activated (emit light), and if " + + "output is 0, the LED will be deactivated."), + "truthTable": [] + } + ] +} diff --git a/src/activities/digital_electricity/resource/NandTruthTable.svg b/src/activities/digital_electricity/resource/NandTruthTable.svg deleted file mode 100644 index 06639c09d..000000000 --- a/src/activities/digital_electricity/resource/NandTruthTable.svg +++ /dev/null @@ -1,309 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - 0 - 0 - 1 - 1 - 0 - 1 - 0 - 1 - A - B - Input - Output - 1 - 1 - 1 - 0 - ~(A.B) - - - - - - - - diff --git a/src/activities/digital_electricity/resource/NorTruthTable.svg b/src/activities/digital_electricity/resource/NorTruthTable.svg deleted file mode 100644 index 3b910b9c3..000000000 --- a/src/activities/digital_electricity/resource/NorTruthTable.svg +++ /dev/null @@ -1,309 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - 0 - 0 - 1 - 1 - 0 - 1 - 0 - 1 - A - B - Input - Output - 1 - 0 - 0 - 0 - ~(A+B) - - - - - - - - diff --git a/src/activities/digital_electricity/resource/NotTruthTable.svg b/src/activities/digital_electricity/resource/NotTruthTable.svg deleted file mode 100644 index 5b1f9082c..000000000 --- a/src/activities/digital_electricity/resource/NotTruthTable.svg +++ /dev/null @@ -1,187 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - 0 - 1 - A - Input - Output - 1 - 0 - ~A - - - - - diff --git a/src/activities/digital_electricity/resource/OrTruthTable.svg b/src/activities/digital_electricity/resource/OrTruthTable.svg deleted file mode 100644 index e61c04d53..000000000 --- a/src/activities/digital_electricity/resource/OrTruthTable.svg +++ /dev/null @@ -1,309 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - 0 - 0 - 1 - 1 - 0 - 1 - 0 - 1 - A - B - Input - Output - 0 - 1 - 1 - 1 - A+B - - - - - - - - diff --git a/src/activities/digital_electricity/resource/XorTruthTable.svg b/src/activities/digital_electricity/resource/XorTruthTable.svg deleted file mode 100644 index 217db8669..000000000 --- a/src/activities/digital_electricity/resource/XorTruthTable.svg +++ /dev/null @@ -1,315 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - 0 - 0 - 1 - 1 - 0 - 1 - 0 - 1 - A - B - Input - Output - 0 - 1 - 1 - 0 - A+B - - - - - - - - diff --git a/src/activities/digital_electricity/resource/deleteOff.svg b/src/activities/digital_electricity/resource/deleteOff.svg new file mode 100644 index 000000000..762ec22e5 --- /dev/null +++ b/src/activities/digital_electricity/resource/deleteOff.svg @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + eraser + 2007-04-17T19:52:58 + + https://openclipart.org/detail/3981/eraser-by-lmproulx + + + lmproulx + + + + + eraser + tool + + + + + + + + + + + diff --git a/src/activities/digital_electricity/resource/deleteOn.svg b/src/activities/digital_electricity/resource/deleteOn.svg new file mode 100644 index 000000000..8a63bddaf --- /dev/null +++ b/src/activities/digital_electricity/resource/deleteOn.svg @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + eraser + 2007-04-17T19:52:58 + + https://openclipart.org/detail/3981/eraser-by-lmproulx + + + lmproulx + + + + + eraser + tool + + + + + + + + + + + diff --git a/src/activities/digital_electricity/resource/tool-del.png b/src/activities/digital_electricity/resource/tool-del.png deleted file mode 100644 index 44bbda34b..000000000 Binary files a/src/activities/digital_electricity/resource/tool-del.png and /dev/null differ diff --git a/src/activities/digital_electricity/resource/tool-del_on.png b/src/activities/digital_electricity/resource/tool-del_on.png deleted file mode 100644 index bcef27a33..000000000 Binary files a/src/activities/digital_electricity/resource/tool-del_on.png and /dev/null differ