diff --git a/b_asic/GUI/main_window.py b/b_asic/GUI/main_window.py index 16c807085329315a7ecaa98ff622419e535fae56..c3fc99f08b4f19e4b82f1e4ffecd1a3f7716a148 100644 --- a/b_asic/GUI/main_window.py +++ b/b_asic/GUI/main_window.py @@ -64,6 +64,8 @@ class MainWindow(QMainWindow): self.operationDragDict = {} self.operationItemSceneList = [] self.signalList = [] + self.mouse_pressed = False + self.mouse_draggin = False self.pressed_operations = [] self.portDict = {} self.signalPortDict = {} @@ -190,6 +192,7 @@ class MainWindow(QMainWindow): operation_positions[op_drag.operation.graph_id] = ( int(op_scene.x()), int(op_scene.y()), + op_drag.is_flipped(), ) try: @@ -250,10 +253,13 @@ class MainWindow(QMainWindow): if positions is None: positions = {} + #print(sfg) for op in sfg.split(): + #print(op) self.create_operation( op, - positions[op.graph_id] if op.graph_id in positions else None, + positions[op.graph_id][0:2] if op.graph_id in positions else None, + positions[op.graph_id][-1] if op.graph_id in positions else None, ) def connect_ports(ports): @@ -483,8 +489,15 @@ class MainWindow(QMainWindow): namespace, self.ui.custom_operations_list ) - def create_operation(self, op, position=None): + def create_operation(self, op, position=None, is_flipped=False): + try: + + if op in self.operationDragDict: + self.logger.warning("Multiple instances of operation with same name") + return + + attr_button = DragButton(op.graph_id, op, True, window=self) if position is None: attr_button.move(GRID * 3, GRID * 2) @@ -536,8 +549,14 @@ class MainWindow(QMainWindow): ) operation_label.moveBy(10, -20) attr_button.add_label(operation_label) + + if isinstance(is_flipped, bool): + if is_flipped: + attr_button._flip() + self.operationDragDict[op] = attr_button self.dragOperationSceneDict[attr_button] = attr_button_scene + except Exception as e: self.logger.error( "Unexpected error occurred while creating operation: " + str(e) @@ -577,6 +596,15 @@ class MainWindow(QMainWindow): self.pressed_operations.clear() super().keyPressEvent(event) + #TODO + def mouseMoveEvent(self, event): + print("ok") + if event.button() == Qt.MouseButton.LeftButton and self.mouse_pressed: + print("move") + self.mouse_draggin = True + + super().mouseMoveEvent(event) + def _connect_button(self, *event): if len(self.pressed_ports) < 2: self.logger.warning( diff --git a/b_asic/GUI/simulate_sfg_window.py b/b_asic/GUI/simulate_sfg_window.py index 8989d75d09fd4d9334f3e3209697ca6d5cae959d..c8eac5e913c9ae1f43507e099afdcde1b5fc3cd6 100644 --- a/b_asic/GUI/simulate_sfg_window.py +++ b/b_asic/GUI/simulate_sfg_window.py @@ -5,6 +5,14 @@ from matplotlib.backends.backend_qt5agg import ( FigureCanvasQTAgg as FigureCanvas, ) from matplotlib.figure import Figure +import numpy as np + +from b_asic.signal_generator import ( + Impulse, + Step, + ZeroPad, +) + from qtpy.QtCore import Qt, Signal from qtpy.QtGui import QKeySequence from qtpy.QtWidgets import ( @@ -22,6 +30,7 @@ from qtpy.QtWidgets import ( QSizePolicy, QSpinBox, QVBoxLayout, + QComboBox, ) @@ -42,6 +51,8 @@ class SimulateSFGWindow(QDialog): self.simulate_btn.clicked.connect(self.save_properties) self.dialog_layout.addWidget(self.simulate_btn) self.setLayout(self.dialog_layout) + self.input_grid = QGridLayout() + self.input_files = {} def add_sfg_to_dialog(self, sfg): sfg_layout = QVBoxLayout() @@ -66,36 +77,31 @@ class SimulateSFGWindow(QDialog): "iteration_count": spin_box, "show_plot": check_box_plot, "all_results": check_box_all, - "input_values": [], } if sfg.input_count > 0: input_label = QLabel("Input values:") options_layout.addRow(input_label) - input_grid = QGridLayout() x, y = 0, 0 for i in range(sfg.input_count): - input_layout = QHBoxLayout() - input_layout.addStretch() if i % 2 == 0 and i > 0: x += 1 y = 0 input_label = QLabel(f"in{i}") - input_layout.addWidget(input_label) - input_value = QLineEdit() - input_value.setPlaceholderText("e.g. 0, 0, 0") - input_value.setFixedWidth(100) - input_layout.addWidget(input_value) - input_layout.addStretch() - input_layout.setSpacing(10) - input_grid.addLayout(input_layout, x, y) - - self.input_fields[sfg]["input_values"].append(input_value) + self.input_grid.addWidget(input_label,i,0) + + input_dropdown = QComboBox() + input_dropdown.insertItems(0,["Impulse","Step","Input","File"]) + input_dropdown.currentTextChanged.connect(lambda text, i=i:self.change_input_format(i,text)) + self.input_grid.addWidget(input_dropdown,i,1,alignment=Qt.AlignLeft) + + self.change_input_format(i,"Impulse") + y += 1 - sfg_layout.addLayout(input_grid) + sfg_layout.addLayout(self.input_grid) frame = QFrame() frame.setFrameShape(QFrame.HLine) @@ -105,6 +111,58 @@ class SimulateSFGWindow(QDialog): self.sfg_to_layout[sfg] = sfg_layout self.dialog_layout.addLayout(sfg_layout) + def change_input_format(self, i, text): + + grid = self.input_grid.itemAtPosition(i,2) + if grid: + for j in reversed(range(grid.count())): + item = grid.itemAt(j) + widget = item.widget() + if widget: + widget.hide() + self.input_grid.removeItem(grid) + + param_grid = QGridLayout() + + if (text == "Impulse"): + delay_label = QLabel("Delay") + param_grid.addWidget(delay_label,0,0) + delay_spin_box = QSpinBox() + delay_spin_box.setRange(0,2147483647) + param_grid.addWidget(delay_spin_box,0,1) + elif(text == "Step"): + delay_label = QLabel("Delay") + param_grid.addWidget(delay_label,0,0) + delay_spin_box = QSpinBox() + delay_spin_box.setRange(0,2147483647) + param_grid.addWidget(delay_spin_box,0,1) + elif(text == "Input"): + input_label = QLabel("Input") + param_grid.addWidget(input_label,0,0) + input_sequence = QLineEdit() + param_grid.addWidget(input_sequence,0,1) + zpad_label = QLabel("Zpad") + param_grid.addWidget(zpad_label,1,0) + zpad_button = QCheckBox() + param_grid.addWidget(zpad_button,1,1) + elif(text == "File"): + file_label = QLabel("Browse") + param_grid.addWidget(file_label,0,0) + file_browser = QPushButton("No file selected") + file_browser.clicked.connect(lambda i=i:self.get_input_file(i,file_browser)) + param_grid.addWidget(file_browser,0,1) + else: + raise Exception("Input selection is not implemented") + + self.input_grid.addLayout(param_grid,i,2) + + return + + def get_input_file(self, i,file_browser): + module, accepted = QFileDialog().getOpenFileName() + file_browser.setText(module) + return + def parse_input_values(self, input_values): _input_values = [] for _list in input_values: @@ -128,15 +186,62 @@ class SimulateSFGWindow(QDialog): def save_properties(self): for sfg, _properties in self.input_fields.items(): - input_values = self.parse_input_values( - [ - widget.text().split(",") if widget.text() else [0] - for widget in self.input_fields[sfg]["input_values"] - ] - ) + + ic_value = self.input_fields[sfg]["iteration_count"].value() + if ic_value == 0: + self._window.logger.error( + "Iteration count is set to zero." + ) + + tmp = [] + + for i in range(self.input_grid.rowCount()): + + in_format = self.input_grid.itemAtPosition(i,1).widget().currentText() + in_param = self.input_grid.itemAtPosition(i,2) + + tmp2 = [] + + if (in_format == "Impulse"): + g = Impulse(in_param.itemAtPosition(0,1).widget().value()) + for j in range(ic_value): + tmp2.append(str(g(j))) + + elif(in_format == "Step"): + g = Step(in_param.itemAtPosition(0,1).widget().value()) + for j in range(ic_value): + tmp2.append(str(g(j))) + + elif(in_format == "Input"): + widget = in_param.itemAtPosition(0,1).widget() + tmp3 = widget.text().split(",") + if in_param.itemAtPosition(1,1).widget().isChecked(): + g = ZeroPad(tmp3) + for j in range(ic_value): + tmp2.append(str(g(j))) + else: + tmp2 = tmp3 + + elif(in_format == "File"): + widget = in_param.itemAtPosition(0,1).widget() + path = widget.text() + try: + tmp2 = np.loadtxt(path,dtype=str).tolist() + except FileNotFoundError: + self._window.logger.error( + f"Selected input file not found." + ) + continue + else: + raise Exception("Input selection is not implemented") + + tmp.append(tmp2) + + input_values = self.parse_input_values(tmp) + max_len = max(len(list_) for list_ in input_values) min_len = min(len(list_) for list_ in input_values) - ic_value = self.input_fields[sfg]["iteration_count"].value() + if max_len != min_len: self._window.logger.error( "Minimum length of input lists are not equal to maximum "