wire4 = Wire() wire4.position = (0, 1) model.addComponent(wire4) wire5 = Wire() wire5.position = (0, 2) model.addComponent(wire5) resistor = Resistor() resistor.position = (1, 2) model.addComponent(resistor) wire6 = Wire() wire6.position = (2, 2) model.addComponent(wire6) model.addConnection(wire, battery) model.addConnection(battery, wire2) model.addConnection(wire2, wire3) model.addConnection(wire3, bulb) model.addConnection(bulb, wire4) model.addConnection(wire4, wire5) model.addConnection(wire5, resistor) model.addConnection(resistor, wire6) model.addConnection(wire6, wire3) circuitLogic = CircuitLogicController(model) # circuitLogic.printBreadboard() circuitLogic.runBreadboard()
class MainController(): def __init__(self, model=None, view=None): self._view = None self._model = None # instantiate sub controllers self.circuitLogic = CircuitLogicController(model) # default states self.previousTool = None self._mode = Mode.Run self._tool = Tool.Select self._mouseState = MouseState.Normal # circuit diagram variables # wire tool self.wirePath = [] self.currentBlock = (None, None) # drag and drop new component self.newComponentType = None # drag and drop existing component self._selection = None # run mode variable self.buttonHeld = (None, None) self.view = view self.model = model @property def view(self): return self._view @view.setter def view(self, value): if self.view is None and value is not self.view: self._view = value self.updateProperties() @property def mode(self): return self._mode @mode.setter def mode(self, value): if value is not self.mode: self._mode = value if self.mode is Mode.Run: self.circuitLogic.runBreadboard() else: self.circuitLogic.stopBreadboard() self.view.updateCursorAndToolButtons(self.mode, self.tool, self.mouseState) @property def tool(self): return self._tool @tool.setter def tool(self, value): if value is not self._tool: self.previousTool = self._tool self._tool = value self.view.ui.circuitDiagram.shouldShowSelection = self.tool is Tool.Select self.updateProperties() if self.mode is Mode.Run: self.mode = Mode.Build else: self.view.updateCursorAndToolButtons(self.mode, self.tool, self.mouseState) @property def mouseState(self): return self._mouseState @mouseState.setter def mouseState(self, value): if value is not self._mouseState: self._mouseState = value if self.tool is Tool.Select: self.view.ui.circuitDiagram.dragging = value is MouseState.Dragging self.view.updateCursorAndToolButtons(self.mode, self.tool, self.mouseState) @property def selection(self): return self._selection @selection.setter def selection(self, value): if self.selection is not value: self._selection = value self.updateProperties() self.view.ui.circuitDiagram.selection = self.selection def updateProperties(self): if self.view is not None and self.tool is Tool.Select: self.view.ui.componentTypeLabel.hide() self.view.ui.componentType.hide() self.view.ui.componentType.clear() self.view.ui.voltageLabel.hide() self.view.ui.voltage.hide() self.view.ui.resistanceLabel.hide() self.view.ui.resistance.hide() self.view.ui.closedLabel.hide() self.view.ui.closed.hide() self.view.ui.currentLabel.hide() self.view.ui.current.hide() if self.selection is not None: self.view.ui.componentTypeLabel.show() self.view.ui.componentType.show() self.view.ui.componentType.addItem("%s" % self.selection.type) if self.selection.type is ComponentType.Battery: self.view.ui.voltageLabel.show() self.view.ui.voltage.show() self.view.ui.voltage.setRange(0.0, 24.0) self.view.ui.voltage.setSingleStep(1.0) self.view.ui.voltage.setEnabled(True) self.view.ui.voltage.setValue(self.selection.voltage) self.view.ui.voltage.valueChanged.connect(self.updateVoltage) elif self.selection.type is ComponentType.Bulb or self.selection.type is ComponentType.Resistor: self.view.ui.resistanceLabel.show() self.view.ui.resistance.show() self.view.ui.resistance.setRange(0.0, 24.0) self.view.ui.resistance.setSingleStep(1.0) self.view.ui.resistance.setEnabled(True) self.view.ui.resistance.setValue(self.selection.resistance) self.view.ui.resistance.valueChanged.connect(self.updateResistance) elif self.selection.type is ComponentType.Switch: self.view.ui.closedLabel.show() self.view.ui.closed.show() self.view.ui.closed.setChecked(self.selection.closed) self.view.ui.closed.setEnabled(True) self.view.ui.closed.stateChanged.connect(self.updateSwitch) def updateVoltage(self): updatedVoltage = self.view.ui.voltage.value() self.selection.voltage = updatedVoltage def updateResistance(self): updatedResistance = self.view.ui.resistance.value() self.selection.resistance = updatedResistance def updateSwitch(self): if self.view.ui.closed.isChecked(): self.selection.closed = True else: self.selection.closed = False def circuitDiagramMousePress(self, index, coordinate): if self.mode is Mode.Build: if self.tool is Tool.Select: if self.model.componentAtIndex(index) is not None: self.view.ui.circuitDiagram.draggingStart = coordinate print("about to start dragging: ", self.view.ui.circuitDiagram.draggingStart) self.selection = self.model.componentAtIndex(index) self.mouseState = MouseState.Dragging elif self.tool is Tool.Wire: if self.model.componentAtIndex(index) is not None: # print("starting wire at ", index) self.mouseState = MouseState.Dragging self.currentBlock = index self.wirePath = [index] else: pass # print("invalid wire start") elif self.tool is Tool.Delete: if self.model.componentAtIndex(index) is not None: self.model.removeComponentAtIndex(index) elif self.mode is Mode.Run: if self.model.componentAtIndex(index) is not None: if self.model.componentAtIndex(index).type is ComponentType.Switch: self.model.componentAtIndex(index).flip() self.model.modelChanged.emit() self.circuitLogic.runBreadboard() elif self.model.componentAtIndex(index).type is ComponentType.Button: self.model.componentAtIndex(index).flip() self.buttonHeld = index self.model.modelChanged.emit() self.circuitLogic.runBreadboard() def circuitDiagramMouseMove(self, index, coordinate): if self.tool is Tool.Select and self.mouseState is MouseState.Dragging: if self.model.validIndex(index): pass # print("moving %s to %s" % (self.selectedComponent, index)) else: self.mouseState = MouseState.Normal elif self.tool is Tool.NewComponent and self.mouseState is MouseState.Dragging: pass elif self.tool is Tool.Wire and self.mouseState is MouseState.Dragging: if not self.model.validIndex(index): #print("invalid wire") self.mouseState = MouseState.Normal else: if index != self.currentBlock: #print("move wire to ", index) self.wirePath.append(index) print(self.wirePath) self.currentBlock = index if self.model.componentAtIndex(self.currentBlock) is not None: if self.model.componentAtIndex(self.currentBlock).numberOfConnections() < 2 or (self.model.componentAtIndex(self.currentBlock).numberOfConnections() == 2 and self.model.componentAtIndex(self.currentBlock).type == ComponentType.Wire): # wire has formed a connection to existing component, or making a "junction" self.model.addConnection(self.model.componentAtIndex(self.wirePath[-2]), self.model.componentAtIndex(self.wirePath[-1])) if self.model.componentAtIndex(self.currentBlock).type in [ComponentType.Battery, ComponentType.Switch, ComponentType.Button, ComponentType.Resistor] and (self.currentBlock[0] == self.wirePath[-2][0]): self.wirePath.pop() self.wirePath.pop(0) for block in self.wirePath: if self.model.componentAtIndex(block).type is ComponentType.Wire: self.model.removeComponentAtIndex(block) self.mouseState = MouseState.Normal else: # wire has formed a bad number of connections to existing component -> end and destroy wires in invalid path here self.wirePath.pop() self.wirePath.pop(0) for block in self.wirePath: if self.model.componentAtIndex(block).type is ComponentType.Wire: self.model.removeComponentAtIndex(block) self.mouseState = MouseState.Normal else: # restrict wires coming in and out of horizontal components to horizontal if (len(self.wirePath) == 2) and (self.model.componentAtIndex(self.wirePath[0]).type in [ComponentType.Battery, ComponentType.Switch, ComponentType.Button, ComponentType.Resistor]) and (self.wirePath[0][0] == self.wirePath[1][0]): # invalid wire direction coming out of horizontal component -> end and destroy wires in invalid path here self.wirePath.pop() self.wirePath.pop(0) for block in self.wirePath: if self.model.componentAtIndex(block).type is ComponentType.Wire: self.model.removeComponentAtIndex(block) self.mouseState = MouseState.Normal else: if (self.model.componentAtIndex(self.wirePath[-2]).numberOfConnections() > 1 and self.model.componentAtIndex(self.wirePath[-2]).type is not ComponentType.Wire) or (self.model.componentAtIndex(self.wirePath[-2]).numberOfConnections() > 2 and self.model.componentAtIndex(self.wirePath[-2]).type is ComponentType.Wire): # trying to add a wire which would create a 3rd connection on a non-wire component -> end invalid wire keep valid portion of wire up to invalid component ########## OR # trying to add a wire which would create a 4th connection on junction wire -> end invalid wire keep valid portion of wire up to invalid component self.mouseState = MouseState.Normal else: wireComponent = Wire() wireComponent.position = self.wirePath[-1] if self.model.addComponent(wireComponent): print("added wire") else: print("could not add wire") #print(self.wirePath) self.model.addConnection(self.model.componentAtIndex(self.wirePath[-2]), self.model.componentAtIndex(self.wirePath[-1])) def circuitDiagramMouseRelease(self, index, coordinate): if self.mode is Mode.Build: if self.tool is Tool.Select: if self.mouseState is MouseState.Normal: self.selection = self.model.componentAtIndex(index) elif self.mouseState is MouseState.Dragging: if self.model.validIndex(index) and self.model.componentAtIndex(index) is None: self.model.moveComponent(self.selection, index) print("moved %s to %s" % (self.selection, index)) else: print("invalid move") elif self.tool is Tool.Wire: if self.model.validIndex(index): print("valid end wire at ", index) else: print("invalid wire") elif self.tool is Tool.NewComponent: newComponent = None if self.model.validIndex(index) and self.model.componentAtIndex(index) is None: if self.newComponentType is ComponentType.Battery: newComponent = Battery() elif self.newComponentType is ComponentType.Bulb: newComponent = Bulb() elif self.newComponentType is ComponentType.Resistor: newComponent = Resistor() elif self.newComponentType is ComponentType.Switch: newComponent = Switch() elif self.newComponentType is ComponentType.Button: newComponent = Button() elif self.newComponentType is ComponentType.Ammeter: newComponent = Ammeter() elif self.newComponentType is ComponentType.Voltmeter: newComponent = Voltmeter() if newComponent is not None: newComponent.position = index self.model.addComponent(newComponent) self.tool = self.previousTool self.mouseState = MouseState.Normal self.selection = newComponent elif self.mode is Mode.Run: if self.buttonHeld != (None, None): self.model.componentAtIndex(self.buttonHeld).flip() self.model.modelChanged.emit() self.buttonHeld = (None, None) self.circuitLogic.runBreadboard() self.mouseState = MouseState.Normal def newComponentButtonMousePress(self, componentType, event): self.tool = Tool.NewComponent self.mouseState = MouseState.Dragging self.newComponentType = componentType newComponentDrag = QDrag(self.view) newComponentDrag.setHotSpot(QPoint(self.view.ui.circuitDiagram.blockSideLength / 2, self.view.ui.circuitDiagram.blockSideLength / 2)) newComponentDrag.setMimeData(QMimeData()) newComponentDrag.setPixmap(QPixmap(self.view.ui.circuitDiagram.componentTypeToImageName(componentType)).scaled(self.view.ui.circuitDiagram.blockSideLength, self.view.ui.circuitDiagram.blockSideLength)) newComponentDrag.exec_(Qt.MoveAction)