diff --git a/src/activities/digital_electricity/ListWidget.qml b/src/activities/digital_electricity/ListWidget.qml index 5ec8bb25f..3755505d3 100644 --- a/src/activities/digital_electricity/ListWidget.qml +++ b/src/activities/digital_electricity/ListWidget.qml @@ -1,323 +1,329 @@ /* 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.3 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 = toolDelete.state == "selected" ? "notSelected" : "selected" - Activity.toolDelete = !Activity.toolDelete //true + Activity.toolDelete = !Activity.toolDelete + Activity.toolDeleteSticky = false //console.log("state",toolDelete.state) } + onDoubleClicked: { + Activity.toolDeleteSticky = true + Activity.toolDelete = true + toolDelete.state = "selected" + } } states: [ State { name: "selected" PropertyChanges{ target: toolDelete source: Activity.url + "deleteOn.svg" } }, State { name: "notSelected" PropertyChanges { target: toolDelete 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/components/ElectricalComponent.qml b/src/activities/digital_electricity/components/ElectricalComponent.qml index 6a7047acc..ad9cee3b9 100644 --- a/src/activities/digital_electricity/components/ElectricalComponent.qml +++ b/src/activities/digital_electricity/components/ElectricalComponent.qml @@ -1,146 +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 GCompris 1.0 Image { id: electricalComponent property double posX property double posY property double imgWidth property double imgHeight 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 double terminalSize property alias rotateComponent: rotateComponent x: posX * parent.width y: posY * parent.height width: imgWidth * parent.width height: imgHeight * parent.height fillMode: Image.PreserveAspectFit 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,electricalComponent) - if(Activity.toolDelete) { + if(Activity.toolDelete || Activity.toolDeleteSticky) { 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) } } } 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/SignalGenerator.qml b/src/activities/digital_electricity/components/SignalGenerator.qml new file mode 100644 index 000000000..85b4ce4f6 --- /dev/null +++ b/src/activities/digital_electricity/components/SignalGenerator.qml @@ -0,0 +1,166 @@ +/* GCompris - SignalGenerator.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 +import "../../../core" + +ElectricalComponent { + id: signalGenerator + imgWidth: 0.25 + imgHeight: 0.18 + imgSrc: "signalGenerator.svg" + toolTipTxt: qsTr("Signal Generator") + terminalSize: 0.451 + noOfInputs: 0 + noOfOutputs: 1 + + information: qsTr("Signal Generator is used to generate alternating signals of 0 and 1. " + + "It takes frequency as input, and generate outputs accordingly. Frequency " + + "refers to the number of times the output will change in 1 second. So 1 Hz " + + "means that the output will change after every 1 second, 0.5 Hz means that " + + "the output will change after every 2 seconds, and so on. For the demonstration " + + "purpose, the minimum frequency of signal generator in this activity is " + + "0.25 Hz, and maximum frequency is 2 Hz. The frequency can be changed by clicking " + + "on the arrows on the signal generator") + + property alias outputTerminals: outputTerminals + property double frequency: 0.25 + + Repeater { + id: outputTerminals + model: 1 + delegate: outputTerminal + Component { + id: outputTerminal + TerminalPoint { + posX: 0.914 + posY: 0.512 + value: 0 + type: "Out" + } + } + } + + function updateOutput(wireVisited) { + var terminal = outputTerminals.itemAt(0) + terminal.value = terminal.value == 1 ? 0 : 1 + 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) + } + } + } + + Timer { + id: timer + interval: 1000 / signalGenerator.frequency + running: true + repeat: true + onTriggered: Activity.updateComponent(signalGenerator.index) + } + + Image { + source: Activity.url + "arrowUp.svg" + height: 0.339 * parent.height + width: 0.123 * parent.width + property double posX: 0.632 + property double posY: 0.284 + x: (parent.width - parent.paintedWidth) / 2 + posX * parent.paintedWidth - width / 2 + y: (parent.height - parent.paintedHeight) / 2 + posY * parent.paintedHeight - height / 2 + fillMode: Image.PreserveAspectFit + mipmap: true + antialiasing: true + MouseArea { + anchors.fill: parent + anchors.centerIn: parent + enabled: signalGenerator.frequency != 2 + onPressed: { + //console.log("Up pressed") + signalGenerator.frequency += 0.25 + timer.restart() + outputTerminals.itemAt(0).value = 1 + Activity.updateComponent(signalGenerator.index) + } + } + } + + Image { + source: Activity.url + "arrowDown.svg" + height: 0.339 * parent.height + width: 0.123 * parent.width + property double posX: 0.632 + property double posY: 0.713 + x: (parent.width - parent.paintedWidth) / 2 + posX * parent.paintedWidth - width / 2 + y: (parent.height - parent.paintedHeight) / 2 + posY * parent.paintedHeight - height / 2 + fillMode: Image.PreserveAspectFit + mipmap: true + antialiasing: true + MouseArea { + anchors.fill: parent + anchors.centerIn: parent + enabled: signalGenerator.frequency != 0.25 + onPressed: { + //console.log("Down pressed") + signalGenerator.frequency -= 0.25 + timer.restart() + outputTerminals.itemAt(0).value = 1 + Activity.updateComponent(signalGenerator.index) + } + } + } + + Image { + //id: valueContainer + source: Activity.url + "valueContainer.svg" + sourceSize.height: 0.818 * parent.height + sourceSize.width: 0.512 * parent.width + property double posX: 0.306 + property double posY: 0.503 + x: (parent.width - parent.paintedWidth) / 2 + posX * parent.paintedWidth - width / 2 + y: (parent.height - parent.paintedHeight) / 2 + posY * parent.paintedHeight - height / 2 + GCText { + id: value + anchors.centerIn: parent + fontSizeMode: Text.Fit + minimumPointSize: 6 + font.pointSize: 40 + //font.pixelSize: 40 + color: "white" + style: Text.Outline + styleColor: "black" + horizontalAlignment: Text.AlignRight + verticalAlignment: Text.AlignVCenter + height: parent.height - 10 + width: parent.width - 10 + text: qsTr("%1 Hz").arg(signalGenerator.frequency.toFixed(2)) + } + } +} diff --git a/src/activities/digital_electricity/digital_electricity.js b/src/activities/digital_electricity/digital_electricity.js index 82230d718..47403dc2a 100644 --- a/src/activities/digital_electricity/digital_electricity.js +++ b/src/activities/digital_electricity/digital_electricity.js @@ -1,396 +1,409 @@ /* 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 toolDelete +var toolDeleteSticky var selectedIndex var animationInProgress var selectedTerminal var deletedIndex = [] var components = [] var connected = [] var colors = ["red","green","blue","blueviolet","silver"] function start(items_) { items = items_ currentLevel = 0 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") }) + items.availablePieces.model.append( { + "imgName": "signalGenerator.svg", + "imgWidth": 0.25, + "imgHeight": 0.18, + "toolTipText": qsTr("Signal Generator") + }) 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) removeComponent(i) } } function initLevel() { items.availablePieces.view.currentDisplayedGroup = 0 items.availablePieces.view.previousNavigation = 1 items.availablePieces.view.nextNavigation = 1 deletedIndex = [] components = [] connected = [] animationInProgress = false - deselect() toolDelete = false + toolDeleteSticky = false + deselect() updateToolTip("") } function reset() { deselect() stop() initLevel() } function createComponent(x, y, src) { 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 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") + else if(src == "signalGenerator.svg") + electricComponent = Qt.createComponent(componentLocation + "SignalGenerator.qml") //console.log("Error loading component:", electricComponent.errorString()) components[index] = electricComponent.createObject( items.backgroundContainer, { "index": index, "posX": x, "posY": y }); - + toolDeleteSticky = false + deselect() componentSelected(index) updateComponent(index) } function terminalPointSelected(terminal) { 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[inTerminal] == undefined || connected[inTerminal] == -1) { //console.log("in2") var wireComponent = Qt.createComponent("qrc:/gcompris/src/activities/digital_electricity/Wire.qml") var colorIndex = Math.floor(Math.random() * colors.length) 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 = terminal terminal.selected = true } } function updateComponent(index) { - + //console.log("updateComponent",index) var wireVisited = [] components[index].updateOutput(wireVisited) } function updateWires(index) { var component = components[index] if(component == undefined || component.noOfInputs == undefined || component.noOfOutputs == undefined) return var rotatedAngle = component.initialAngle * Math.PI / 180 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) 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.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.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 = 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.x = x1 wire.y = y1 wire.width = width wire.rotation = angle } } } function deselect() { - //items.availablePieces.toolDelete.state = "notSelected" + if(toolDeleteSticky == false) { + toolDelete = false + 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 < 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] 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.noOfOutputs ; ++i) { var terminal = component.outputTerminals.itemAt(i) //console.log("Remove terminal.wireIndex.length",terminal.wireIndex.length) while (terminal.wires.length != 0) { //console.log("terminal.wireIndex[j]",terminal.wireIndex[j]) removeWire(terminal.wires[0]) // Output Terminal can have more than 1 wire } } components[index].destroy() deletedIndex.push(index) deselect() } function removeWire(wire) { var inTerminal = wire.to var outTerminal = wire.from 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 = 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].rotateComponent.start() /*components[selectedIndex].initialAngle = components[selectedIndex].rotationAngle == -360 ? 0 : components[selectedIndex].rotationAngle*/ } function rotateRight() { components[selectedIndex].rotationAngle = 2 components[selectedIndex].rotateComponent.start() /*components[selectedIndex].initialAngle = components[selectedIndex].rotationAngle == 360 ? 0 : components[selectedIndex].rotationAngle*/ } function displayInfo() { var component = components[selectedIndex] var componentTruthTable = component.truthTable deselect() items.infoTxt.visible = true items.infoTxt.text = component.information if(component.infoImageSrc != undefined) { items.infoImage.imgVisible = true 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/arrowDown.svg b/src/activities/digital_electricity/resource/arrowDown.svg new file mode 100644 index 000000000..c6be6c80e --- /dev/null +++ b/src/activities/digital_electricity/resource/arrowDown.svg @@ -0,0 +1,273 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + arrow_orange_down + 2008-05-26T11:33:54 + + https://openclipart.org/detail/16966/arrow_orange_down-by-jean_victor_balin + + + jean_victor_balin + + + + + arrow + icon + + + + + + + + + + + diff --git a/src/activities/digital_electricity/resource/arrowUp.svg b/src/activities/digital_electricity/resource/arrowUp.svg new file mode 100644 index 000000000..6fce2b905 --- /dev/null +++ b/src/activities/digital_electricity/resource/arrowUp.svg @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + arrow_orange_up + 2008-05-26T11:35:32 + + https://openclipart.org/detail/16969/arrow_orange_up-by-jean_victor_balin + + + jean_victor_balin + + + + + arrow + icon + + + + + + + + + + + diff --git a/src/activities/digital_electricity/resource/signalGenerator.svg b/src/activities/digital_electricity/resource/signalGenerator.svg new file mode 100644 index 000000000..ec6081b6d --- /dev/null +++ b/src/activities/digital_electricity/resource/signalGenerator.svg @@ -0,0 +1,552 @@ + + + + + Function Generator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + Function Generator + 2009-11-02T21:36:40 + A stylized depiction of a function generator. + https://openclipart.org/detail/28031/function-generator-by-mothinator + + + mothinator + + + + + cartoon + electronic equipment + equipment + function generator + remix + science + scientific equipment + + + + + + + + + + + diff --git a/src/activities/digital_electricity/resource/valueContainer.svg b/src/activities/digital_electricity/resource/valueContainer.svg new file mode 100644 index 000000000..b982ddca3 --- /dev/null +++ b/src/activities/digital_electricity/resource/valueContainer.svg @@ -0,0 +1,336 @@ + + + + + Function Generator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + Function Generator + 2009-11-02T21:36:40 + A stylized depiction of a function generator. + https://openclipart.org/detail/28031/function-generator-by-mothinator + + + mothinator + + + + + cartoon + electronic equipment + equipment + function generator + remix + science + scientific equipment + + + + + + + + + + +