diff --git a/b_asic/GUI/drag_button.py b/b_asic/GUI/drag_button.py index 241e00e3aa8e65f381b9baeeb0c4e2e1c547e7c4..495291a3a859b6dfc71a9a3b24edd4e25cc0c39d 100644 --- a/b_asic/GUI/drag_button.py +++ b/b_asic/GUI/drag_button.py @@ -38,7 +38,6 @@ class DragButton(QPushButton): self, name, operation, - operation_path_name, is_show_name, window, parent=None, @@ -48,7 +47,6 @@ class DragButton(QPushButton): self.is_show_name = is_show_name self._window = window self.operation = operation - self.operation_path_name = operation_path_name self.clicked = 0 self.pressed = False self._m_press = False @@ -75,7 +73,7 @@ class DragButton(QPushButton): flip.triggered.connect(self._flip) menu.exec_(self.cursor().pos()) - def show_properties_window(self, event): + def show_properties_window(self, event=None): self._properties_window = PropertiesWindow(self, self._window) self._properties_window.show() @@ -155,7 +153,9 @@ class DragButton(QPushButton): path_to_image = os.path.join( os.path.dirname(__file__), "operation_icons", - f"{self.operation_path_name}{'_grey.png' if self.pressed else '.png'}", + ( + f"{self.operation.type_name().lower()}{'_grey.png' if self.pressed else '.png'}" + ), ) self.setIcon(QIcon(path_to_image)) self.setIconSize(QSize(MINBUTTONSIZE, MINBUTTONSIZE)) diff --git a/b_asic/GUI/main_window.py b/b_asic/GUI/main_window.py index 5ea25e56070a2ae91c8ec9244c62c95f273967c6..c0e1adad97ae411c6411e7934498b92a255df006 100644 --- a/b_asic/GUI/main_window.py +++ b/b_asic/GUI/main_window.py @@ -489,9 +489,7 @@ class MainWindow(QMainWindow): def create_operation(self, op, position=None): try: - attr_button = DragButton( - op.graph_id, op, op.type_name().lower(), True, window=self - ) + attr_button = DragButton(op.graph_id, op, True, window=self) if position is None: attr_button.move(GRID * 3, GRID * 2) else: diff --git a/b_asic/GUI/properties_window.py b/b_asic/GUI/properties_window.py index 84576d8b8f0d8808f0ebf196c2f1f93298622b50..3ff586fc05c7d75818adff88e57d84308803bdc1 100644 --- a/b_asic/GUI/properties_window.py +++ b/b_asic/GUI/properties_window.py @@ -23,7 +23,9 @@ class PropertiesWindow(QDialog): self.name_layout = QHBoxLayout() self.name_layout.setSpacing(50) self.name_label = QLabel("Name:") - self.edit_name = QLineEdit(self.operation.operation_path_name) + self.edit_name = QLineEdit( + self.operation.name or self.operation.type_name + ) self.name_layout.addWidget(self.name_label) self.name_layout.addWidget(self.edit_name) self.latency_fields = {} diff --git a/b_asic/operation.py b/b_asic/operation.py index 7a01d8d8977a818011c0d7b11bbeeb440ea379e7..ecedacef101c6ebcbe170d48609e15fb7cc56aee 100644 --- a/b_asic/operation.py +++ b/b_asic/operation.py @@ -389,7 +389,6 @@ class Operation(GraphComponent, SignalSourceProvider): """ raise NotImplementedError - @abstractmethod def _increase_time_resolution(self, factor: int) -> None: raise NotImplementedError diff --git a/b_asic/schedule.py b/b_asic/schedule.py index a0ac495e63e2cba8b696f8f79e64a536b4ef0a30..3a4f0f7bbb5bcb8e1a3aaedaa8b7416adfee0448 100644 --- a/b_asic/schedule.py +++ b/b_asic/schedule.py @@ -90,7 +90,8 @@ class Schedule: op = cast(Operation, self._sfg.find_by_id(op_id)) for outport in op.outputs: max_end_time = max( - max_end_time, op_start_time + cast(int, outport.latency_offset) + max_end_time, + op_start_time + cast(int, outport.latency_offset), ) return max_end_time @@ -209,7 +210,9 @@ class Schedule: k: factor * v for k, v in self._start_times.items() } for op_id in self._start_times: - cast(Operation, self._sfg.find_by_id(op_id))._increase_time_resolution(factor) + cast( + Operation, self._sfg.find_by_id(op_id) + )._increase_time_resolution(factor) self._schedule_time *= factor return self @@ -260,7 +263,9 @@ class Schedule: k: v // factor for k, v in self._start_times.items() } for op_id in self._start_times: - cast(Operation, self._sfg.find_by_id(op_id))._decrease_time_resolution(factor) + cast( + Operation, self._sfg.find_by_id(op_id) + )._decrease_time_resolution(factor) self._schedule_time = self._schedule_time // factor return self diff --git a/b_asic/signal_flow_graph.py b/b_asic/signal_flow_graph.py index 0c98df62aeb2fd2a9157988eeaa7c0a63d1c7910..c52d7dba8fe794436327538e84e0e92f5850599d 100644 --- a/b_asic/signal_flow_graph.py +++ b/b_asic/signal_flow_graph.py @@ -160,8 +160,12 @@ class SFG(AbstractOperation): raise ValueError( f"Duplicate input signal {signal!r} in SFG" ) - new_input_op = cast(Input, self._add_component_unconnected_copy(Input())) - new_signal = cast(Signal, self._add_component_unconnected_copy(signal)) + new_input_op = cast( + Input, self._add_component_unconnected_copy(Input()) + ) + new_signal = cast( + Signal, self._add_component_unconnected_copy(signal) + ) new_signal.set_source(new_input_op.output(0)) self._input_operations.append(new_input_op) self._original_input_signals_to_indices[signal] = input_index @@ -190,14 +194,20 @@ class SFG(AbstractOperation): # Setup output signals. if output_signals is not None: for output_index, signal in enumerate(output_signals): - new_output_op = cast(Output, self._add_component_unconnected_copy(Output())) + new_output_op = cast( + Output, self._add_component_unconnected_copy(Output()) + ) if signal in self._original_components_to_new: # Signal was already added when setting up inputs. - new_signal = cast(Signal, self._original_components_to_new[signal]) + new_signal = cast( + Signal, self._original_components_to_new[signal] + ) new_signal.set_destination(new_output_op.input(0)) else: # New signal has to be created. - new_signal = cast(Signal, self._add_component_unconnected_copy(signal)) + new_signal = cast( + Signal, self._add_component_unconnected_copy(signal) + ) new_signal.set_destination(new_output_op.input(0)) self._output_operations.append(new_output_op) @@ -213,7 +223,9 @@ class SFG(AbstractOperation): f"Duplicate output operation {output_op!r} in SFG" ) - new_output_op = cast(Output, self._add_component_unconnected_copy(output_op)) + new_output_op = cast( + Output, self._add_component_unconnected_copy(output_op) + ) for signal in output_op.input(0).signals: if signal in self._original_components_to_new: # Signal was already added when setting up inputs. @@ -993,11 +1005,16 @@ class SFG(AbstractOperation): original_op = op_stack.pop() # Add or get the new copy of the operation. if original_op not in self._original_components_to_new: - new_op = cast(Operation, self._add_component_unconnected_copy(original_op)) + new_op = cast( + Operation, + self._add_component_unconnected_copy(original_op), + ) self._components_dfs_order.append(new_op) self._operations_dfs_order.append(new_op) else: - new_op = cast(Operation, self._original_components_to_new[original_op]) + new_op = cast( + Operation, self._original_components_to_new[original_op] + ) # Connect input ports to new signals. for original_input_port in original_op.inputs: @@ -1011,9 +1028,10 @@ class SFG(AbstractOperation): in self._original_input_signals_to_indices ): # New signal already created during first step of constructor. - new_signal = cast(Signal, self._original_components_to_new[ - original_signal - ]) + new_signal = cast( + Signal, + self._original_components_to_new[original_signal], + ) new_signal.set_destination( new_op.input(original_input_port.index) @@ -1023,9 +1041,7 @@ class SFG(AbstractOperation): self._components_dfs_order.extend( [new_signal, source.operation] ) - self._operations_dfs_order.append( - source.operation - ) + self._operations_dfs_order.append(source.operation) # Check if the signal has not been added before. elif ( @@ -1036,9 +1052,12 @@ class SFG(AbstractOperation): "Dangling signal without source in SFG" ) - new_signal = cast(Signal, self._add_component_unconnected_copy( - original_signal - )) + new_signal = cast( + Signal, + self._add_component_unconnected_copy( + original_signal + ), + ) new_signal.set_destination( new_op.input(original_input_port.index) @@ -1054,19 +1073,23 @@ class SFG(AbstractOperation): original_connected_op in self._original_components_to_new ): - component = cast(Operation, self._original_components_to_new[ - original_connected_op - ]) + component = cast( + Operation, + self._original_components_to_new[ + original_connected_op + ], + ) # Set source to the already added operations port. new_signal.set_source( component.output(original_signal.source.index) ) else: # Create new operation, set signal source to it. - new_connected_op = cast(Operation, + new_connected_op = cast( + Operation, self._add_component_unconnected_copy( original_connected_op - ) + ), ) new_signal.set_source( new_connected_op.output( @@ -1089,9 +1112,10 @@ class SFG(AbstractOperation): in self._original_output_signals_to_indices ): # New signal already created during first step of constructor. - new_signal = cast(Signal, self._original_components_to_new[ - original_signal - ]) + new_signal = cast( + Signal, + self._original_components_to_new[original_signal], + ) new_signal.set_source( new_op.output(original_output_port.index) diff --git a/test/test_gui.py b/test/test_gui.py index 7dab9d388afb7256ede7e9b6a32c6f2b03e0007b..7bf9a424560f1fa40b571f22feb6cfee83ec8837 100644 --- a/test/test_gui.py +++ b/test/test_gui.py @@ -138,5 +138,46 @@ def test_help_dialogs(qtbot): widget.display_faq_page() widget.display_about_page() widget.display_keybinds_page() + qtbot.wait(100) + widget.faq_page.close() + widget.about_page.close() + widget.keybinds_page.close() + + widget.exit_app() + + +def test_properties_window_smoke_test(qtbot, datadir): + # Smoke test to open up the properties window + # Should really check that the contents are correct and changes works etc + widget = GUI.MainWindow() + qtbot.addWidget(widget) + widget._load_from_file(datadir.join('twotapfir.py')) + sfg = widget.sfg_dict['twotapfir'] + op = sfg.find_by_name("cmul2")[0] + dragbutton = widget.operationDragDict[op] + dragbutton.show_properties_window() + assert dragbutton._properties_window.operation == dragbutton + qtbot.mouseClick(dragbutton._properties_window.ok, QtCore.Qt.MouseButton.LeftButton) + widget.exit_app() + + +def test_properties_window_change_name(qtbot, datadir): + # Smoke test to open up the properties window + # Should really check that the contents are correct and changes works etc + widget = GUI.MainWindow() + qtbot.addWidget(widget) + widget._load_from_file(datadir.join('twotapfir.py')) + sfg = widget.sfg_dict['twotapfir'] + op = sfg.find_by_name("cmul2")[0] + dragbutton = widget.operationDragDict[op] + assert dragbutton.name == "cmul2" + assert dragbutton.operation.name == "cmul2" + dragbutton.show_properties_window() + assert dragbutton._properties_window.edit_name.text() == "cmul2" + dragbutton._properties_window.edit_name.setText("cmul73") + qtbot.mouseClick(dragbutton._properties_window.ok, QtCore.Qt.MouseButton.LeftButton) + dragbutton._properties_window.save_properties() + assert dragbutton.name == "cmul73" + assert dragbutton.operation.name == "cmul73" widget.exit_app() diff --git a/test/test_gui/twotapfir.py b/test/test_gui/twotapfir.py index 15660359fa8c83dca20a12e79c0b9af6c9c9dcca..c0ab4c540113986e896ebc70196b21496f9290be 100644 --- a/test/test_gui/twotapfir.py +++ b/test/test_gui/twotapfir.py @@ -13,9 +13,9 @@ out1 = Output(name="") # Operations: t1 = Delay(initial_value=0, name="") -cmul1 = ConstantMultiplication(value=0.5, name="cmul2", latency_offsets={'in0': None, 'out0': None}) +cmul1 = ConstantMultiplication(value=-0.5, name="cmul1", latency_offsets={'in0': None, 'out0': None}) add1 = Addition(name="add1", latency_offsets={'in0': None, 'in1': None, 'out0': None}) -cmul2 = ConstantMultiplication(value=0.5, name="cmul", latency_offsets={'in0': None, 'out0': None}) +cmul2 = ConstantMultiplication(value=0.5, name="cmul2", latency_offsets={'in0': None, 'out0': None}) # Signals: