Newer
Older
from qtpy.QtGui import QPen, QPainterPath
from qtpy.QtWidgets import QGraphicsPathItem, QMenu
Angus Lothian
committed
from b_asic.GUI._preferences import LINECOLOR, PORTHEIGHT, PORTWIDTH
Angus Lothian
committed
from b_asic.signal import Signal
"""Arrow/connection in signal flow graph GUI."""
Angus Lothian
committed
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)
Angus Lothian
committed
self.source = source
if signal is None:
signal = Signal(source.port, destination.port)
self.signal = signal
Angus Lothian
committed
self.destination = destination
self._window = window
self.moveLine()
self.source.moved.connect(self.moveLine)
self.destination.moved.connect(self.moveLine)
def contextMenuEvent(self, event):
Angus Lothian
committed
menu = QMenu()
menu.addAction("Delete", self.remove)
menu.exec_(self.cursor().pos())
def remove(self):
"""Remove line and connections to signals etc."""
Angus Lothian
committed
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]:
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
]
op: self._window.opToSFG[op]
for op in self._window.opToSFG
if self._window.opToSFG[op]
is not self._window.opToSFG[operation]
}
Angus Lothian
committed
del self._window.signalPortDict[self]
def moveLine(self):
"""
Draw a line connecting self.source with self.destination. Used as callback when moving operations.
"""
ORTHOGONAL = True
OFFSET = 2 * PORTWIDTH
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
)
xmid = (x0 + x1) / 2
ymid = (y0 + y1) / 2
p = QPainterPath(QPointF(x0, y0))
if y0 == y1 or not ORTHOGONAL:
pass
elif abs(x0 - x1) <= OFFSET / 2:
p.lineTo(QPointF(x0 + OFFSET, y0))
p.lineTo(QPointF(x0 + OFFSET, ymid))
p.lineTo(QPointF(x0 - OFFSET, ymid))
p.lineTo(QPointF(x0 - OFFSET, y1))
else:
p.lineTo(QPointF(xmid, y0))
p.lineTo(QPointF(xmid, y1))
p.lineTo(QPointF(x1, y1))
self.setPath(p)