Example #1
0
    def box_rect(self, rect: QtCore.QRectF):
        self._box_rect = rect

        # Update the scene rect so that it matches how much space we
        # currently want for drawing everything.
        rect.setWidth(rect.width() - 1)
        self.setSceneRect(rect)
Example #2
0
    def get_header_rect(self):
        header_height = 1.4 * self.title_label.boundingRect().height()  # 35 * (self.parent_node.title.count('\n')+1)

        header_rect = QRectF()
        header_rect.setTopLeft(QPointF(-self.width/2, -self.height/2))
        header_rect.setWidth(self.width)
        header_rect.setHeight(header_height)
        return header_rect
Example #3
0
 def boundingRect(self):
     # remember: (0, 0) shall be the NI's center!
     rect = QRectF()
     w = self.layout.geometry().width()
     h = self.layout.geometry().height()
     rect.setLeft(-w / 2)
     rect.setTop(-h / 2)
     rect.setWidth(w)
     rect.setHeight(h)
     return rect
Example #4
0
    def get_header_rect(w, h, title_rect):
        """
        :param w: width
        :param h: height
        """

        header_height = 1.4 * title_rect.height(
        )  # 35 * (self.parent_node.title.count('\n')+1)

        header_rect = QRectF()
        header_rect.setTopLeft(QPointF(-w / 2, -h / 2))
        header_rect.setWidth(w)
        header_rect.setHeight(header_height)
        return header_rect
Example #5
0
    def get_title_rect(self):
        title_rect_offset_factor = 0.56

        header_rect = self.get_header_rect()
        rect = QRectF()
        rect.setTop(header_rect.top() + (header_rect.height() / 2) *
                    (1 - title_rect_offset_factor))
        rect.setLeft(header_rect.left() + 10)
        rect.setHeight(header_rect.height() * title_rect_offset_factor)
        w = header_rect.width() * title_rect_offset_factor
        title_width = self.display_name_FM.width(
            get_longest_line(self.parent_node.title))
        rect.setWidth(w if w > title_width else title_width)
        return rect
Example #6
0
 def show_all(self):
     # trick:
     # if user zoom in or zoom out too much view exceeds matrix limit
     # so need to set view's matrix to initial matrix
     self.setMatrix(self.initial_matrix)
     items = self.get_visible_items()
     rect = QRectF()
     for i in items:
         rect = rect.united(i.boundingRect())
     # it is not working properly without updating the rect
     # need to set new position and edit rect's size
     rect.setX(rect.x() - 1)
     rect.setY(rect.y() - 1)
     rect.setWidth(rect.width() + 1)
     rect.setHeight(rect.height() + 1)
     self.fitInView(rect, Qt.KeepAspectRatio)
Example #7
0
    def get_whole_scene_img(self):
        self.hide_proxies()
        img = QImage(self.sceneRect().width() / self.total_scale_div, self.sceneRect().height() / self.total_scale_div,
                     QImage.Format_RGB32)
        img.fill(Qt.transparent)

        painter = QPainter(img)
        painter.setRenderHint(QPainter.Antialiasing)
        rect = QRectF()
        rect.setLeft(-self.viewport().pos().x())
        rect.setTop(-self.viewport().pos().y())
        rect.setWidth(img.rect().width())
        rect.setHeight(img.rect().height())
        # rect is right... but it only renders from the viewport's point down-and rightwards, not from topleft (0,0) ...
        self.render(painter, rect, rect.toRect())
        self.show_proxies()
        return img
Example #8
0
    def paint(self, painter, option, widget=None):
        if Design.flow_theme == 'dark std':
            color = QColor(
                '#2E688C'
            ) if self.parent_port_instance.type_ == 'data' else QColor(
                '#3880ad')
            if option.state & QStyle.State_MouseOver:
                color = color.lighter()

            brush = QBrush(QColor(color))
            painter.setBrush(brush)
            painter.setPen(Qt.NoPen)

            painter.drawEllipse(
                QRectF(self.padding, self.padding, self.painting_width,
                       self.painting_height))

        elif Design.flow_theme == 'dark tron':
            color = ''
            if self.parent_port_instance.type_ == 'exec':
                color = '#FFFFFF'
            elif self.parent_port_instance.type_ == 'data':
                color = self.parent_node_instance.parent_node.color
            pen = QPen(color)
            pen.setWidth(2)
            painter.setPen(pen)
            if len(self.parent_port_instance.connected_port_instances) > 0 or \
                    option.state & QStyle.State_MouseOver:  # also fill when mouse hovers
                c = self.parent_node_instance.parent_node.color
                r = c.red()
                g = c.green()
                b = c.blue()
                brush = QBrush(QColor(r, g, b, 100))
                painter.setBrush(brush)
            else:
                painter.setBrush(Qt.NoBrush)

            painter.drawEllipse(
                QRectF(self.padding, self.padding, self.painting_width,
                       self.painting_height))

        elif Design.flow_theme == 'ghostly' or Design.flow_theme == 'blender':
            color = ''
            if self.parent_port_instance.type_ == 'exec':
                color = '#FFFFFF'

                if len(self.parent_port_instance.connected_port_instances) > 0 or \
                        option.state & QStyle.State_MouseOver:  # also fill when mouse hovers
                    brush = QBrush(QColor(255, 255, 255, 100))
                    painter.setBrush(brush)
                else:
                    painter.setBrush(Qt.NoBrush)
            elif self.parent_port_instance.type_ == 'data':
                color = self.parent_node_instance.parent_node.color

                if len(self.parent_port_instance.connected_port_instances) > 0 or \
                        option.state & QStyle.State_MouseOver:  # also fill when mouse hovers
                    c = self.parent_node_instance.parent_node.color
                    r = c.red()
                    g = c.green()
                    b = c.blue()
                    brush = QBrush(QColor(r, g, b, 100))
                    painter.setBrush(brush)
                else:
                    painter.setBrush(Qt.NoBrush)

            pen = QPen(color)
            pen.setWidth(1)
            painter.setPen(pen)

            rect = QRectF()
            rect.moveCenter(QPointF(self.width / 2, self.height / 2))
            rect.setWidth(self.painting_width)
            rect.setHeight(self.painting_height)
            painter.drawEllipse(QPointF(self.width / 2, self.height / 2),
                                self.painting_width / 3,
                                self.painting_height / 3)
Example #9
0
class TextLineItem(QAbstractGraphicsShapeItem):
    """A one-line text item.

    Default origin point is at the left side of the baseline. This can change if setAlignMode is called. TextLineItem
    also supports drawing text background. Its brush can be set using setBackgroundBrush(). Text must not contain
    newline characters.
    """
    def __init__(self, text=None, parent=None):
        super().__init__(parent)

        self._text = text or ""
        self._elided_text = text or ""
        self._elide_mode = Qt.ElideRight
        self._align_mode = Qt.AlignLeft
        self._max_width = None
        self._font = QFont()
        self._bounding_rect = QRectF()
        """Bounding and drawing rectangle. Determined automatically."""

        self.background = QGraphicsRectItem(self)
        self.background.setPen(Qt.NoPen)
        self.background.setFlag(QGraphicsItem.ItemStacksBehindParent)

        self.adjust()

    def setText(self, text: str, /) -> None:
        if '\n' in text:
            raise ValueError("text must not contain newline characters")

        self.prepareGeometryChange()
        self._text = text
        self.adjust()

    def setElideMode(self, mode: int, /) -> None:
        """Elide mode specifies where the ellipsis should be located when the text is elided. Default value is 
        Qt.ElideRight.
        """
        self.prepareGeometryChange()
        self._elide_mode = mode
        self.adjust()

    def setAlignMode(self, mode: int, /) -> None:
        """Align mode specifies text alignment.

        Text alignment changes the origin point x position:  
        - If mode is Qt.AlignLeft, the origin point is on the left of the baseline.
        - If mode is Qt.AlignHCenter, the origin point is in the center of the baseline.
        - If mode is Qt.AlignRight, the origin point is on the right of the baseline.

        Vertical alignment has no meaning for one line of text and should not be set. Default value is Qt.AlignLeft.
        """
        self.prepareGeometryChange()
        self._align_mode = mode
        self.adjust()

    def setMaximumWidth(self, width, /):
        """Set the maximum width the text is allowed to be. `None` represents unlimited width."""
        self.prepareGeometryChange()
        self._max_width = width
        self.adjust()

    def setFont(self, font: QFont, /) -> None:
        self.prepareGeometryChange()
        self._font = font
        self.adjust()

    def setBackgroundBrush(self, brush: QBrush, /):
        self.background.setBrush(brush)

    def text(self) -> str:
        return self._text

    def elidedText(self) -> str:
        return self._elided_text

    def elideMode(self) -> int:
        return self._elide_mode

    def alignMode(self) -> int:
        return self._align_mode

    def maximumWidth(self):
        """Maximum width the text is allowed to be. `None` represents unlimited width."""
        return self._max_width

    def font(self) -> QFont:
        return self._font

    def backgroundBrush(self):
        return self.background.brush()

    def adjust(self):
        """Adjust the item's geometry in response to changes."""
        metrics = QFontMetricsF(self.font())

        # Get bounding rectangle for full text
        self._bounding_rect = metrics.boundingRect(self.text())

        # Constrain by maximum width
        if self.maximumWidth() is not None:
            self._bounding_rect.setWidth(self.maximumWidth())

        # Compute elided text
        self._elided_text = metrics.elidedText(self.text(), self.elideMode(),
                                               self.boundingRect().width())

        # Get bounding rectangle for elided text
        self._bounding_rect = metrics.boundingRect(self.elidedText())
        # It seems that for small characters like "..." the bounding rect returned is too small. Adjust it by a small
        # value.
        metrics_correction = px(1 / 72)
        self._bounding_rect.adjust(-metrics_correction, 0, metrics_correction,
                                   0)

        # Move origin point according to the alignment
        if self.alignMode() & Qt.AlignLeft:
            self._bounding_rect.moveLeft(0)
        elif self.alignMode() & Qt.AlignRight:
            self._bounding_rect.moveRight(0)
        else:
            self._bounding_rect.moveLeft(-self._bounding_rect.width() / 2)

        # Set background rect
        self.background.setRect(self.boundingRect())

    def boundingRect(self) -> QRectF:
        return self._bounding_rect

    def paint(self, painter: QPainter, option, widget=...) -> None:
        painter.setBrush(self.brush())
        painter.setPen(self.pen())
        painter.setFont(self.font())

        painter.drawText(self.boundingRect(), self.alignMode(),
                         self.elidedText())
Example #10
0
    def eventFilter(self, obj, event):
        if event.type() == QEvent.GraphicsSceneMousePress:
            if event.button() == Qt.MouseButton.LeftButton:
                self.mouse_pressed = True

                self.mouse_pressed_x, self.mouse_pressed_y = event.pos().x(
                ), event.pos().y()

                if self.draw_ellipse:
                    ellipsis = QGraphicsEllipseItem(self.chart)

                    ellipsis.setZValue(12)
                    ellipsis.setBrush(QBrush(QColor(244, 67, 54, 50)))
                    ellipsis.setPen(QPen(Qt.transparent))

                    self.ellipses.append(ellipsis)
                elif self.write_text:
                    for t in self.texts:
                        r = QRectF()
                        r.setTopLeft(t.pos())
                        r.setWidth(t.boundingRect().width())
                        r.setHeight(t.boundingRect().height())

                        if r.contains(self.mouse_pressed_x,
                                      self.mouse_pressed_y):
                            return True
                    """
                        The user clicked over an area where there is no text. So we create one.
                    """

                    text = QGraphicsTextItem(self.chart)

                    text.setZValue(12)
                    text.setPos(
                        QPointF(self.mouse_pressed_x, self.mouse_pressed_y))
                    text.setPlainText("label")
                    text.setAcceptHoverEvents(True)
                    text.setTabChangesFocus(True)
                    text.setFlags(QGraphicsTextItem.ItemIsMovable)
                    text.installEventFilter(self.text_event_filter)

                    self.texts.append(text)

                return True
            elif event.button() == Qt.MouseButton.RightButton:
                x, y = event.pos().x(), event.pos().y()

                for e in self.ellipses:
                    if e.rect().contains(x, y):
                        e.hide()

                        self.ellipses.remove(e)

                for t in self.texts:
                    r = QRectF()
                    r.setTopLeft(t.pos())
                    r.setWidth(t.boundingRect().width())
                    r.setHeight(t.boundingRect().height())

                    if r.contains(x, y):
                        t.hide()

                        self.texts.remove(t)

                return True

            return QObject.eventFilter(self, obj, event)

        elif event.type() == QEvent.GraphicsSceneMouseRelease:
            self.mouse_pressed = False

            return True

        elif event.type() == QEvent.GraphicsSceneMouseMove:
            if self.mouse_pressed:
                if self.draw_ellipse:
                    x, y = event.pos().x(), event.pos().y()

                    width = x - self.mouse_pressed_x
                    height = y - self.mouse_pressed_y

                    self.ellipses[-1].setRect(self.mouse_pressed_x,
                                              self.mouse_pressed_y, width,
                                              height)

                    return True

            return QObject.eventFilter(self, obj, event)

        return QObject.eventFilter(self, obj, event)