Skip to content
Snippets Groups Projects
arrow.py 3.3 KiB
Newer Older
  • Learn to ignore specific revisions
  • from qtpy.QtCore import QPointF
    from qtpy.QtGui import QPen, QPolygonF
    from qtpy.QtWidgets import QGraphicsPolygonItem, QMenu
    
    from b_asic.GUI._preferences import LINECOLOR, PORTHEIGHT, PORTWIDTH
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
    
    
    class Arrow(QGraphicsPolygonItem):
    
        """Arrow/connection in signal flow graph GUI."""
    
    
        def __init__(self, source, destination, window, signal=None, parent=None):
    
            """
            Parameters
            ==========
    
            source :
                Source operation.
            destination :
                Destination operation.
            window :
                Window containing signal flow graph.
            signal : Signal, optional
                Let arrow represent *signal*.
            parent : optional
                Parent.
            """
    
            super().__init__(parent)
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            if signal is None:
                signal = Signal(source.port, destination.port)
            self.signal = signal
    
            self.destination = destination
            self._window = window
            self.moveLine()
            self.source.moved.connect(self.moveLine)
            self.destination.moved.connect(self.moveLine)
    
        def contextMenuEvent(self, event):
    
            """Open right-click menu."""
    
            menu = QMenu()
            menu.addAction("Delete", self.remove)
            menu.exec_(self.cursor().pos())
    
        def remove(self):
    
            """Remove line and connections to signals etc."""
    
            self.signal.remove_destination()
            self.signal.remove_source()
            self._window.scene.removeItem(self)
            if self in self._window.signalList:
                self._window.signalList.remove(self)
    
            if self in self._window.signalPortDict:
                for port1, port2 in self._window.signalPortDict[self]:
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
                    for (
                        operation,
                        operation_ports,
                    ) in self._window.portDict.items():
                        if (
                            port1 in operation_ports or port2 in operation_ports
                        ) and operation in self._window.opToSFG:
                            self._window.logger.info(
                                "Operation detected in existing SFG, removing SFG"
                                " with name:"
                                f" {self._window.opToSFG[operation].name}."
                            )
                            del self._window.sfg_dict[
                                self._window.opToSFG[operation].name
                            ]
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
                            self._window.opToSFG = {
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
                                op: self._window.opToSFG[op]
                                for op in self._window.opToSFG
                                if self._window.opToSFG[op]
                                is not self._window.opToSFG[operation]
                            }
    
    
            del self._window.signalPortDict[self]
    
        def moveLine(self):
    
            """
            Draw a line connecting self.source with self.destination. Used as callback when moving operations.
            """
    
            self.setPen(QPen(LINECOLOR, 3))
    
            x0 = self.source.operation.x() + self.source.x() + PORTWIDTH
            y0 = self.source.operation.y() + self.source.y() + PORTHEIGHT/2
            x1 = self.destination.operation.x() + self.destination.x()
            y1 = self.destination.operation.y() + self.destination.y() + PORTHEIGHT/2
            p = QPolygonF() << QPointF(x0, y0) << QPointF(x1, y1)
            self.setPolygon(p)