diff --git a/b_asic/GUI/main_window.py b/b_asic/GUI/main_window.py index d6b05eacf06e0625504cc2742c662c7b460f381c..bdb3f805f9209228c44ecfb16438acf20e46b373 100644 --- a/b_asic/GUI/main_window.py +++ b/b_asic/GUI/main_window.py @@ -270,7 +270,7 @@ class MainWindow(QMainWindow): positions = {} for op in sfg.split(): - self.create_operation( + self.add_operation( op, 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, @@ -530,7 +530,9 @@ class MainWindow(QMainWindow): module, accepted = QFileDialog().getOpenFileName() if not accepted: return + self._add_namespace(module) + def _add_namespace(self, module): spec = importlib.util.spec_from_file_location( f"{QFileInfo(module).fileName()}", module ) @@ -539,18 +541,23 @@ class MainWindow(QMainWindow): self.add_operations_from_namespace(namespace, self._ui.custom_operations_list) - def create_operation( + def add_operation( self, op: Operation, position: Optional[Tuple[float, float]] = None, is_flipped: bool = False, ) -> None: """ + Add operation to GUI. + Parameters ---------- op : Operation + The operation to add. position : (float, float), optional + (x, y)-position for operation. is_flipped : bool, default: False + Whether the operation is flipped. """ try: if op in self._drag_buttons: @@ -625,7 +632,7 @@ class MainWindow(QMainWindow): self._logger.info("Creating operation of type: %s" % str(item.text())) try: attr_operation = self._operations_from_name[item.text()]() - self.create_operation(attr_operation) + self.add_operation(attr_operation) except Exception as e: self._logger.error( "Unexpected error occurred while creating operation: " + str(e) diff --git a/b_asic/scheduler_gui/axes_item.py b/b_asic/scheduler_gui/axes_item.py index d11b7a7caefbbb28c0da287130ecd71beb9052c3..bfea80673e824926be7d951a9b01a6f15ab83e88 100644 --- a/b_asic/scheduler_gui/axes_item.py +++ b/b_asic/scheduler_gui/axes_item.py @@ -128,11 +128,6 @@ class AxesItem(QGraphicsItemGroup): """ return self._width - # @width.setter - # def width(self, width: int) -> None: - # if self._width != width: - # self.update_axes(width = width) - @property def height(self) -> float: """ @@ -141,22 +136,6 @@ class AxesItem(QGraphicsItemGroup): """ return self._height - @height.setter - def height(self, height: float) -> None: - if self._height != height: - self._height = height - self._update_yaxis() - - # @property - # def width_indent(self) -> float: - # """Get or set the current x-axis indent. Setting the indent to a new - # value will update the axes automatically.""" - # return self._width_indent - # @width_indent.setter - # def width_indent(self, width_indent: float) -> None: - # if self._width_indent != width_indent: - # self.update_axes(width_indent = width_indent) - @property def event_items(self) -> List[QGraphicsItem]: """Return a list of objects, that receives events.""" @@ -170,8 +149,9 @@ class AxesItem(QGraphicsItemGroup): # TODO: docstring if height < 0: raise ValueError(f"'height' greater or equal to 0 expected, got: {height}.") - self._height = height - self._update_yaxis() + if self._height != height: + self._height = height + self._update_yaxis() def set_width(self, width: int) -> None: # TODO: docstring diff --git a/b_asic/scheduler_gui/main_window.py b/b_asic/scheduler_gui/main_window.py index 60e7c9622cb9f47db2f141798143cfecd8c93342..e02c7b8b017db368bfe7a53fdc7e5fb591f0bddb 100644 --- a/b_asic/scheduler_gui/main_window.py +++ b/b_asic/scheduler_gui/main_window.py @@ -318,6 +318,9 @@ class MainWindow(QMainWindow, Ui_MainWindow): self._graph.removeSceneEventFilters(self._graph.event_items) self._scene.removeItem(self._graph) self.menu_close_schedule.setEnabled(False) + self.menu_save.setEnabled(False) + self.menu_save_as.setEnabled(False) + del self._graph self._graph = None del self._schedule @@ -487,6 +490,8 @@ class MainWindow(QMainWindow, Ui_MainWindow): self._graph = SchedulerItem(self._schedule) self._graph.setPos(1 / self._scale, 1 / self._scale) self.menu_close_schedule.setEnabled(True) + self.menu_save.setEnabled(True) + self.menu_save_as.setEnabled(True) self._scene.addItem(self._graph) self._graph.installSceneEventFilters(self._graph.event_items) self._graph._signals.component_selected.connect( diff --git a/b_asic/scheduler_gui/scheduler_event.py b/b_asic/scheduler_gui/scheduler_event.py index 026d90fa1d5ef8c73e62c73833bb45025e88d4fc..7e6fa0ca8de5d882d9d220a60c37488445f48f76 100644 --- a/b_asic/scheduler_gui/scheduler_event.py +++ b/b_asic/scheduler_gui/scheduler_event.py @@ -119,28 +119,14 @@ class SchedulerEvent: # PyQt5 if isinstance(item, OperationItem): # one component switch = { - # QEvent.FocusIn: self.operation_focusInEvent, - # QEvent.GraphicsSceneContextMenu: self.operation_contextMenuEvent, - # QEvent.GraphicsSceneDragEnter: self.operation_dragEnterEvent, - # QEvent.GraphicsSceneDragMove: self.operation_dragMoveEvent, - # QEvent.GraphicsSceneDragLeave: self.operation_dragLeaveEvent, - # QEvent.GraphicsSceneDrop: self.operation_dropEvent, - # QEvent.GraphicsSceneHoverEnter: self.operation_hoverEnterEvent, - # QEvent.GraphicsSceneHoverMove: self.operation_hoverMoveEvent, - # QEvent.GraphicsSceneHoverLeave: self.operation_hoverLeaveEvent, QEvent.GraphicsSceneMouseMove: self.operation_mouseMoveEvent, QEvent.GraphicsSceneMousePress: self.operation_mousePressEvent, QEvent.GraphicsSceneMouseRelease: self.operation_mouseReleaseEvent, - # QEvent.GraphicsSceneMouseDoubleClick: - # self.operation_mouseDoubleClickEvent, - # QEvent.GraphicsSceneWheel: self.operation_wheelEvent } handler = switch.get(event.type()) elif isinstance(item, TimelineItem): # the timeline switch = { - # QEvent.GraphicsSceneHoverEnter: self.timeline_hoverEnterEvent, - # QEvent.GraphicsSceneHoverLeave: self.timeline_hoverLeaveEvent, QEvent.GraphicsSceneMouseMove: self.timeline_mouseMoveEvent, QEvent.GraphicsSceneMousePress: self.timeline_mousePressEvent, QEvent.GraphicsSceneMouseRelease: self.timeline_mouseReleaseEvent, @@ -161,32 +147,6 @@ class SchedulerEvent: # PyQt5 ################################# # Event Handlers: OperationItem # ################################# - def operation_focusInEvent(self, event: QFocusEvent) -> None: - ... - - def operation_contextMenuEvent(self, event: QGraphicsSceneContextMenuEvent) -> None: - ... - - def operation_dragEnterEvent(self, event: QGraphicsSceneDragDropEvent) -> None: - ... - - def operation_dragMoveEvent(self, event: QGraphicsSceneDragDropEvent) -> None: - ... - - def operation_dragLeaveEvent(self, event: QGraphicsSceneDragDropEvent) -> None: - ... - - def operation_dropEvent(self, event: QGraphicsSceneDragDropEvent) -> None: - ... - - def operation_hoverEnterEvent(self, event: QGraphicsSceneHoverEvent) -> None: - ... - - def operation_hoverMoveEvent(self, event: QGraphicsSceneHoverEvent) -> None: - ... - - def operation_hoverLeaveEvent(self, event: QGraphicsSceneHoverEvent) -> None: - ... def operation_mouseMoveEvent(self, event: QGraphicsSceneMouseEvent) -> None: """ @@ -263,12 +223,6 @@ class SchedulerEvent: # PyQt5 self._redraw_lines(item) self._signals.component_moved.emit(item.graph_id) - def operation_mouseDoubleClickEvent(self, event: QGraphicsSceneMouseEvent) -> None: - ... - - def operation_wheelEvent(self, event: QGraphicsSceneWheelEvent) -> None: - ... - ################################### # Event Handlers: GraphicsLineTem # ################################### diff --git a/b_asic/scheduler_gui/scheduler_item.py b/b_asic/scheduler_gui/scheduler_item.py index 29afe418e58ebf0aa4baa1d80cf488b20f3fa081..82c8536a76a4895c0766107431a67a8618449ef1 100644 --- a/b_asic/scheduler_gui/scheduler_item.py +++ b/b_asic/scheduler_gui/scheduler_item.py @@ -42,7 +42,7 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5 Parameters ========== - schedule : Schedule + schedule : :class:`~b_asic.schedule.Schedule` The Schedule to draw. parent : QGraphicsItem, optional @@ -91,7 +91,7 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5 Parameters ---------- - item : OperationItem + item : :class:`b_asic.scheduler_gui.operation_item.OperationItem` The component. pos : float The x-position to check. @@ -136,11 +136,11 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5 def set_item_active(self, item: OperationItem) -> None: """ - Set an item as active, i.e., draw it and connecting signals in special colors. + Set *item* as active, i.e., draw it and connecting signals in special colors. Parameters ---------- - item : OperationItem + item : :class:`b_asic.scheduler_gui.operation_item.OperationItem` The item to set as active. """ @@ -150,12 +150,12 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5 def set_item_inactive(self, item: OperationItem) -> None: """ - Set an item as inactive, i.e., draw it and connecting signals in standard + Set *item* as inactive, i.e., draw it and connecting signals in standard colors. Parameters ---------- - item : OperationItem + item : :class:`b_asic.scheduler_gui.operation_item.OperationItem` The item to set as active. """ @@ -164,7 +164,15 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5 signal.set_inactive() def set_new_start_time(self, item: OperationItem) -> None: - """Set new start time for *item*.""" + """ + Set new start time for *item*. + + Parameters + ---------- + item : :class:`b_asic.scheduler_gui.operation_item.OperationItem` + The item to set as active. + + """ pos = item.x() op_start_time = self.schedule.start_time_of_operation(item.graph_id) new_start_time = floor(pos) - floor(self._x_axis_indent) @@ -175,6 +183,12 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5 def is_valid_delta_time(self, delta_time: int) -> bool: """ Return True if the schedule time can be changed by *delta_time*. + + Parameters + ---------- + delta_time : int + The time difference to check for. + """ # TODO: implement # item = self.scene().mouseGrabberItem() @@ -185,7 +199,14 @@ class SchedulerItem(SchedulerEvent, QGraphicsItemGroup): # PySide2 / PyQt5 ) def change_schedule_time(self, delta_time: int) -> None: - """Change the schedule time by *delta_time* and redraw the graph.""" + """ + Change the schedule time by *delta_time* and redraw the graph. + + Parameters + ---------- + delta_time : int + The time difference to change the schedule time with. + """ if self._axes is None: raise RuntimeError("No AxesItem!") if self.schedule is None: diff --git a/b_asic/scheduler_gui/signal_item.py b/b_asic/scheduler_gui/signal_item.py index 2852a227bd54eac14904f54ca2c8d7b0e7f9edd1..267ab08e8368714bf956a48a6bf1fe864d4fba72 100644 --- a/b_asic/scheduler_gui/signal_item.py +++ b/b_asic/scheduler_gui/signal_item.py @@ -32,11 +32,11 @@ class SignalItem(QGraphicsPathItem): Parameters ---------- - src_operation : `~b_asic.scheduler_gui.operation_item.OperationItem` + src_operation : :class:`~b_asic.scheduler_gui.operation_item.OperationItem` The operation that the signal is drawn from. - dest_operation : `~b_asic.scheduler_gui.operation_item.OperationItem` + dest_operation : :class:`~b_asic.scheduler_gui.operation_item.OperationItem` The operation that the signal is drawn to. - signal : `~b_asic.signal.Signal` + signal : :class:`~b_asic.signal.Signal` The signal on the SFG level. parent : QGraphicsItem, optional The parent QGraphicsItem passed to QGraphicsPathItem. @@ -59,7 +59,7 @@ class SignalItem(QGraphicsPathItem): self._src_operation = src_operation self._dest_operation = dest_operation self._signal = signal - self.refresh_pens() + self._refresh_pens() self.set_inactive() self.update_path() @@ -97,7 +97,7 @@ class SignalItem(QGraphicsPathItem): path.cubicTo(ctrl_point1, ctrl_point2, dest_point) self.setPath(path) - def refresh_pens(self) -> None: + def _refresh_pens(self) -> None: """Create pens.""" pen = QPen(SIGNAL_ACTIVE) pen.setWidthF(SIGNAL_WIDTH) diff --git a/b_asic/scheduler_gui/timeline_item.py b/b_asic/scheduler_gui/timeline_item.py index 17752b33e383588c79920b7101676e608a5cf9cb..d2d82d399d7f50fdddcbb9023370632dd8af92c2 100644 --- a/b_asic/scheduler_gui/timeline_item.py +++ b/b_asic/scheduler_gui/timeline_item.py @@ -98,13 +98,11 @@ class TimelineItem(QGraphicsLineItem): # self._delta_time_label.setVisible(visible) def show_label(self) -> None: - """Show the label (label are not visible by default). This convenience - function is equivalent to calling set_label_visible(True).""" + """Show the label.""" self._delta_time_label.show() def hide_label(self) -> None: - """Hide the label (label are not visible by default). This convenience - function is equivalent to calling set_label_visible(False).""" + """Hide the label.""" self._delta_time_label.hide() def set_text_scale(self, scale: float) -> None: diff --git a/test/test_gui.py b/test/test_gui.py index 2b97730f9e4905cd2be426695f7aa44426933bbe..beb22644ce4681be795e8c1018178cdc1bd581b4 100644 --- a/test/test_gui.py +++ b/test/test_gui.py @@ -212,9 +212,9 @@ def test_add_operation_and_create_sfg(qtbot, monkeypatch): sqrt = SquareRoot() out1 = Output() # Create operations - widget.create_operation(in1) - widget.create_operation(sqrt) - widget.create_operation(out1) + widget.add_operation(in1) + widget.add_operation(sqrt) + widget.add_operation(out1) # Should be three operations assert len(widget._drag_buttons) == 3 # These particular three