Skip to content
Snippets Groups Projects
port_button.py 4.02 KiB
Newer Older
  • Learn to ignore specific revisions
  • Oscar Gustafsson's avatar
    Oscar Gustafsson committed
    """
    B-ASIC port button module.
    """
    
    from typing import TYPE_CHECKING
    
    
    Olle Hansson's avatar
    Olle Hansson committed
    from qtpy.QtCore import QMimeData, Qt, Signal
    from qtpy.QtGui import QDrag
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
    from qtpy.QtWidgets import QMenu, QPushButton
    
    if TYPE_CHECKING:
        from b_asic.GUI.drag_button import DragButton
    
        from b_asic.operation import Operation
    
        from b_asic.port import Port
    
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        """
        A button corresponding to a port.
    
        Parameters
        ----------
    
            The name of the button.
    
        operation_button : :class:`~b_asic.GUI.drag_button.DragButton`
    
            The parent DragButton.
    
        port : :class:`~b_asic.port.Port`
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
        """
    
    
        connectionRequested = Signal(QPushButton)
        moved = Signal()
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
    
    
        def __init__(self, name: str, operation_button: "DragButton", port: "Port"):
            super().__init__(name, parent=operation_button)
    
            self._window = operation_button._window
    
            self._operation_button = operation_button
    
    Olle Hansson's avatar
    Olle Hansson committed
            self.setAcceptDrops(True)
            self.setCursor(Qt.ArrowCursor)
    
    
            self.setStyleSheet("background-color: white")
    
    Olle Hansson's avatar
    Olle Hansson committed
            self.connectionRequested.connect(self._window._connect_callback)
    
        @property
        def operation(self) -> "Operation":
            """Operation associated with PortButton."""
            return self._operation_button.operation
    
    
        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:
    
                self._window._mouse_pressed = True
    
            super().mousePressEvent(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)
    
    Olle Hansson's avatar
    Olle Hansson committed
        def mouseMoveEvent(self, event):
    
            if self._window._mouse_pressed:
                self._window._mouse_dragging = True
                self._window._starting_port = self
    
    Olle Hansson's avatar
    Olle Hansson committed
                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:
    
    Olle Hansson's avatar
    Olle Hansson committed
                self.select_port(Qt.KeyboardModifier.ControlModifier)
                self._window._connect_callback()
            self.update()
            super().dropEvent(event)
    
    
        def _toggle_port(self, pressed: bool = False):
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
            self.setStyleSheet(
    
    Oscar Gustafsson's avatar
    Oscar Gustafsson committed
                f"background-color: {'white' if not self.pressed else 'grey'}"
            )
    
            """
            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:
    
                    port._toggle_port(port.pressed)
    
                self._toggle_port(self.pressed)
    
                self._window._pressed_ports = [self]
    
                if self in self._window._pressed_ports:
                    self._window._pressed_ports.remove(self)
    
                    self._window._pressed_ports.append(self)
    
            for arrow in self._window._arrow_ports:
                arrow.update()