diff --git a/b_asic/gui_utils/icons.py b/b_asic/gui_utils/icons.py index ea59c6e292193a4eed0d48bc742430dd0f409173..8ba60f4641ea0c3c26d68f69c34364081c407fcb 100644 --- a/b_asic/gui_utils/icons.py +++ b/b_asic/gui_utils/icons.py @@ -32,6 +32,7 @@ ICONS = { 'full-screen': 'mdi6.fullscreen', 'full-screen-exit': 'mdi6.fullscreen-exit', 'warning': 'fa.warning', + 'port-numbers': 'fa.hashtag', } diff --git a/b_asic/scheduler_gui/main_window.py b/b_asic/scheduler_gui/main_window.py index 36de5a88f1ad2357185b65986816cd4047bd38be..ca021deb566638656b379b41f0408ac177f111fd 100644 --- a/b_asic/scheduler_gui/main_window.py +++ b/b_asic/scheduler_gui/main_window.py @@ -121,6 +121,7 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow): self._init_ui() self._file_name = None self._show_incorrect_execution_time = True + self._show_port_numbers = True # Recent files self._max_recent_files = 4 @@ -156,6 +157,8 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow): self.action_incorrect_execution_time.triggered.connect( self._toggle_execution_time_warning ) + self.action_show_port_numbers.setIcon(get_icon('port-numbers')) + self.action_show_port_numbers.triggered.connect(self._toggle_port_number) self.actionPlot_schedule.setIcon(get_icon('plot-schedule')) self.actionPlot_schedule.triggered.connect(self._plot_schedule) self.actionZoom_to_fit.setIcon(get_icon('zoom-to-fit')) @@ -846,6 +849,11 @@ class ScheduleMainWindow(QMainWindow, Ui_MainWindow): ) self._graph.set_warnings(self._show_incorrect_execution_time) + def _toggle_port_number(self, event=None) -> None: + """Callback for toggling the status bar.""" + self._show_port_numbers = self.action_show_port_numbers.isChecked() + self._graph.set_port_numbers(self._show_port_numbers) + def _toggle_fullscreen(self, event=None): """Callback for toggling full screen mode.""" if self.isFullScreen(): diff --git a/b_asic/scheduler_gui/main_window.ui b/b_asic/scheduler_gui/main_window.ui index 0de9d87255f34ca3cd98c4558759a9c4e1733ffc..4bd2dd0c52ec4cacd2c4588b587ade4adae80b26 100644 --- a/b_asic/scheduler_gui/main_window.ui +++ b/b_asic/scheduler_gui/main_window.ui @@ -232,6 +232,7 @@ <addaction name="actionToolbar"/> <addaction name="actionStatus_bar"/> <addaction name="action_incorrect_execution_time"/> + <addaction name="action_show_port_numbers"/> <addaction name="separator"/> <addaction name="actionPlot_schedule"/> <addaction name="separator"/> @@ -289,6 +290,7 @@ <addaction name="separator"/> <addaction name="menu_node_info"/> <addaction name="action_incorrect_execution_time"/> + <addaction name="action_show_port_numbers"/> <addaction name="actionReorder"/> </widget> <action name="menu_load_from_file"> @@ -503,6 +505,23 @@ <string>Show/hide toolbar</string> </property> </action> + <action name="action_show_port_numbers"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="text"> + <string>S&how port numbers</string> + </property> + <property name="toolTip"> + <string>Show port numbers of operation</string> + </property> + <property name="iconVisibleInMenu"> + <bool>false</bool> + </property> + </action> <action name="action_incorrect_execution_time"> <property name="checkable"> <bool>true</bool> diff --git a/b_asic/scheduler_gui/operation_item.py b/b_asic/scheduler_gui/operation_item.py index d8f52d9d78e23560092bbb046896df868f24a651..258934a49c9718dc146b610468f4eaf9a9a96219 100644 --- a/b_asic/scheduler_gui/operation_item.py +++ b/b_asic/scheduler_gui/operation_item.py @@ -62,6 +62,7 @@ class OperationItem(QGraphicsItemGroup): _execution_time_item: QGraphicsPathItem _label_item: QGraphicsSimpleTextItem _port_items: List[QGraphicsEllipseItem] + _port_number_items: List[QGraphicsSimpleTextItem] def __init__( self, @@ -81,6 +82,7 @@ class OperationItem(QGraphicsItemGroup): self._ports = {k: {"latency": float(v)} for k, v in latency_offsets.items()} self._end_time = max(latency_offsets.values()) self._port_items = [] + self._port_number_items = [] self.setFlag(QGraphicsItem.ItemIsMovable) # mouse move events self.setFlag(QGraphicsItem.ItemIsSelectable) # mouse move events @@ -186,6 +188,10 @@ class OperationItem(QGraphicsItemGroup): self._set_background(OPERATION_LATENCY_INACTIVE) self.setCursor(QCursor(Qt.CursorShape.OpenHandCursor)) + def set_show_port_numbers(self, port_number: bool = True): + for item in self._port_number_items: + item.setVisible(port_number) + def set_port_active(self, key: str): item = self._ports[key]["item"] item.setBrush(self._port_filling_brush_active) @@ -263,6 +269,20 @@ class OperationItem(QGraphicsItemGroup): create_ports(self._operation.get_input_coordinates(), "in") create_ports(self._operation.get_output_coordinates(), "out") + for i, (x, y) in enumerate(self._operation.get_input_coordinates()): + port_item = QGraphicsSimpleTextItem(str(i)) + port_item.setScale(port_item.scale() / self._scale) + center = port_item.boundingRect().center() / self._scale + port_item.setPos(QPointF(x + center.x(), y * self._height - center.y())) + self._port_number_items.append(port_item) + + for i, (x, y) in enumerate(self._operation.get_output_coordinates()): + port_item = QGraphicsSimpleTextItem(str(i)) + port_item.setScale(port_item.scale() / self._scale) + center = port_item.boundingRect().center() / self._scale + port_item.setPos(QPointF(x - 3 * center.x(), y * self._height - center.y())) + self._port_number_items.append(port_item) + # op-id/label self._label_item = QGraphicsSimpleTextItem(self._operation.graph_id) self._label_item.setScale(self._label_item.scale() / self._scale) @@ -275,6 +295,8 @@ class OperationItem(QGraphicsItemGroup): for port in self._ports.values(): self.addToGroup(port["item"]) self.addToGroup(self._label_item) + for item in self._port_number_items: + self.addToGroup(item) if execution_time: self.addToGroup(self._execution_time_item) diff --git a/b_asic/scheduler_gui/scheduler_item.py b/b_asic/scheduler_gui/scheduler_item.py index b2b03600d2506eabac98f52dc0d27e3b0f5e25f3..988fccca5543f232852997822bbd4bffe722b161 100644 --- a/b_asic/scheduler_gui/scheduler_item.py +++ b/b_asic/scheduler_gui/scheduler_item.py @@ -45,6 +45,14 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5 schedule : :class:`~b_asic.schedule.Schedule` The Schedule to draw. + warnings : bool, default: True + Whether to draw processes with execution time longer than schedule time in + a different color. + + port_numbers : bool, default: False + Whether to show port numbers on the operations. + + parent : QGraphicsItem, optional The parent. Passed to the constructor of QGraphicsItemGroup """ @@ -59,6 +67,7 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5 self, schedule: Schedule, warnings: bool = True, + show_port_numbers: bool = False, parent: Optional[QGraphicsItem] = None, ): """ @@ -74,13 +83,16 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5 # super().__init__(parent=self) self._schedule = schedule self._parent = parent - self._warnings = warnings + self._warnings = not warnings # To trigger redraw + self._show_port_numbers = not show_port_numbers # To trigger redraw self._axes = None self._operation_items = {} self._x_axis_indent = SCHEDULE_INDENT self._event_items = [] self._signal_dict = defaultdict(set) self._make_graph() + self.set_warnings(warnings) + self.set_port_numbers(show_port_numbers) def clear(self) -> None: """ @@ -142,7 +154,7 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5 Parameters ---------- - warnings : bool + warnings : bool, default: True Whether to draw processes with execution time longer than schedule time in a different color. """ @@ -154,6 +166,20 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5 for signal in s: signal.set_inactive() + def set_port_numbers(self, port_numbers: bool = True): + """ + Set if port numbers are shown. + + Parameters + ---------- + port_numbers : bool, default: True + Whether to show port numbers on the operations. + """ + if port_numbers != self._show_port_numbers: + self._show_port_numbers = port_numbers + for item in self._operation_items.values(): + item.set_show_port_numbers(port_numbers) + def set_item_active(self, item: OperationItem) -> None: """ Set *item* as active, i.e., draw it and connecting signals in special colors. diff --git a/b_asic/scheduler_gui/ui_main_window.py b/b_asic/scheduler_gui/ui_main_window.py index 7159bf2e7bd2ae08174143f98bf27e87b22d4512..1409e7fc1f82cb7bce01c77b8282698eb9e3e088 100644 --- a/b_asic/scheduler_gui/ui_main_window.py +++ b/b_asic/scheduler_gui/ui_main_window.py @@ -226,6 +226,11 @@ class Ui_MainWindow(object): self.actionToolbar.setCheckable(True) self.actionToolbar.setChecked(True) self.actionToolbar.setObjectName("actionToolbar") + self.action_show_port_numbers = QtWidgets.QAction(MainWindow) + self.action_show_port_numbers.setCheckable(True) + self.action_show_port_numbers.setChecked(False) + self.action_show_port_numbers.setIconVisibleInMenu(False) + self.action_show_port_numbers.setObjectName("action_show_port_numbers") self.action_incorrect_execution_time = QtWidgets.QAction(MainWindow) self.action_incorrect_execution_time.setCheckable(True) self.action_incorrect_execution_time.setChecked(True) @@ -251,6 +256,7 @@ class Ui_MainWindow(object): self.menuView.addAction(self.actionToolbar) self.menuView.addAction(self.actionStatus_bar) self.menuView.addAction(self.action_incorrect_execution_time) + self.menuView.addAction(self.action_show_port_numbers) self.menuView.addSeparator() self.menuView.addAction(self.actionPlot_schedule) self.menuView.addSeparator() @@ -280,6 +286,7 @@ class Ui_MainWindow(object): self.toolBar.addSeparator() self.toolBar.addAction(self.menu_node_info) self.toolBar.addAction(self.action_incorrect_execution_time) + self.toolBar.addAction(self.action_show_port_numbers) self.toolBar.addAction(self.actionReorder) self.retranslateUi(MainWindow) @@ -362,6 +369,12 @@ class Ui_MainWindow(object): ) self.actionToolbar.setText(_translate("MainWindow", "&Toolbar")) self.actionToolbar.setToolTip(_translate("MainWindow", "Show/hide toolbar")) + self.action_show_port_numbers.setText( + _translate("MainWindow", "S&how port numbers") + ) + self.action_show_port_numbers.setToolTip( + _translate("MainWindow", "Show port numbers of operation") + ) self.action_incorrect_execution_time.setText( _translate("MainWindow", "&Incorrect execution time") )