Newer
Older
from typing import TYPE_CHECKING
from qtpy.QtCore import QMimeData, Qt, Signal
from qtpy.QtGui import QDrag
Angus Lothian
committed
if TYPE_CHECKING:
from b_asic.GUI.drag_button import DragButton
from b_asic.operation import Operation
from b_asic.port import Port
Angus Lothian
committed
class PortButton(QPushButton):
"""
A button corresponding to a port.
Parameters
----------
operation_button : :class:`~b_asic.GUI.drag_button.DragButton`
port : :class:`~b_asic.port.Port`
Angus Lothian
committed
connectionRequested = Signal(QPushButton)
moved = Signal()
def __init__(self, name: str, operation_button: "DragButton", port: "Port"):
super().__init__(name, parent=operation_button)
Angus Lothian
committed
self.pressed = False
self._window = operation_button._window
Angus Lothian
committed
self.port = port
self._operation_button = operation_button
Angus Lothian
committed
self._m_drag = False
self._m_press = False
self.setAcceptDrops(True)
self.setCursor(Qt.ArrowCursor)
Angus Lothian
committed
self.setStyleSheet("background-color: white")
self.connectionRequested.connect(self._window._connect_callback)
Angus Lothian
committed
@property
def operation(self) -> "Operation":
"""Operation associated with PortButton."""
return self._operation_button.operation
Angus Lothian
committed
def contextMenuEvent(self, event):
menu = QMenu()
menu.addAction("Connect", lambda: self.connectionRequested.emit(self))
menu.exec_(self.cursor().pos())
def mousePressEvent(self, event):
if event.button() == Qt.MouseButton.LeftButton:
Angus Lothian
committed
self.select_port(event.modifiers())
super().mousePressEvent(event)
Angus Lothian
committed
def mouseReleaseEvent(self, event):
if event.button() == Qt.MouseButton.LeftButton and self._window._mouse_pressed:
self._window._mouse_pressed = False
if self._window._mouse_dragging:
self._window._mouse_dragging = False
super().mouseReleaseEvent(event)
Angus Lothian
committed
if self._window._mouse_pressed:
self._window._mouse_dragging = True
self._window._starting_port = self
data = QMimeData()
drag = QDrag(self)
drag.setMimeData(data)
drag.exec()
super().mouseMoveEvent(event)
def dragEnterEvent(self, event):
event.acceptProposedAction()
self.update()
super().dragEnterEvent(event)
def dragLeaveEvent(self, event):
self.update()
super().dragLeaveEvent(event)
def dragMoveEvent(self, event):
event.acceptProposedAction()
super().dragMoveEvent(event)
def dropEvent(self, event):
event.acceptProposedAction()
if self != self._window._starting_port:
self.select_port(Qt.KeyboardModifier.ControlModifier)
self._window._connect_callback()
self.update()
super().dropEvent(event)
def _toggle_port(self, pressed: bool = False):
Angus Lothian
committed
self.pressed = not pressed
f"background-color: {'white' if not self.pressed else 'grey'}"
)
Angus Lothian
committed
def select_port(self, modifiers=None):
"""
Select the port taking *modifiers* into account.
Parameters
----------
modifiers : optional
Qt keyboard modifier.
"""
if modifiers != Qt.KeyboardModifier.ControlModifier:
for port in self._window._pressed_ports:
Angus Lothian
committed
port._toggle_port(port.pressed)
self._toggle_port(self.pressed)
self._window._pressed_ports = [self]
Angus Lothian
committed
else:
self._toggle_port(self.pressed)
if self in self._window._pressed_ports:
self._window._pressed_ports.remove(self)
Angus Lothian
committed
else:
self._window._pressed_ports.append(self)
Angus Lothian
committed
for arrow in self._window._arrow_ports:
arrow.update()