class ValveChipItem(WidgetChipItem): def __init__(self, valve: Valve): super().__init__() AppGlobals.Instance().onChipModified.connect(self.CheckForValve) self._valve = valve self.valveToggleButton = QToolButton() self.valveNumberLabel = QLabel("Number") self.valveNumberDial = QSpinBox() self.valveNumberDial.setMinimum(0) self.valveNumberDial.setValue(self._valve.solenoidNumber) self.valveNumberDial.setMaximum(9999) self.valveNumberDial.valueChanged.connect(self.UpdateValve) self.valveNameLabel = QLabel("Name") self.valveNameField = QLineEdit(self._valve.name) self.valveNameField.textChanged.connect(self.UpdateValve) mainLayout = QVBoxLayout() mainLayout.addWidget(self.valveToggleButton, alignment=Qt.AlignCenter) layout = QGridLayout() layout.addWidget(self.valveNameLabel, 0, 0) layout.addWidget(self.valveNameField, 0, 1) layout.addWidget(self.valveNumberLabel, 1, 0) layout.addWidget(self.valveNumberDial, 1, 1) mainLayout.addLayout(layout) self.containerWidget.setLayout(mainLayout) self.valveToggleButton.clicked.connect(self.Toggle) self.Update() self.Move(QPointF()) def CheckForValve(self): if self._valve not in AppGlobals.Chip().valves: self.RemoveItem() def Move(self, delta: QPointF): if delta != QPointF(): AppGlobals.Instance().onChipDataModified.emit() self._valve.position += delta self.GraphicsObject().setPos(self._valve.position) def SetEditDisplay(self, editing: bool): self.valveNameField.setVisible(editing) self.valveNameLabel.setVisible(editing) self.valveNumberLabel.setVisible(editing) self.valveNumberDial.setVisible(editing) super().SetEditDisplay(editing) def UpdateValve(self): self._valve.solenoidNumber = self.valveNumberDial.value() self._valve.name = self.valveNameField.text() AppGlobals.Instance().onChipDataModified.emit() def Toggle(self): AppGlobals.Rig().SetSolenoidState( self._valve.solenoidNumber, not AppGlobals.Rig().GetSolenoidState(self._valve.solenoidNumber), True) def RequestDelete(self): AppGlobals.Chip().valves.remove(self._valve) AppGlobals.Instance().onChipModified.emit() def Duplicate(self) -> 'ChipItem': newValve = Valve() newValve.position = QPointF(self._valve.position) newValve.name = self._valve.name newValve.solenoidNumber = AppGlobals.Chip().NextSolenoidNumber() AppGlobals.Chip().valves.append(newValve) AppGlobals.Instance().onChipModified.emit() return ValveChipItem(newValve) def Update(self): text = self._valve.name + "\n(" + str(self._valve.solenoidNumber) + ")" if text != self.valveToggleButton.text(): self.valveToggleButton.setText(text) lastState = self.valveToggleButton.property("valveState") newState = { True: "OPEN", False: "CLOSED" }[AppGlobals.Rig().GetSolenoidState(self._valve.solenoidNumber)] if lastState != newState: self.valveToggleButton.setProperty("valveState", newState) self.valveToggleButton.setStyle(self.valveToggleButton.style())
class ParameterEditorItem(QWidget): onRemoveParameter = Signal(Parameter) onMoveParameterUp = Signal(Parameter) onMoveParameterDown = Signal(Parameter) onChanged = Signal() def __init__(self, parameter: Parameter): super().__init__() self.parameter = parameter deleteButton = QToolButton() deleteButton.setText("X") deleteButton.clicked.connect( lambda: self.onRemoveParameter.emit(self.parameter)) upButton = QToolButton() upButton.setText("\u2191") upButton.clicked.connect( lambda: self.onMoveParameterUp.emit(self.parameter)) downButton = QToolButton() downButton.setText("\u2193") downButton.clicked.connect( lambda: self.onMoveParameterDown.emit(self.parameter)) buttonsLayout = QVBoxLayout() buttonsLayout.setAlignment(Qt.AlignTop) buttonsLayout.addWidget(deleteButton) buttonsLayout.addWidget(upButton) buttonsLayout.addWidget(downButton) self._nameLabel = QLabel("Name") self._nameField = QLineEdit() self._nameField.textChanged.connect(self.OnChanged) self._dataTypeLabel = QLabel("Data Type") self._dataTypeField = QComboBox() for dataType in DataType: self._dataTypeField.addItem(dataType.ToString(), userData=dataType) self._dataTypeField.currentIndexChanged.connect(self.OnChanged) self._defaultValueLabel = QLabel("Default Value") self._defaultInteger = QSpinBox() self._defaultInteger.valueChanged.connect(self.OnChanged) self._defaultFloat = QDoubleSpinBox() self._defaultFloat.valueChanged.connect(self.OnChanged) self._defaultBoolean = QComboBox() self._defaultBoolean.addItem("True", True) self._defaultBoolean.addItem("False", False) self._defaultBoolean.currentIndexChanged.connect(self.OnChanged) self._defaultString = QLineEdit() self._defaultString.textChanged.connect(self.OnChanged) self._minimumLabel = QLabel("Minimum") self._minimumFloat = QDoubleSpinBox() self._minimumFloat.valueChanged.connect(self.OnChanged) self._minimumInteger = QSpinBox() self._minimumInteger.valueChanged.connect(self.OnChanged) self._maximumLabel = QLabel("Maximum") self._maximumFloat = QDoubleSpinBox() self._maximumFloat.valueChanged.connect(self.OnChanged) self._maximumInteger = QSpinBox() self._maximumInteger.valueChanged.connect(self.OnChanged) gridLayout = QGridLayout() gridLayout.setAlignment(Qt.AlignTop) gridLayout.addWidget(self._nameLabel, 0, 0) gridLayout.addWidget(self._nameField, 0, 1) gridLayout.addWidget(self._dataTypeLabel, 1, 0) gridLayout.addWidget(self._dataTypeField, 1, 1) gridLayout.addWidget(self._defaultValueLabel, 2, 0) for defaultField in [ self._defaultInteger, self._defaultFloat, self._defaultBoolean, self._defaultString ]: gridLayout.addWidget(defaultField, 2, 1) gridLayout.addWidget(self._minimumLabel, 3, 0) gridLayout.addWidget(self._minimumInteger, 3, 1) gridLayout.addWidget(self._minimumFloat, 3, 1) gridLayout.addWidget(self._maximumLabel, 4, 0) gridLayout.addWidget(self._maximumInteger, 4, 1) gridLayout.addWidget(self._maximumFloat, 4, 1) layout = QHBoxLayout() layout.addLayout(buttonsLayout) layout.addLayout(gridLayout) self.setLayout(layout) self.SetFieldsFromParameter() def SetFieldsFromParameter(self): self._nameField.setText(self.parameter.name) self._dataTypeField.setCurrentText(self.parameter.dataType.ToString()) minFloat, maxFloat = self.parameter.minimumFloat, self.parameter.maximumFloat minInt, maxInt = self.parameter.minimumInteger, self.parameter.maximumInteger self._minimumFloat.setRange(-2**30, maxFloat) self._maximumFloat.setRange(minFloat, 2**30) self._minimumInteger.setRange(-2**30, maxInt) self._maximumInteger.setRange(minInt, 2**30) if self._minimumFloat.value() != minFloat: self._minimumFloat.setValue(minFloat) if self._maximumFloat.value() != maxFloat: self._maximumFloat.setValue(maxFloat) if self._minimumInteger.value() != minInt: self._minimumInteger.setValue(minInt) if self._maximumInteger.value() != maxInt: self._maximumInteger.setValue(maxInt) self._defaultInteger.setRange(minInt, maxInt) self._defaultFloat.setRange(minFloat, maxFloat) if self._defaultInteger.value() != self.parameter.defaultValueDict[ DataType.INTEGER]: self._defaultInteger.setValue( self.parameter.defaultValueDict[DataType.INTEGER]) if self._defaultFloat.value() != self.parameter.defaultValueDict[ DataType.FLOAT]: self._defaultFloat.setValue( self.parameter.defaultValueDict[DataType.FLOAT]) if self._defaultBoolean.currentData( ) != self.parameter.defaultValueDict[DataType.BOOLEAN]: self._defaultBoolean.setCurrentText( str(self.parameter.defaultValueDict[DataType.BOOLEAN])) if self._defaultString.text() != self.parameter.defaultValueDict[ DataType.STRING]: self._defaultString.setText( self.parameter.defaultValueDict[DataType.STRING]) self.UpdateVisibility() def UpdateVisibility(self): self._defaultInteger.setVisible( self._dataTypeField.currentData() is DataType.INTEGER) self._defaultFloat.setVisible( self._dataTypeField.currentData() is DataType.FLOAT) self._defaultBoolean.setVisible( self._dataTypeField.currentData() is DataType.BOOLEAN) self._defaultString.setVisible( self._dataTypeField.currentData() is DataType.STRING) self._minimumLabel.setVisible(self._dataTypeField.currentData() in [DataType.INTEGER, DataType.FLOAT]) self._maximumLabel.setVisible(self._dataTypeField.currentData() in [DataType.INTEGER, DataType.FLOAT]) self._minimumInteger.setVisible( self._dataTypeField.currentData() is DataType.INTEGER) self._maximumInteger.setVisible( self._dataTypeField.currentData() is DataType.INTEGER) self._minimumFloat.setVisible( self._dataTypeField.currentData() is DataType.FLOAT) self._maximumFloat.setVisible( self._dataTypeField.currentData() is DataType.FLOAT) self._minimumLabel.setVisible(self._dataTypeField.currentData() in [DataType.INTEGER, DataType.FLOAT]) self._maximumLabel.setVisible(self._dataTypeField.currentData() in [DataType.INTEGER, DataType.FLOAT]) self._defaultValueLabel.setVisible(self._dataTypeField.currentData( ) not in [DataType.VALVE, DataType.PROGRAM, DataType.PROGRAM_PRESET]) def OnChanged(self): self.UpdateVisibility() self._minimumFloat.setMaximum(self._maximumFloat.value()) self._maximumFloat.setMinimum(self._minimumFloat.value()) self._minimumInteger.setMaximum(self._maximumInteger.value()) self._maximumInteger.setMinimum(self._minimumInteger.value()) self._defaultInteger.setRange(self._minimumInteger.value(), self._maximumInteger.value()) self._defaultFloat.setRange(self._minimumFloat.value(), self._maximumFloat.value()) self.onChanged.emit() def UpdateParameter(self): self.parameter.name = self._nameField.text() self.parameter.dataType = self._dataTypeField.currentData() self.parameter.defaultValueDict[ DataType.INTEGER] = self._defaultInteger.value() self.parameter.defaultValueDict[ DataType.FLOAT] = self._defaultFloat.value() self.parameter.defaultValueDict[ DataType.BOOLEAN] = self._defaultBoolean.currentData() self.parameter.defaultValueDict[ DataType.STRING] = self._defaultString.text() self.parameter.minimumInteger = self._minimumInteger.value() self.parameter.maximumInteger = self._maximumInteger.value() self.parameter.minimumFloat = self._minimumFloat.value() self.parameter.maximumFloat = self._maximumFloat.value() self.parameter.ValidateDefaultValues() self.SetFieldsFromParameter()