Skip to content
Snippets Groups Projects
signal_item.py 4.38 KiB
Newer Older
  • Learn to ignore specific revisions
  • """
    B-ASIC Scheduler-GUI Signal Item Module.
    
    Contains the scheduler_gui SignalItem class for drawing and maintaining a signal
    in the schedule.
    """
    
    
    from typing import TYPE_CHECKING, cast
    
    Andreas Bolin's avatar
    Andreas Bolin committed
    
    
    from qtpy.QtCore import QPointF
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
    from qtpy.QtGui import QPainterPath, QPen
    
    from qtpy.QtWidgets import QGraphicsPathItem
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
    
    
    # B-ASIC
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
    from b_asic.scheduler_gui._preferences import (
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        SIGNAL_ACTIVE,
        SIGNAL_INACTIVE,
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        SIGNAL_WIDTH,
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
    )
    
    from b_asic.scheduler_gui.operation_item import OperationItem
    
    Andreas Bolin's avatar
    Andreas Bolin committed
    from b_asic.signal import Signal
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
    
    
    if TYPE_CHECKING:
        from b_asic.scheduler_gui.scheduler_item import SchedulerItem
    
    
    Andreas Bolin's avatar
    Andreas Bolin committed
    
    
    class SignalItem(QGraphicsPathItem):
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        """
        Class representing a signal in the scheduler GUI.
    
        Parameters
        ----------
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        src_operation : :class:`~b_asic.scheduler_gui.operation_item.OperationItem`
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            The operation that the signal is drawn from.
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        dest_operation : :class:`~b_asic.scheduler_gui.operation_item.OperationItem`
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            The operation that the signal is drawn to.
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        signal : :class:`~b_asic.signal.Signal`
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            The signal on the SFG level.
        parent : QGraphicsItem, optional
    
            The parent QGraphicsItem passed to QGraphicsPathItem.
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        """
    
    
        _src_operation: OperationItem
        _dest_operation: OperationItem
    
    Andreas Bolin's avatar
    Andreas Bolin committed
        _signal: Signal
    
        _active_pen: QPen
        _inactive_pen: QPen
    
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        def __init__(
            self,
    
            src_operation: OperationItem,
            dest_operation: OperationItem,
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            signal: Signal,
    
            parent: "SchedulerItem",
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        ):
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            super().__init__(parent=parent)
            self._src_operation = src_operation
            self._dest_operation = dest_operation
            self._signal = signal
    
            self._src_key = f"out{self._signal.source.index}"
            self._dest_key = f"in{self._signal.destination.index}"
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            self._refresh_pens()
    
            self.set_inactive()
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            self.update_path()
    
    
        def update_path(self) -> None:
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            """
            Create a new path after moving connected operations.
            """
    
            source_point = self._src_operation.get_port_location(self._src_key)
            dest_point = self._dest_operation.get_port_location(self._dest_key)
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            path = QPainterPath()
            path.moveTo(source_point)
            source_x = source_point.x()
            source_y = source_point.y()
            dest_x = dest_point.x()
            dest_y = dest_point.y()
    
            schedule = cast("SchedulerItem", self.parentItem()).schedule
            if dest_x - source_x <= -0.1 or schedule._laps[self._signal.graph_id]:
    
                offset = SCHEDULE_INDENT  # TODO: Get from parent/axes...
    
                path.lineTo(schedule.schedule_time + offset, source_y)
    
                path.moveTo(0 + offset, dest_y)
                path.lineTo(dest_x, dest_y)
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            else:
    
                if abs(source_x - dest_x) <= 0.1:  # "== 0"
                    ctrl_point1 = QPointF(source_x + 0.5, source_y)
                    ctrl_point2 = QPointF(source_x - 0.5, dest_y)
                else:
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
                    mid_x = (source_x + dest_x) / 2
    
                    ctrl_point1 = QPointF(mid_x, source_y)
                    ctrl_point2 = QPointF(mid_x, dest_y)
    
    Andreas Bolin's avatar
    Andreas Bolin committed
    
    
                path.cubicTo(ctrl_point1, ctrl_point2, dest_point)
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            self.setPath(path)
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        def _refresh_pens(self) -> None:
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            """Create pens."""
    
            pen = QPen(SIGNAL_ACTIVE)
    
            pen.setWidthF(SIGNAL_WIDTH_ACTIVE)
    
            self._active_pen = pen
            pen = QPen(SIGNAL_INACTIVE)
            pen.setWidthF(SIGNAL_WIDTH)
            self._inactive_pen = pen
    
            pen = QPen(SIGNAL_WARNING)
            pen.setWidthF(SIGNAL_WIDTH_WARNING)
            self._warning_pen = pen
    
        def set_active(self) -> None:
            """
            Set the signal color to represent that a connected operation is selected.
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            """
    
            self.setPen(self._active_pen)
    
            self._src_operation.set_port_active(self._src_key)
            self._dest_operation.set_port_active(self._dest_key)
    
        def set_inactive(self) -> None:
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            """Set the signal color to the default color."""
    
            warning = self._parent._warnings and (
                self._parent._schedule._input_slacks(self._signal.destination)[self._signal]
                > self._parent._schedule.schedule_time
            )
            self.setPen(self._warning_pen if warning else self._inactive_pen)
            self._src_operation.set_port_inactive(self._src_key, warning)
            self._dest_operation.set_port_inactive(self._dest_key, warning)