diff --git a/src/activities/digital_electricity/BCDToSevenSegment.qml b/src/activities/digital_electricity/BCDToSevenSegment.qml deleted file mode 100644 index c56be6cce..000000000 --- a/src/activities/digital_electricity/BCDToSevenSegment.qml +++ /dev/null @@ -1,102 +0,0 @@ -/* GCompris - BCDToSevenSegment.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 - -Item { - id: bcdTosevenSegment - property variant code - height: parent.height - width: parent.width - - Image { - source: Activity.url + (code[0] == 1 ? "BCDTo7SegmentA_red.svgz" : "BCDTo7SegmentA_black.svgz") - anchors.centerIn: parent - height: parent.height - width: parent.width - fillMode: Image.PreserveAspectFit - mipmap: true - antialiasing: true - } - - Image { - source: Activity.url + (code[1] == 1 ? "BCDTo7SegmentB_red.svgz" : "BCDTo7SegmentB_black.svgz") - anchors.centerIn: parent - height: parent.height - width: parent.width - fillMode: Image.PreserveAspectFit - mipmap: true - antialiasing: true - } - - Image { - source: Activity.url + (code[2] == 1 ? "BCDTo7SegmentC_red.svgz" : "BCDTo7SegmentC_black.svgz") - anchors.centerIn: parent - height: parent.height - width: parent.width - fillMode: Image.PreserveAspectFit - mipmap: true - antialiasing: true - } - - Image { - source: Activity.url + (code[3] == 1 ? "BCDTo7SegmentD_red.svgz" : "BCDTo7SegmentD_black.svgz") - anchors.centerIn: parent - height: parent.height - width: parent.width - fillMode: Image.PreserveAspectFit - mipmap: true - antialiasing: true - } - - Image { - source: Activity.url + (code[4] == 1 ? "BCDTo7SegmentE_red.svgz" : "BCDTo7SegmentE_black.svgz") - anchors.centerIn: parent - height: parent.height - width: parent.width - fillMode: Image.PreserveAspectFit - mipmap: true - antialiasing: true - } - - Image { - source: Activity.url + (code[5] == 1 ? "BCDTo7SegmentF_red.svgz" : "BCDTo7SegmentF_black.svgz") - anchors.centerIn: parent - height: parent.height - width: parent.width - fillMode: Image.PreserveAspectFit - mipmap: true - antialiasing: true - } - - Image { - source: Activity.url + (code[6] == 1 ? "BCDTo7SegmentG_red.svgz" : "BCDTo7SegmentG_black.svgz") - anchors.centerIn: parent - height: parent.height - width: parent.width - fillMode: Image.PreserveAspectFit - mipmap: true - antialiasing: true - } -} diff --git a/src/activities/digital_electricity/CMakeLists.txt b/src/activities/digital_electricity/CMakeLists.txt index 9e91c9f0c..b2e6cb264 100644 --- a/src/activities/digital_electricity/CMakeLists.txt +++ b/src/activities/digital_electricity/CMakeLists.txt @@ -1 +1 @@ -GCOMPRIS_ADD_RCC(activities/digital_electricity *.qml *.svg *.js resource/*) +GCOMPRIS_ADD_RCC(activities/digital_electricity *.qml *.svg *.js resource/* components/*) diff --git a/src/activities/digital_electricity/DragListItem.qml b/src/activities/digital_electricity/DragListItem.qml index 3db2f3ba3..f0917f5be 100644 --- a/src/activities/digital_electricity/DragListItem.qml +++ b/src/activities/digital_electricity/DragListItem.qml @@ -1,141 +1,141 @@ /* gcompris - DragListItem.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 GCompris 1.0 import "digital_electricity.js" as Activity Item { id: item width: tile.width height: tile.height property string source: imgName property double heightInColumn property double widthInColumn property double tileWidth property double tileHeight property bool selected: false //property double terminalSize: size signal pressed Rectangle { id: tile width: tileWidth height: tileHeight color: (parent.selected && tileImage.parent == tile) ? "#33FF294D" : "transparent" border.color: (parent.selected && tileImage.parent == tile) ? "white" : "transparent" border.width: 3 radius: 2 property double xCenter: tile.x + tile.width / 2 property double yCenter: tile.y + tile.height / 2 property bool selected: false Image { anchors.centerIn: parent width: widthInColumn height: heightInColumn fillMode: Image.PreserveAspectFit source: Activity.url + imgName } Image { id: tileImage anchors.centerIn: parent width: smallWidth height: smallHeight fillMode: Image.PreserveAspectFit source: Activity.url + imgName mipmap: true antialiasing: true property double smallWidth: widthInColumn property double smallHeight: heightInColumn property double fullWidth: imgWidth * backgroundContainer.width property double fullHeight: imgHeight * backgroundContainer.height property QtObject tileImageParent property bool small: true function toSmall() { width = smallWidth height = smallHeight small = true } function toFull() { width = fullWidth height = fullHeight small = false } MultiPointTouchArea { id: mouseArea touchPoints: [ TouchPoint { id: point1 } ] property real startX property real startY property bool pressedOnce anchors.fill: parent onPressed: { //item.pressed() //tileImage.toSmall() //console.log("onPressed 1",tileImage.parent) tileImage.anchors.centerIn = undefined //console.log("onPressed 2",tileImage.parent) startX = point1.x startY = point1.y tileImage.toFull() toolTip.show(toolTipText) pressedOnce = true item.selected = true } onUpdated: { var moveX = point1.x - startX var moveY = point1.y - startY parent.x = parent.x + moveX parent.y = parent.y + moveY //console.log("parent.x",parent.x,"parent.y",parent.y) } onReleased: { if (pressedOnce) { pressedOnce = false item.selected = false //console.log("dropped parent.x",parent.x,"parent.y",parent.y) var coord = backgroundContainer.mapFromItem(tileImage.parent, parent.x, parent.y) //console.log("coord.x",coord.x,"coord.y",coord.y) //console.log("dropped",terminalSize) if(coord.x > 0 && (backgroundContainer.width - coord.x > tileImage.fullWidth)) - Activity.createComponent(coord.x, coord.y, imgName, imgWidth, imgHeight, toolTipText, terminalSize) + Activity.createComponent(coord.x, coord.y, imgName) tileImage.anchors.centerIn = tile tileImage.toSmall() toolTip.show("") } } } } } } diff --git a/src/activities/digital_electricity/SevenSegment.qml b/src/activities/digital_electricity/SevenSegment.qml deleted file mode 100644 index 1da2646da..000000000 --- a/src/activities/digital_electricity/SevenSegment.qml +++ /dev/null @@ -1,109 +0,0 @@ -/* GCompris - SevenSegment.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 - -Item { - id: sevenSegment - property variant code - height: parent.height - width: parent.width - - Image { - source: Activity.url + "sevenSegmentDisplayA.svgz" - visible: code[0] == 1 - anchors.centerIn: parent - height: parent.height - width: parent.width - fillMode: Image.PreserveAspectFit - mipmap: true - antialiasing: true - } - - Image { - source: Activity.url + "sevenSegmentDisplayB.svgz" - visible: code[1] == 1 - anchors.centerIn: parent - height: parent.height - width: parent.width - fillMode: Image.PreserveAspectFit - mipmap: true - antialiasing: true - } - - Image { - source: Activity.url + "sevenSegmentDisplayC.svgz" - visible: code[2] == 1 - anchors.centerIn: parent - height: parent.height - width: parent.width - fillMode: Image.PreserveAspectFit - mipmap: true - antialiasing: true - } - - Image { - source: Activity.url + "sevenSegmentDisplayD.svgz" - visible: code[3] == 1 - anchors.centerIn: parent - height: parent.height - width: parent.width - fillMode: Image.PreserveAspectFit - mipmap: true - antialiasing: true - } - - Image { - source: Activity.url + "sevenSegmentDisplayE.svgz" - visible: code[4] == 1 - anchors.centerIn: parent - height: parent.height - width: parent.width - fillMode: Image.PreserveAspectFit - mipmap: true - antialiasing: true - } - - Image { - source: Activity.url + "sevenSegmentDisplayF.svgz" - visible: code[5] == 1 - anchors.centerIn: parent - height: parent.height - width: parent.width - fillMode: Image.PreserveAspectFit - mipmap: true - antialiasing: true - } - - Image { - source: Activity.url + "sevenSegmentDisplayG.svgz" - visible: code[6] == 1 - anchors.centerIn: parent - height: parent.height - width: parent.width - fillMode: Image.PreserveAspectFit - mipmap: true - antialiasing: true - } -} diff --git a/src/activities/digital_electricity/Wire.qml b/src/activities/digital_electricity/Wire.qml index b22e89095..72760de91 100644 --- a/src/activities/digital_electricity/Wire.qml +++ b/src/activities/digital_electricity/Wire.qml @@ -1,66 +1,52 @@ /* GCompris - Wire.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 Rectangle { id: wire - //property double posX1 - //property double posY1 - //property double posX2 - //property double posY2 - //property double rectWidth - //property double rotateAngle property string wireColor + property QtObject from + property QtObject to - property int index - property int from - property int to - - //width: rectWidth height: 5 - color: wireColor //"Red" + color: wireColor radius: height / 2 - - //x: posX1 - //y: posY1 - transformOrigin: Item.Left - //rotation: rotateAngle MouseArea { id: mouseArea //anchors.fill: parent width: parent.width height: parent.height * 3 anchors.centerIn: parent onPressed: { - //console.log("Pressed Wire",index,color,wireColor) + //console.log("Pressed Wire",color,wireColor) if(Activity.toolDelete) { - Activity.removeWire(index) + Activity.removeWire(wire) } } } } diff --git a/src/activities/digital_electricity/components/AndGate.qml b/src/activities/digital_electricity/components/AndGate.qml new file mode 100644 index 000000000..b88dd0124 --- /dev/null +++ b/src/activities/digital_electricity/components/AndGate.qml @@ -0,0 +1,95 @@ +/* GCompris - AndGate.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 GCompris 1.0 + +ElectricalComponent { + id: andGate + imgWidth: 0.15 + imgHeight: 0.12 + imgSrc: "gateAnd.svg" + toolTipTxt: qsTr("AND gate") + terminalSize: 0.246 + noOfInputs: 2 + noOfOutputs: 1 + property variant inputTerminalPosY: [0.219, 0.773] + + 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']] + + property alias inputTerminals: inputTerminals + property alias outputTerminals: outputTerminals + + Repeater { + id: inputTerminals + model: 2 + delegate: inputTerminal + Component { + id: inputTerminal + TerminalPoint { + posX: 0.045 + posY: inputTerminalPosY[index] + type: "In" + } + } + } + + Repeater { + id: outputTerminals + model: 1 + delegate: outputTerminal + Component { + id: outputTerminal + TerminalPoint { + posX: 0.955 + posY: 0.5 + type: "Out" + } + } + } + + function updateOutput(wireVisited) { + var terminal = outputTerminals.itemAt(0) + terminal.value = inputTerminals.itemAt(0).value & inputTerminals.itemAt(1).value + //console.log("component",andGate,terminal.value) + for(var i = 0 ; i < terminal.wires.length ; ++i) + terminal.wires[i].to.value = terminal.value + + var componentVisited = [] + for(var i = 0 ; i < terminal.wires.length ; ++i) { + var wire = terminal.wires[i] + var component = wire.to.parent + if(componentVisited[component] != true && wireVisited[wire] != true) { + componentVisited[component] = true + wireVisited[wire] = true + component.updateOutput(wireVisited) + } + } + } +} diff --git a/src/activities/digital_electricity/components/BCDToSevenSegment.qml b/src/activities/digital_electricity/components/BCDToSevenSegment.qml new file mode 100644 index 000000000..559d9e612 --- /dev/null +++ b/src/activities/digital_electricity/components/BCDToSevenSegment.qml @@ -0,0 +1,159 @@ +/* GCompris - BCDToSevenSegment.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 + +ElectricalComponent { + id: bcdTo7Segment + imgWidth: 0.3 + imgHeight: 0.4 + imgSrc: "BCDTo7SegmentDropped.svg" + toolTipTxt: qsTr("BCD To 7 Segment") + terminalSize: 0.097 + noOfInputs: 4 + noOfOutputs: 7 + property variant inputTerminalPosY: [0.057,0.35,0.649,0.935] + property variant outputTerminalPosY: [0.048,0.198,0.353,0.509,0.664,0.812,0.952] + property variant blackChar: ["BCDTo7SegmentA_black.svgz","BCDTo7SegmentB_black.svgz","BCDTo7SegmentC_black.svgz", + "BCDTo7SegmentD_black.svgz","BCDTo7SegmentE_black.svgz","BCDTo7SegmentF_black.svgz", + "BCDTo7SegmentG_black.svgz"] + property variant redChar: ["BCDTo7SegmentA_red.svgz","BCDTo7SegmentB_red.svgz","BCDTo7SegmentC_red.svgz", + "BCDTo7SegmentD_red.svgz","BCDTo7SegmentE_red.svgz","BCDTo7SegmentF_red.svgz", + "BCDTo7SegmentG_red.svgz"] + + information: 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:") + + truthTable: [['A','B','C','D','a','b','c','d','e','f','g'], + ['0','0','0','0','1','1','1','1','1','1','0'], + ['0','0','0','1','0','1','1','0','0','0','0'], + ['0','0','1','0','1','1','0','1','1','0','1'], + ['0','0','1','1','1','1','1','1','0','0','1'], + ['0','1','0','0','0','1','1','0','0','1','1'], + ['0','1','0','1','1','0','1','1','0','1','1'], + ['0','1','1','0','1','0','1','1','1','1','1'], + ['0','1','1','1','1','1','1','0','0','0','0'], + ['1','0','0','0','1','1','1','1','1','1','1'], + ['1','0','0','1','1','1','1','1','0','1','1']] + + property alias inputTerminals: inputTerminals + property alias outputTerminals: outputTerminals + + Repeater { + id: inputTerminals + model: 4 + delegate: inputTerminal + Component { + id: inputTerminal + TerminalPoint { + posX: 0.031 + posY: inputTerminalPosY[index] + type: "In" + } + } + } + + Repeater { + id: outputTerminals + model: 7 + delegate: outputTerminal + Component { + id: outputTerminal + TerminalPoint { + posX: 0.969 + posY: outputTerminalPosY[index] + type: "Out" + } + } + } + + function updateOutput(wireVisited) { + + var i + for(i = 1 ; i < truthTable.length ; ++i) { + var j + for(j = 0 ; j < noOfInputs; ++j) { + if(inputTerminals.itemAt(j).value != truthTable[i][j]) + break + } + if(j == noOfInputs) + break + } + if(i == truthTable.length) { + for(var j = 0 ; j < noOfOutputs ; ++j) { + outputTerminals.itemAt(j).value = 0 + outputChar.itemAt(j).source = Activity.url + blackChar[j] + } + } + else { + // truthTable[i][j + noOfInputs] gives value of the outputs (which are just after the inputs) + for(var j = 0 ; j < noOfOutputs ; ++j) { + var terminal = outputTerminals.itemAt(j) + terminal.value = truthTable[i][j + noOfInputs] + outputChar.itemAt(j).source = Activity.url + (terminal.value == 0 ? blackChar[j] : redChar[j]) + } + } + + for(var i = 0 ; i < noOfOutputs ; ++i) { + var terminal = outputTerminals.itemAt(i) + for(var j = 0 ; j < terminal.wires.length ; ++j) + terminal.wires[j].to.value = terminal.value + } + + var componentVisited = [] + for(var i = 0 ; i < noOfOutputs ; ++i) { + var terminal = outputTerminals.itemAt(i) + for(var j = 0 ; j < terminal.wires.length ; ++j) { + var wire = terminal.wires[j] + var component = wire.to.parent + if(componentVisited[component] != true && wireVisited[wire] != true) { + componentVisited[component] = true + wireVisited[wire] = true + component.updateOutput(wireVisited) + } + } + } + } + + Repeater { + id: outputChar + model: 7 + delegate: outputCharImages + Component { + id: outputCharImages + Image { + source: "" + anchors.centerIn: parent + height: parent.height + width: parent.width + fillMode: Image.PreserveAspectFit + mipmap: true + antialiasing: true + } + } + } +} diff --git a/src/activities/digital_electricity/components/DigitalLight.qml b/src/activities/digital_electricity/components/DigitalLight.qml new file mode 100644 index 000000000..f8c444c77 --- /dev/null +++ b/src/activities/digital_electricity/components/DigitalLight.qml @@ -0,0 +1,95 @@ +/* GCompris - DigitalLight.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 GCompris 1.0 + +ElectricalComponent { + id: digitalLight + imgWidth: 0.2 + imgHeight: 0.18 + imgSrc: "DigitalLightOff.svg" + toolTipTxt: qsTr("Digital Light") + terminalSize: 0.358 + noOfInputs: 1 + noOfOutputs: 1 + + information: qsTr("Digital light is used to check the output of other digital components. It forwards " + + "its input to its output. If the input is 1, then the digital light will glow, else " + + "it will turn off.") + + truthTable: [] + + property alias inputTerminals: inputTerminals + property alias outputTerminals: outputTerminals + + Repeater { + id: inputTerminals + model: 1 + delegate: inputTerminal + Component { + id: inputTerminal + TerminalPoint { + posX: 0.066 + posY: 0.497 + type: "In" + } + } + } + + Repeater { + id: outputTerminals + model: 1 + delegate: outputTerminal + Component { + id: outputTerminal + TerminalPoint { + posX: 0.934 + posY: 0.497 + type: "Out" + } + } + } + + function updateOutput(wireVisited) { + + var terminal = outputTerminals.itemAt(0) + terminal.value = inputTerminals.itemAt(0).value == 1 ? 1 : 0 + if(terminal.value == 1) + imgSrc = "DigitalLightOn.svg" + else + imgSrc = "DigitalLightOff.svg" + + for(var i = 0 ; i < terminal.wires.length ; ++i) + terminal.wires[i].to.value = terminal.value + + var componentVisited = [] + for(var i = 0 ; i < terminal.wires.length ; ++i) { + var wire = terminal.wires[i] + var component = wire.to.parent + if(componentVisited[component] != true && wireVisited[wire] != true) { + componentVisited[component] = true + wireVisited[wire] = true + component.updateOutput(wireVisited) + } + } + } +} diff --git a/src/activities/digital_electricity/ElectricalComponent.qml b/src/activities/digital_electricity/components/ElectricalComponent.qml similarity index 92% rename from src/activities/digital_electricity/ElectricalComponent.qml rename to src/activities/digital_electricity/components/ElectricalComponent.qml index 099292e7e..6a7047acc 100644 --- a/src/activities/digital_electricity/ElectricalComponent.qml +++ b/src/activities/digital_electricity/components/ElectricalComponent.qml @@ -1,149 +1,146 @@ /* 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 "../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 imgSrc + property string information property string toolTipTxt + property variant truthTable: [] + property int index + property int noOfInputs + property int noOfOutputs 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 == "BCDTo7Segment.svg" ? "BCDTo7SegmentDropped.svg" : imgSrc) + + source: Activity.url + imgSrc z: 2 mipmap: true antialiasing: true onPaintedWidthChanged: { updateDragConstraints() Activity.updateWires(index) } 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() } else rotateComponent.start() } easing.type: Easing.InOutQuad } function updateDragConstraints() { //console.log("initialAngle",initialAngle) if(initialAngle == 0 || initialAngle == 180 || initialAngle == 360 || initialAngle == -360 || initialAngle == -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 onPressed: { //console.log("Component index",index) Activity.updateToolTip(toolTipTxt) Activity.componentSelected(index) } onClicked: { - //console.log("Component index",index) + console.log("Component index",index,electricalComponent) if(Activity.toolDelete) { Activity.removeComponent(index) } else { if(imgSrc == "switchOff.svg") { imgSrc = "switchOn.svg" Activity.updateComponent(index) } else if(imgSrc == "switchOn.svg") { imgSrc = "switchOff.svg" Activity.updateComponent(index) } } } - /*onPositionChanged: { - Activity.updateWires(index) - }*/ onReleased: { 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/components/One.qml b/src/activities/digital_electricity/components/One.qml new file mode 100644 index 000000000..57317b02b --- /dev/null +++ b/src/activities/digital_electricity/components/One.qml @@ -0,0 +1,78 @@ +/* GCompris - One.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 GCompris 1.0 + +ElectricalComponent { + id: one + imgWidth: 0.12 + imgHeight: 0.2 + imgSrc: "one.svg" + toolTipTxt: qsTr("One input") + terminalSize: 0.218 + noOfInputs: 0 + noOfOutputs: 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.") + + property alias outputTerminals: outputTerminals + + Repeater { + id: outputTerminals + model: 1 + delegate: outputTerminal + Component { + id: outputTerminal + TerminalPoint { + posX: 0.91 + posY: 0.5 + value: 1 + type: "Out" + } + } + } + + function updateOutput(wireVisited) { + var terminal = outputTerminals.itemAt(0) + for(var i = 0 ; i < terminal.wires.length ; ++i) + terminal.wires[i].to.value = terminal.value + + var componentVisited = [] + for(var i = 0 ; i < terminal.wires.length ; ++i) { + var wire = terminal.wires[i] + var component = wire.to.parent + if(componentVisited[component] != true && wireVisited[wire] != true) { + componentVisited[component] = true + wireVisited[wire] = true + component.updateOutput(wireVisited) + } + } + } +} diff --git a/src/activities/digital_electricity/components/SevenSegment.qml b/src/activities/digital_electricity/components/SevenSegment.qml new file mode 100644 index 000000000..1c5ead59c --- /dev/null +++ b/src/activities/digital_electricity/components/SevenSegment.qml @@ -0,0 +1,91 @@ +/* GCompris - SevenSegment.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 + +ElectricalComponent { + id: sevenSegmentDisplay + imgWidth: 0.18 + imgHeight: 0.4 + imgSrc: "sevenSegmentDisplay.svgz" + toolTipTxt: qsTr("7 Segment Display") + terminalSize: 0.116 + noOfInputs: 7 + noOfOutputs: 0 + property variant inputTerminalPosY: [0.058,0.195,0.337,0.484,0.636,0.791,0.942] + property variant redBars: ["sevenSegmentDisplayA.svgz","sevenSegmentDisplayB.svgz","sevenSegmentDisplayC.svgz", + "sevenSegmentDisplayD.svgz","sevenSegmentDisplayE.svgz","sevenSegmentDisplayF.svgz", + "sevenSegmentDisplayG.svgz"] + + information: 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:") + + property string infoImageSrc: "7SegmentDisplay.svg" + + property alias inputTerminals: inputTerminals + + Repeater { + id: inputTerminals + model: 7 + delegate: inputTerminal + Component { + id: inputTerminal + TerminalPoint { + posX: 0.06 + posY: inputTerminalPosY[index] + type: "In" + } + } + } + + function updateOutput(wireVisited) { + for(var i = 0 ; i < noOfInputs ; ++i) { + if(inputTerminals.itemAt(i).value == 1) + outputBar.itemAt(i).visible = true; + else + outputBar.itemAt(i).visible = false; + } + } + + Repeater { + id: outputBar + model: 7 + delegate: outputBarImages + Component { + id: outputBarImages + Image { + source: Activity.url + redBars[index] + visible: false //code[0] == 1 + anchors.centerIn: parent + height: parent.height + width: parent.width + fillMode: Image.PreserveAspectFit + mipmap: true + antialiasing: true + } + } + } +} diff --git a/src/activities/digital_electricity/TerminalPoint.qml b/src/activities/digital_electricity/components/TerminalPoint.qml similarity index 65% rename from src/activities/digital_electricity/TerminalPoint.qml rename to src/activities/digital_electricity/components/TerminalPoint.qml index 0d233d0fb..2c7ce0fd4 100644 --- a/src/activities/digital_electricity/TerminalPoint.qml +++ b/src/activities/digital_electricity/components/TerminalPoint.qml @@ -1,87 +1,71 @@ /* GCompris - TerminalPoint.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 "../digital_electricity.js" as Activity import GCompris 1.0 Rectangle { id: terminalPoint property double posX property double posY property double size: parent.terminalSize property bool selected: false property string type - property int value: -1 - property int index - property int componentIndex - property variant wireIndex: [] + property int value: 0 + property variant wires: [] width: size * parent.paintedHeight height: size * parent.paintedHeight radius: width / 2 color: "Black" x: (parent.width - parent.paintedWidth) / 2 + posX * parent.paintedWidth - width / 2 y: (parent.height - parent.paintedHeight) / 2 + posY * parent.paintedHeight - height / 2 - //property variant coord: parent.parent.mapFromItem(terminalPoint, terminalPoint.x + width / 2, terminalPoint.y + height / 2) - property double xCenter: terminalPoint.parent.x + terminalPoint.x + width/2 property double yCenter: terminalPoint.parent.y + terminalPoint.y + height/2 - //property double xCenterFromComponent: terminalPoint.parent.x + terminalPoint.parent.width / 2 - xCenter - //property double yCenterFromComponent: terminalPoint.parent.y + terminalPoint.parent.height / 2 - yCenter property double xCenterFromComponent: terminalPoint.x + width/2 - terminalPoint.parent.width / 2 property double yCenterFromComponent: terminalPoint.y + height/2 - terminalPoint.parent.height / 2 Rectangle { id: boundary anchors.centerIn: terminalPoint width: terminalPoint.width * 1.4 height: width visible: selected radius: width / 2 color: "green" z: -1 } MouseArea { id: mouseArea anchors.fill: parent onPressed: { selected = true - //console.log("Pressed Terminal",index,type,value) - Activity.terminalPointSelected(index) - //parent.parent.parent.moveFromX = parent.parent.x + mouseX - //parent.parent.parent.moveFromY = parent.parent.y + mouseY + console.log("Pressed Terminal",type,value) + Activity.terminalPointSelected(terminalPoint) } - /* - onPositionChanged: { - parent.parent.parent.moveToX = parent.parent.x + mouseX - parent.parent.parent.moveToY = parent.parent.y + mouseY - //console.log(parent.parent.parent.moveToX,parent.parent.parent.moveToY) - //console.log(parent.parent.x + mouseX,parent.parent.y + mouseY) - parent.parent.parent.requestPaint() - }*/ } } diff --git a/src/activities/digital_electricity/components/Zero.qml b/src/activities/digital_electricity/components/Zero.qml new file mode 100644 index 000000000..33125ee3e --- /dev/null +++ b/src/activities/digital_electricity/components/Zero.qml @@ -0,0 +1,80 @@ +/* GCompris - Zero.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 + +ElectricalComponent { + id: zero + imgWidth: 0.12 + imgHeight: 0.2 + imgSrc: "zero.svg" + toolTipTxt: qsTr("Zero input") + terminalSize: 0.205 + noOfInputs: 0 + noOfOutputs: 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.") + + property alias outputTerminals: outputTerminals + + Repeater { + id: outputTerminals + model: 1 + delegate: outputTerminal + Component { + id: outputTerminal + TerminalPoint { + posX: 0.91 + posY: 0.5 + value: 0 + type: "Out" + } + } + } + + function updateOutput(wireVisited) { + var terminal = outputTerminals.itemAt(0) + for(var i = 0 ; i < terminal.wires.length ; ++i) + terminal.wires[i].to.value = terminal.value + + var componentVisited = [] + for(var i = 0 ; i < terminal.wires.length ; ++i) { + var wire = terminal.wires[i] + var component = wire.to.parent + if(componentVisited[component] != true && wireVisited[wire] != true) { + componentVisited[component] = true + wireVisited[wire] = true + component.updateOutput(wireVisited) + } + } + } +} diff --git a/src/activities/digital_electricity/digital_electricity.js b/src/activities/digital_electricity/digital_electricity.js index c4ebb9ca2..82230d718 100644 --- a/src/activities/digital_electricity/digital_electricity.js +++ b/src/activities/digital_electricity/digital_electricity.js @@ -1,642 +1,396 @@ /* 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.3 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"] -var sevenSegmentDisplay = [] -var BCDTo7Segment = [] function start(items_) { items = items_ currentLevel = 0 - var filename = url + "ElectricalComponents.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") + }) + items.availablePieces.model.append( { + "imgName": "one.svg", + "imgWidth": 0.12, + "imgHeight": 0.2, + "toolTipText": qsTr("One input") + }) + items.availablePieces.model.append( { + "imgName": "gateAnd.svg", + "imgWidth": 0.15, + "imgHeight": 0.12, + "toolTipText": qsTr("AND gate") + }) + 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.svgz", + "imgWidth": 0.18, + "imgHeight": 0.4, + "toolTipText": qsTr("7 Segment Display") + }) + items.availablePieces.model.append( { + "imgName": "DigitalLightOff.svg", + "imgWidth": 0.2, + "imgHeight": 0.18, + "toolTipText": qsTr("Digital Light") + }) 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) { - if(components[i].imgSrc == "sevenSegmentDisplay.svgz") - sevenSegmentDisplay[i].destroy() - else if(components[i].imgSrc == "BCDTo7Segment.svg") - BCDTo7Segment[i].destroy() - 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() + if(j == deletedIndex.length) + removeComponent(i) } } function initLevel() { items.availablePieces.view.currentDisplayedGroup = 0 items.availablePieces.view.previousNavigation = 1 items.availablePieces.view.nextNavigation = 1 - terminals = [] deletedIndex = [] components = [] - wires = [] connected = [] - deletedWireIndex = [] - sevenSegmentDisplay = [] - BCDTo7Segment = [] animationInProgress = false deselect() toolDelete = false updateToolTip("") } function reset() { deselect() stop() initLevel() } -function createComponent(x, y, src, imgWidth, imgHeight, toolTipTxt, terminalSize) { +function createComponent(x, y, src) { - var electricComponent = Qt.createComponent("qrc:/gcompris/src/activities/digital_electricity/ElectricalComponent.qml") - //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]] + var electricComponent + var componentLocation = "qrc:/gcompris/src/activities/digital_electricity/components/" + if(src == "one.svg") + electricComponent = Qt.createComponent(componentLocation + "One.qml") + else if(src == "zero.svg") + electricComponent = Qt.createComponent(componentLocation + "Zero.qml") + else if(src == "gateAnd.svg") + electricComponent = Qt.createComponent(componentLocation + "AndGate.qml") + else if(src == "BCDTo7Segment.svg") + electricComponent = Qt.createComponent(componentLocation + "BCDToSevenSegment.qml") + else if(src == "sevenSegmentDisplay.svgz") + electricComponent = Qt.createComponent(componentLocation + "SevenSegment.qml") + else if(src == "DigitalLightOff.svg") + electricComponent = Qt.createComponent(componentLocation + "DigitalLight.qml") + + //console.log("Error loading component:", electricComponent.errorString()) components[index] = electricComponent.createObject( items.backgroundContainer, { "index": index, "posX": x, - "posY": y, - "imgSrc": src, - "imgWidth": componentInfo[0], - "imgHeight": componentInfo[1], - "toolTipTxt": componentInfo[2], - "terminalSize": componentInfo[3] + "posY": y }); - 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 == "sevenSegmentDisplay.svgz") { - var sevenSegmentComponent = Qt.createComponent("qrc:/gcompris/src/activities/digital_electricity/SevenSegment.qml") - sevenSegmentDisplay[index] = sevenSegmentComponent.createObject( - electricComponentCreated, { - "code": [0, 0, 0, 0, 0, 0, 0] - }); - sevenSegmentDisplay[index].anchors.centerIn = electricComponentCreated - } - else if(src == "BCDTo7Segment.svg") { - var BCDTo7SegmentComponent = Qt.createComponent( - "qrc:/gcompris/src/activities/digital_electricity/BCDToSevenSegment.qml") - BCDTo7Segment[index] = BCDTo7SegmentComponent.createObject( - electricComponentCreated, { - "code": [0, 0, 0, 0, 0, 0, 0] - }); - BCDTo7Segment[index].anchors.centerIn = electricComponentCreated - } - - 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": input[0], - "posY": input[1], - "index": terminalIndex - 1, - "type": "In", - "componentIndex": index, - "value": input[2] - }); - //console.log("posX",input[0]) - } - - 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": output[0], - "posY": output[1], - "index": terminalIndex - 1, - "type": "Out", - "componentIndex": index, - "value": output[2] - }); - } - componentSelected(index) + updateComponent(index) } -function terminalPointSelected(index) { +function terminalPointSelected(terminal) { - 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 + if(selectedTerminal == -1 || selectedTerminal == terminal) + selectedTerminal = terminal + else if((selectedTerminal.type != terminal.type) && (selectedTerminal.parent != terminal.parent)) { + var inTerminal = terminal.type == "In" ? terminal : selectedTerminal + var outTerminal = terminal.type == "Out" ? terminal : selectedTerminal //console.log("in, connected[inIndex]",connected[inIndex],"inIndex",inIndex) - if(connected[inIndex] == undefined || connected[inIndex] == -1) { + if(connected[inTerminal] == undefined || connected[inTerminal] == -1) { //console.log("in2") var wireComponent = Qt.createComponent("qrc:/gcompris/src/activities/digital_electricity/Wire.qml") - 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, { - "from": outIndex, - "to": inIndex, - "wireColor": colors[colorIndex], - "index": index - }); - terminals[inIndex].value = terminals[outIndex].value - terminals[inIndex].wireIndex.push(index) - terminals[outIndex].wireIndex.push(index) - updateWires(terminals[inIndex].componentIndex) - updateWires(terminals[outIndex].componentIndex) - updateComponent(terminals[inIndex].componentIndex) - connected[inIndex] = outIndex + var wire = wireComponent.createObject( + items.backgroundContainer, { + "from": outTerminal, + "to": inTerminal, + "wireColor": colors[colorIndex] + //"index": index + }); + inTerminal.value = outTerminal.value + inTerminal.wires.push(wire) + outTerminal.wires.push(wire) + updateWires(inTerminal.parent.index) + updateWires(outTerminal.parent.index) + updateComponent(inTerminal.parent.index) + connected[inTerminal] = outTerminal } deselect() } else { //console.log("else") deselect() - selectedTerminal = index - terminals[index].selected = true + selectedTerminal = terminal + terminal.selected = true } } function updateComponent(index) { - var visited = [] - 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 == "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 - } - else if(component.imgSrc == "sevenSegmentDisplay.svgz") { - var code = [] - for(var i = 0 ; i < 7 ; ++i) { - var value = terminals[component.inputs[i]].value - if(value == -1) { - code[i] = 0 - } - code[i] = value - } - sevenSegmentDisplay[index].code = code - return - } - else if(component.imgSrc == "switchOff.svg") { - terminals[component.outputs[0]].value = -1 - } - else if(component.imgSrc == "switchOn.svg") { - terminals[component.outputs[0]].value = terminals[component.inputs[0]].value - } - else if(component.imgSrc == "comparator.svg") { - var firstInput = terminals[component.inputs[0]].value - var secondInput = terminals[component.inputs[1]].value - if(firstInput != -1 && secondInput != -1) { - terminals[component.outputs[0]].value = firstInput < secondInput ? 1 : 0 - terminals[component.outputs[1]].value = firstInput == secondInput ? 1 : 0 - terminals[component.outputs[2]].value = firstInput > secondInput ? 1 : 0 - } - else { - terminals[component.outputs[0]].value = -1 - terminals[component.outputs[1]].value = -1 - terminals[component.outputs[2]].value = -1 - } - } - else { // For the components that have a truth table - var inputSet = false - var compnentInfo = componentsInfo[mapSrc[component.imgSrc]] - var truthTable = compnentInfo[7] - var i - var input = component.inputs - for(i = 1 ; i < truthTable.length ; ++i) { - var j - for(j = 0 ; j < input.length; ++j) { - if(terminals[input[j]].value != truthTable[i][j]) - break - } - if(j == input.length) - break - } - var output = component.outputs - if(i == truthTable.length) { - for(var j = 0 ; j < output.length ; ++j) - terminals[output[j]].value = -1 - } - else { - for(var j = 0 ; j < output.length ; ++j) - terminals[output[j]].value = truthTable[i][j + input.length] - } - } - - if(component.imgSrc == "BCDTo7Segment.svg") { - var inputChar = 0 - for(var i = 0 ; i < 4 ; ++i) { - var value = terminals[component.inputs[i]].value - if(value == -1) - value = 0 - inputChar += value * Math.pow(2, i) - } - - // 7 segment encoding as defined on - // https://en.wikipedia.org/wiki/Seven-segment_display#Displaying_letters - var coding = [ 0x7E, 0x30, 0x6D, 0x79, 0x33, 0x5B, 0x5F, 0x70, - 0x7F, 0x7B, 0x77, 0x1F, 0x4E, 0x3D, 0x4F, 0x47] - - var code = [] - for(var i = 0; i < 7; ++i) { - terminals[component.outputs[i]].value = ((coding[inputChar] & (1 << (6 - i))) ? 1 : 0) - code[i] = terminals[component.outputs[i]].value - } - BCDTo7Segment[index].code = code - } - - 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) - } - } + var wireVisited = [] + components[index].updateOutput(wireVisited) } function updateWires(index) { var component = components[index] - if(component == undefined || component.inputs == undefined || component.outputs == undefined) + if(component == undefined || component.noOfInputs == undefined || component.noOfOutputs == 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) + for(var i = 0 ; i < component.noOfInputs ; ++i) { + var terminal = component.inputTerminals.itemAt(i) //terminals[component.inputs[i]] + if(terminal.wires.length != 0) { + var wire = terminal.wires[0] + var otherAngle = wire.from.parent.initialAngle * Math.PI / 180 + //components[terminals[wire.from].componentIndex].initialAngle * Math.PI / 180 + var x = wire.from.xCenterFromComponent + var y = wire.from.yCenterFromComponent + var x1 = wire.from.xCenter - x + x * Math.cos(otherAngle) - y * Math.sin(otherAngle) + var y1 = 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.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]] + for(var i = 0 ; i < component.noOfOutputs ; ++i) { + var terminal = component.outputTerminals.itemAt(i) //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) { + for(var j = 0 ; j < terminal.wires.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 wire = terminal.wires[j] + var otherAngle = wire.to.parent.initialAngle * Math.PI / 180 + x = wire.to.xCenterFromComponent + y = wire.to.yCenterFromComponent + var x2 = wire.to.xCenter - x + x * Math.cos(otherAngle) - y * Math.sin(otherAngle) + var y2 = wire.to.yCenter - y + x * Math.sin(otherAngle) + y * Math.cos(otherAngle) 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 + if(x2 - x1 < 0) + angle = angle - 180 wire.x = x1 wire.y = y1 wire.width = width wire.rotation = angle - //wire.rotateAngle = angle } } } function deselect() { //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 selectedIndex = -1 selectedTerminal = -1 - for(var i = 0 ; i < terminals.length ; ++i) { - terminals[i].selected = false + for(var i = 0 ; i < components.length ; ++i) { + var component = components[i] + for(var j = 0 ; j < component.noOfInputs ; ++j) + component.inputTerminals.itemAt(j).selected = false + for(var j = 0 ; j < component.noOfOutputs ; ++j) + component.outputTerminals.itemAt(j).selected = false } } function removeComponent(index) { var component = components[index] - if(component.src == "sevenSegmentDisplay.svgz") - sevenSegmentDisplay[index].destroy() - 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.noOfInputs ; ++i) { + var terminal = component.inputTerminals.itemAt(i) //terminals[component.inputs[i]] + if(terminal.wires.length != 0) // Input Terminal can have only 1 wire + removeWire(terminal.wires[0]) } - for(var i = 0 ; i < component.outputs.length ; ++i) { - var terminal = terminals[component.outputs[i]] + for(var i = 0 ; i < component.noOfOutputs ; ++i) { + var terminal = component.outputTerminals.itemAt(i) //console.log("Remove terminal.wireIndex.length",terminal.wireIndex.length) - while (terminal.wireIndex.length != 0) { + while (terminal.wires.length != 0) { //console.log("terminal.wireIndex[j]",terminal.wireIndex[j]) - removeWire(terminal.wireIndex[0]) // Output Terminal can have more than 1 wire + removeWire(terminal.wires[0]) // Output Terminal can have more than 1 wire } } components[index].destroy() deletedIndex.push(index) deselect() } -function removeWire(index) { +function removeWire(wire) { - var wire = wires[index] - var inTerminal = terminals[wire.to] - var outTerminal = terminals[wire.from] + var inTerminal = wire.to + var outTerminal = wire.from - var removeIndex = inTerminal.wireIndex.indexOf(index) - inTerminal.wireIndex.splice(removeIndex,1) - removeIndex = outTerminal.wireIndex.indexOf(index) - outTerminal.wireIndex.splice(removeIndex,1) + var removeIndex = inTerminal.wires.indexOf(wire) + inTerminal.wires.splice(removeIndex,1) + removeIndex = outTerminal.wires.indexOf(wire) + outTerminal.wires.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) + inTerminal.value = 0 + wire.destroy() + //deletedWireIndex.push(index) + updateComponent(inTerminal.parent.index) + deselect() } 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].rotationAngle = -2 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].rotationAngle = 2 components[selectedIndex].rotateComponent.start() /*components[selectedIndex].initialAngle = components[selectedIndex].rotationAngle == 360 ? 0 : components[selectedIndex].rotationAngle*/ } function displayInfo() { - var src = components[selectedIndex].imgSrc - var component = componentsInfo[mapSrc[src]] + var component = components[selectedIndex] + var componentTruthTable = component.truthTable 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]}) - } - if(src == "sevenSegmentDisplay.svgz") { + items.infoTxt.text = component.information + + if(component.infoImageSrc != undefined) { items.infoImage.imgVisible = true - items.infoImage.source = url + "7SegmentDisplay.svg" + items.infoImage.source = url + component.infoImageSrc } else { items.infoImage.imgVisible = false items.infoImage.source = "" } + + if(componentTruthTable.length == 0) + items.displayTruthTable = false + else { + items.displayTruthTable = true + var truthTable = items.truthTablesModel + truthTable.clear() + truthTable.rows = componentTruthTable.length + truthTable.columns = componentTruthTable[0].length + truthTable.inputs = component.noOfInputs + truthTable.outputs = component.noOfOutputs + for(var i = 0 ; i < componentTruthTable.length ; ++i) + for(var j = 0 ; j < componentTruthTable[i].length ; ++j) + truthTable.append({'value': componentTruthTable[i][j]}) + } } 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/DigitalLightOff.svg b/src/activities/digital_electricity/resource/DigitalLightOff.svg new file mode 100644 index 000000000..9fae91cb6 --- /dev/null +++ b/src/activities/digital_electricity/resource/DigitalLightOff.svg @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + I + N + + + + + image/svg+xml + + + + + Openclipart + + + Voyant Blanc Eteint - White Light OFF + 2007-09-06T14:32:23 + + https://openclipart.org/detail/5294/voyant-blanc-eteint---white-light-off-by-fatboy178 + + + fatboy178 + + + + + automatisme + voyant + + + + + + + + + + + diff --git a/src/activities/digital_electricity/resource/DigitalLightOn.svg b/src/activities/digital_electricity/resource/DigitalLightOn.svg new file mode 100644 index 000000000..409167e8a --- /dev/null +++ b/src/activities/digital_electricity/resource/DigitalLightOn.svg @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + I + N + + + + + image/svg+xml + + + + + Openclipart + + + Voyant Rouge Allume - Red Light ON + 2007-09-06T13:40:36 + Voyant rouge de l'électricien et de l'automaticien insdustriel + https://openclipart.org/detail/5288/voyant-rouge-allume---red-light-on-by-fatboy178 + + + fatboy178 + + + + + automatisme + electrique + insdustrie + rouge + voyant + + + + + + + + + + + diff --git a/src/activities/digital_electricity/resource/ledOff.svg b/src/activities/digital_electricity/resource/ledOff.svg deleted file mode 100644 index 484737f4e..000000000 --- a/src/activities/digital_electricity/resource/ledOff.svg +++ /dev/null @@ -1,131 +0,0 @@ - - - -image/svg+xml \ No newline at end of file diff --git a/src/activities/digital_electricity/resource/ledOn.svg b/src/activities/digital_electricity/resource/ledOn.svg deleted file mode 100644 index 95c78ddb0..000000000 --- a/src/activities/digital_electricity/resource/ledOn.svg +++ /dev/null @@ -1,140 +0,0 @@ - - - -image/svg+xml \ No newline at end of file