diff --git a/b_asic/GUI/drag_button.py b/b_asic/GUI/drag_button.py index 638a04aaf0fdc738356d27c7450987e96dcf8c57..c28f5551b0c31dad8cc38d756a5b31e4f743e3e7 100644 --- a/b_asic/GUI/drag_button.py +++ b/b_asic/GUI/drag_button.py @@ -47,7 +47,7 @@ class DragButton(QPushButton): self, operation: Operation, show_name: bool, - window, + window: "SFGMainWindow", parent=None, ): self.name = operation.name or operation.graph_id diff --git a/b_asic/scheduler_gui/operation_item.py b/b_asic/scheduler_gui/operation_item.py index 01d0231a23d8dcd7fa4dd58e3f22560b0fe971d5..6259a643c9c376d2bdb8be59f057aca678d843e0 100644 --- a/b_asic/scheduler_gui/operation_item.py +++ b/b_asic/scheduler_gui/operation_item.py @@ -12,11 +12,13 @@ from typing import TYPE_CHECKING, Dict, List, Union, cast from qtpy.QtCore import QPointF, Qt from qtpy.QtGui import QBrush, QColor, QCursor, QPainterPath, QPen from qtpy.QtWidgets import ( + QAction, QGraphicsEllipseItem, QGraphicsItem, QGraphicsItemGroup, QGraphicsPathItem, QGraphicsSimpleTextItem, + QMenu, ) # B-ASIC @@ -81,12 +83,13 @@ class OperationItem(QGraphicsItemGroup): self.setFlag(QGraphicsItem.ItemIsSelectable) # mouse move events # self.setAcceptHoverEvents(True) # mouse hover events self.setAcceptedMouseButtons( - Qt.MouseButton.LeftButton + Qt.MouseButton.LeftButton | Qt.MouseButton.RightButton ) # accepted buttons for movements self.setCursor( QCursor(Qt.CursorShape.OpenHandCursor) ) # default cursor when hovering over object + self._context_menu = None self._make_component() # def sceneEvent(self, event: QEvent) -> bool: @@ -106,6 +109,11 @@ class OperationItem(QGraphicsItemGroup): """The graph-id of the operation that the item corresponds to.""" return self._operation.graph_id + @property + def name(self) -> str: + """The name of the operation that the item corresponds to.""" + return self._operation.name + @property def operation(self) -> Operation: """The operation that the item corresponds to.""" @@ -247,3 +255,14 @@ class OperationItem(QGraphicsItemGroup): self.addToGroup(self._execution_time_item) self.set_inactive() + + def _open_context_menu(self): + menu = QMenu() + swap = QAction("Swap") + menu.addAction(swap) + swap.setEnabled(self._operation.is_swappable) + swap.triggered.connect(self._swap_io) + menu.exec_(self.cursor().pos()) + + def _swap_io(self, event=None) -> None: + self._operation.swap_io() diff --git a/b_asic/scheduler_gui/scheduler_event.py b/b_asic/scheduler_gui/scheduler_event.py index 1639d16618269d6960db435622acd151c067b9a9..f8c74dbeffb106e3925c1de6921b2261d6346841 100644 --- a/b_asic/scheduler_gui/scheduler_event.py +++ b/b_asic/scheduler_gui/scheduler_event.py @@ -10,7 +10,7 @@ import math from typing import List, Optional, overload # QGraphics and QPainter imports -from qtpy.QtCore import QEvent, QObject, QPointF, Signal +from qtpy.QtCore import QEvent, QObject, QPointF, Qt, Signal from qtpy.QtWidgets import QGraphicsItem, QGraphicsSceneMouseEvent from b_asic.schedule import Schedule @@ -181,14 +181,22 @@ class SchedulerEvent: # PyQt5 allows the item to receive future move, release and double-click events. """ item: OperationItem = self.scene().mouseGrabberItem() - self._old_op_position = self._schedule.get_y_location(item.operation.graph_id) - self._signals.component_selected.emit(item.graph_id) - self._current_pos = item.mapToParent(event.pos()) - self.set_item_active(item) - event.accept() + if event.button() == Qt.MouseButton.LeftButton: + self._old_op_position = self._schedule.get_y_location( + item.operation.graph_id + ) + self._signals.component_selected.emit(item.graph_id) + self._current_pos = item.mapToParent(event.pos()) + self.set_item_active(item) + event.accept() + else: # Right-button + item._open_context_menu() def operation_mouseReleaseEvent(self, event: QGraphicsSceneMouseEvent) -> None: """Change the cursor to OpenHandCursor when releasing an object.""" + if event.button() != Qt.MouseButton.LeftButton: + return + item: OperationItem = self.scene().mouseGrabberItem() self.set_item_inactive(item) self.set_new_start_time(item)