class CustomGraphicsView(QGraphicsView):
    def __init__(self, parent):
        super().__init__(parent)
        self.pen = QPen(Qt.green, 3, join=Qt.MiterJoin)
        self.item_batch = []
        self.item_batches = collections.deque()

    def wheelEvent(self, event):
        if self.scene() and QApplication.keyboardModifiers(
        ) == Qt.ControlModifier:
            transform = self.transform()
            scale = 1 + ZOOM_FACTOR if event.angleDelta().y(
            ) > 0 else 1 - ZOOM_FACTOR
            self.setTransform(transform * scale)

    def mousePressEvent(self, event):
        if not self.scene():
            return

        position = self.mapToScene(event.x(), event.y())
        item = self.scene().addRect(position.x(),
                                    position.y(), self.pen.width(),
                                    self.pen.width(), self.pen,
                                    self.pen.brush())
        self.item_batch.append(item)

    # TODO: Calculate line between new and last-known position, and draw a rectangle for each point on the line,
    # TODO: addLine() seems to add a different-looking pattern
    def mouseMoveEvent(self, event):
        self.mousePressEvent(event)

    def mouseReleaseEvent(self, event):
        if self.item_batch:
            self.item_batches.append(self.item_batch)
        self.item_batch = []

    # TODO: This is super ugly because we don't use addLine()
    def undo(self):
        if not self.item_batches:
            return

        item_batch = self.item_batches.pop()
        scene = self.scene()
        for item in item_batch:
            scene.removeItem(item)
    def paint(self,
              painter: QtGui.QPainter,
              option: 'QStyleOptionGraphicsItem',
              widget: QWidget = None):

        print(option.levelOfDetailFromTransform(painter.worldTransform()))

        painter.save()
        pen = QPen(Qt.red)
        pen.setWidth(0)
        painter.setPen(pen)
        brush = pen.brush()
        for i in range(200 - 1):
            height = data['high'][i] - data['low'][i]
            painter.fillRect(
                QRectF(i * 3, data['high'][i] - data['high'].min(), 1, height),
                brush)

        painter.fillRect(QRectF(100, 100, 100, -100), Qt.blue)
        painter.restore()
Esempio n. 3
0
    def paint(self, painter, option, widget):
        painter.save()
        painter.setRenderHint(QPainter.Antialiasing,
                              bool(options.antialiasing == ANTIALIASING_FULL))

        selected = self.isSelected()
        theme = canvas.theme
        if self.m_port_type == PORT_TYPE_AUDIO_JACK:
            poly_color = theme.port_audio_jack_bg_sel if selected else theme.port_audio_jack_bg
            poly_pen = theme.port_audio_jack_pen_sel if selected else theme.port_audio_jack_pen
            text_pen = theme.port_audio_jack_text_sel if selected else theme.port_audio_jack_text
            conn_pen = QPen(theme.port_audio_jack_pen_sel)
        elif self.m_port_type == PORT_TYPE_MIDI_JACK:
            poly_color = theme.port_midi_jack_bg_sel if selected else theme.port_midi_jack_bg
            poly_pen = theme.port_midi_jack_pen_sel if selected else theme.port_midi_jack_pen
            text_pen = theme.port_midi_jack_text_sel if selected else theme.port_midi_jack_text
            conn_pen = QPen(theme.port_midi_jack_pen_sel)
        elif self.m_port_type == PORT_TYPE_MIDI_ALSA:
            poly_color = theme.port_midi_alsa_bg_sel if selected else theme.port_midi_alsa_bg
            poly_pen = theme.port_midi_alsa_pen_sel if selected else theme.port_midi_alsa_pen
            text_pen = theme.port_midi_alsa_text_sel if selected else theme.port_midi_alsa_text
            conn_pen = QPen(theme.port_midi_alsa_pen_sel)
        elif self.m_port_type == PORT_TYPE_PARAMETER:
            poly_color = theme.port_parameter_bg_sel if selected else theme.port_parameter_bg
            poly_pen = theme.port_parameter_pen_sel if selected else theme.port_parameter_pen
            text_pen = theme.port_parameter_text_sel if selected else theme.port_parameter_text
            conn_pen = QPen(theme.port_parameter_pen_sel)
        else:
            qCritical(
                "PatchCanvas::CanvasPort.paint() - invalid port type '%s'" %
                port_type2str(self.m_port_type))
            return

        # To prevent quality worsening
        poly_pen = QPen(poly_pen)
        poly_pen.setWidthF(poly_pen.widthF() + 0.00001)

        if self.m_is_alternate:
            poly_color = poly_color.darker(180)
            #poly_pen.setColor(poly_pen.color().darker(110))
            #text_pen.setColor(text_pen.color()) #.darker(150))
            #conn_pen.setColor(conn_pen.color()) #.darker(150))

        lineHinting = poly_pen.widthF() / 2

        poly_locx = [0, 0, 0, 0, 0]
        poly_corner_xhinting = (float(canvas.theme.port_height) / 2) % floor(
            float(canvas.theme.port_height) / 2)
        if poly_corner_xhinting == 0:
            poly_corner_xhinting = 0.5 * (
                1 - 7 / (float(canvas.theme.port_height) / 2))

        if self.m_port_mode == PORT_MODE_INPUT:
            text_pos = QPointF(3, canvas.theme.port_text_ypos)

            if canvas.theme.port_mode == Theme.THEME_PORT_POLYGON:
                poly_locx[0] = lineHinting
                poly_locx[1] = self.m_port_width + 5 - lineHinting
                poly_locx[2] = self.m_port_width + 12 - poly_corner_xhinting
                poly_locx[3] = self.m_port_width + 5 - lineHinting
                poly_locx[4] = lineHinting
            elif canvas.theme.port_mode == Theme.THEME_PORT_SQUARE:
                poly_locx[0] = lineHinting
                poly_locx[1] = self.m_port_width + 5 - lineHinting
                poly_locx[2] = self.m_port_width + 5 - lineHinting
                poly_locx[3] = self.m_port_width + 5 - lineHinting
                poly_locx[4] = lineHinting
            else:
                qCritical(
                    "PatchCanvas::CanvasPort.paint() - invalid theme port mode '%s'"
                    % canvas.theme.port_mode)
                return

        elif self.m_port_mode == PORT_MODE_OUTPUT:
            text_pos = QPointF(9, canvas.theme.port_text_ypos)

            if canvas.theme.port_mode == Theme.THEME_PORT_POLYGON:
                poly_locx[0] = self.m_port_width + 12 - lineHinting
                poly_locx[1] = 7 + lineHinting
                poly_locx[2] = 0 + poly_corner_xhinting
                poly_locx[3] = 7 + lineHinting
                poly_locx[4] = self.m_port_width + 12 - lineHinting
            elif canvas.theme.port_mode == Theme.THEME_PORT_SQUARE:
                poly_locx[0] = self.m_port_width + 12 - lineHinting
                poly_locx[1] = 5 + lineHinting
                poly_locx[2] = 5 + lineHinting
                poly_locx[3] = 5 + lineHinting
                poly_locx[4] = self.m_port_width + 12 - lineHinting
            else:
                qCritical(
                    "PatchCanvas::CanvasPort.paint() - invalid theme port mode '%s'"
                    % canvas.theme.port_mode)
                return

        else:
            qCritical(
                "PatchCanvas::CanvasPort.paint() - invalid port mode '%s'" %
                port_mode2str(self.m_port_mode))
            return

        polygon = QPolygonF()
        polygon += QPointF(poly_locx[0], lineHinting)
        polygon += QPointF(poly_locx[1], lineHinting)
        polygon += QPointF(poly_locx[2], float(canvas.theme.port_height) / 2)
        polygon += QPointF(poly_locx[3],
                           canvas.theme.port_height - lineHinting)
        polygon += QPointF(poly_locx[4],
                           canvas.theme.port_height - lineHinting)
        polygon += QPointF(poly_locx[0], lineHinting)

        if canvas.theme.port_bg_pixmap:
            portRect = polygon.boundingRect().adjusted(-lineHinting + 1,
                                                       -lineHinting + 1,
                                                       lineHinting - 1,
                                                       lineHinting - 1)
            portPos = portRect.topLeft()
            painter.drawTiledPixmap(portRect, canvas.theme.port_bg_pixmap,
                                    portPos)
        else:
            painter.setBrush(poly_color)  #.lighter(200))

        painter.setPen(poly_pen)
        painter.drawPolygon(polygon)

        painter.setPen(text_pen)
        painter.setFont(self.m_port_font)
        painter.drawText(text_pos, self.m_port_name)

        if canvas.theme.idx == Theme.THEME_OOSTUDIO and canvas.theme.port_bg_pixmap:
            conn_pen.setCosmetic(True)
            conn_pen.setWidthF(0.4)
            painter.setPen(conn_pen)

            if self.m_port_mode == PORT_MODE_INPUT:
                connLineX = portRect.left() + 1
            else:
                connLineX = portRect.right() - 1
            conn_path = QPainterPath()
            conn_path.addRect(
                QRectF(connLineX - 1, portRect.top(), 2, portRect.height()))
            painter.fillPath(conn_path, conn_pen.brush())
            painter.drawLine(
                QLineF(connLineX, portRect.top(), connLineX,
                       portRect.bottom()))

        painter.restore()
Esempio n. 4
0
class CollapseExpandButton(QPushButton):
    def _buildPainterPaths(self, size):
        marginLR = int(math.floor((size.width() * 0.3) + 0.5))
        marginUD = int(math.floor((size.height() * 0.3) + 0.5))
        middleColl = int(math.floor((size.height() / 2.0) + 0.5))
        middleExpd = int(math.floor((size.width() / 2.0) + 0.5))

        self._collapsedPath = QPainterPath(
            QPointF(size.width() - marginLR, marginUD))
        self._collapsedPath.lineTo(marginLR, middleColl)
        self._collapsedPath.lineTo(size.width() - marginLR,
                                   size.height() - marginUD)

        self._expandedPath = QPainterPath(QPointF(marginLR, marginUD))
        self._expandedPath.lineTo(middleExpd, size.height() - marginUD)
        self._expandedPath.lineTo(size.width() - marginLR, marginUD)

    @pyqtSlot()
    def _onClicked(self):
        if self._currentState == State.COLLAPSED:
            self._currentState = State.EXPANDED
            self.collapsedExpanded.emit(Transition.EXPAND)
        elif self._currentState == State.EXPANDED:
            self._currentState = State.COLLAPSED
            self.collapsedExpanded.emit(Transition.COLLAPSE)

        super().update()

    def __init__(self, parent=None):
        super().__init__(parent)
        super().setText('')
        self._currentState = State.EXPANDED

        pal = self.palette()
        self._pen = QPen(pal.color(QPalette.WindowText))
        self._pen.setWidth(2)

        self._collapsedPath = None
        self._expandedPath = None
        self._buildPainterPaths(self.size())

        self.clicked.connect(self._onClicked)

    collapsedExpanded = pyqtSignal(Transition)

    def paintEvent(self, ev):
        super().paintEvent(ev)

        p = QPainter(self)
        p.setPen(self._pen)
        p.setRenderHint(QPainter.Antialiasing, True)

        if self._currentState == State.COLLAPSED:
            p.fillPath(self._collapsedPath, self._pen.brush())
        elif self._currentState == State.EXPANDED:
            p.fillPath(self._expandedPath, self._pen.brush())

    def resizeEvent(self, ev):
        self._buildPainterPaths(ev.size())

    def setState(self, state):
        self._currentState = state
        self.repaint()

    def state(self):
        return self._currentState
Esempio n. 5
0
    def paint(self, painter, option, widget):
        if canvas.scene.loading_items:
            return

        painter.save()
        painter.setRenderHint(QPainter.Antialiasing,
                              bool(options.antialiasing == ANTIALIASING_FULL))

        selected = self.isSelected()
        theme = canvas.theme
        if self.m_port_type == PORT_TYPE_AUDIO_JACK:
            if self.m_is_alternate:
                poly_color = theme.port_cv_jack_bg_sel if selected else theme.port_cv_jack_bg
                poly_pen = theme.port_cv_jack_pen_sel if selected else theme.port_cv_jack_pen
            else:
                poly_color = theme.port_audio_jack_bg_sel if selected else theme.port_audio_jack_bg
                poly_pen = theme.port_audio_jack_pen_sel if selected else theme.port_audio_jack_pen
            text_pen = theme.port_audio_jack_text_sel if selected else theme.port_audio_jack_text
            conn_pen = QPen(theme.port_audio_jack_pen_sel)
        elif self.m_port_type == PORT_TYPE_MIDI_JACK:
            poly_color = theme.port_midi_jack_bg_sel if selected else theme.port_midi_jack_bg
            poly_pen = theme.port_midi_jack_pen_sel if selected else theme.port_midi_jack_pen
            text_pen = theme.port_midi_jack_text_sel if selected else theme.port_midi_jack_text
            conn_pen = QPen(theme.port_midi_jack_pen_sel)
        elif self.m_port_type == PORT_TYPE_MIDI_ALSA:
            poly_color = theme.port_midi_alsa_bg_sel if selected else theme.port_midi_alsa_bg
            poly_pen = theme.port_midi_alsa_pen_sel if selected else theme.port_midi_alsa_pen
            text_pen = theme.port_midi_alsa_text_sel if selected else theme.port_midi_alsa_text
            conn_pen = QPen(theme.port_midi_alsa_pen_sel)
        elif self.m_port_type == PORT_TYPE_PARAMETER:
            poly_color = theme.port_parameter_bg_sel if selected else theme.port_parameter_bg
            poly_pen = theme.port_parameter_pen_sel if selected else theme.port_parameter_pen
            text_pen = theme.port_parameter_text_sel if selected else theme.port_parameter_text
            conn_pen = QPen(theme.port_parameter_pen_sel)
        else:
            qCritical(
                "PatchCanvas::CanvasPort.paint() - invalid port type '%s'" %
                port_type2str(self.m_port_type))
            return

        # To prevent quality worsening
        poly_pen = QPen(poly_pen)
        poly_pen.setWidthF(poly_pen.widthF() + 0.00001)

        lineHinting = poly_pen.widthF() / 2

        poly_locx = [0, 0, 0, 0, 0, 0]
        poly_corner_xhinting = ((float(canvas.theme.port_height) / 2) %
                                floor(float(canvas.theme.port_height) / 2))
        if poly_corner_xhinting == 0:
            poly_corner_xhinting = 0.5 * (
                1 - 7 / (float(canvas.theme.port_height) / 2))

        is_cv_port = bool(self.m_port_type == PORT_TYPE_AUDIO_JACK
                          and self.m_is_alternate)

        if self.m_port_mode == PORT_MODE_INPUT:
            text_pos = QPointF(3, canvas.theme.port_text_ypos)

            if canvas.theme.port_mode == Theme.THEME_PORT_POLYGON and not is_cv_port:
                poly_locx[0] = lineHinting
                poly_locx[1] = self.m_port_width + 5 - lineHinting
                poly_locx[2] = self.m_port_width + 12 - poly_corner_xhinting
                poly_locx[3] = self.m_port_width + 5 - lineHinting
                poly_locx[4] = lineHinting
                poly_locx[5] = self.m_port_width
            elif canvas.theme.port_mode == Theme.THEME_PORT_SQUARE or is_cv_port:
                poly_locx[0] = lineHinting
                poly_locx[1] = self.m_port_width + 5 - lineHinting
                poly_locx[2] = self.m_port_width + 5 - lineHinting
                poly_locx[3] = self.m_port_width + 5 - lineHinting
                poly_locx[4] = lineHinting
                poly_locx[5] = self.m_port_width
            else:
                qCritical(
                    "PatchCanvas::CanvasPort.paint() - invalid theme port mode '%s'"
                    % canvas.theme.port_mode)
                return

        elif self.m_port_mode == PORT_MODE_OUTPUT:
            text_pos = QPointF(9, canvas.theme.port_text_ypos)

            if canvas.theme.port_mode == Theme.THEME_PORT_POLYGON and not is_cv_port:
                poly_locx[0] = self.m_port_width + 12 - lineHinting
                poly_locx[1] = 7 + lineHinting
                poly_locx[2] = 0 + poly_corner_xhinting
                poly_locx[3] = 7 + lineHinting
                poly_locx[4] = self.m_port_width + 12 - lineHinting
                poly_locx[5] = 12 - lineHinting
            elif canvas.theme.port_mode == Theme.THEME_PORT_SQUARE or is_cv_port:
                poly_locx[0] = self.m_port_width + 12 - lineHinting
                poly_locx[1] = 5 + lineHinting
                poly_locx[2] = 5 + lineHinting
                poly_locx[3] = 5 + lineHinting
                poly_locx[4] = self.m_port_width + 12 - lineHinting
                poly_locx[5] = 12 - lineHinting
            else:
                qCritical(
                    "PatchCanvas::CanvasPort.paint() - invalid theme port mode '%s'"
                    % canvas.theme.port_mode)
                return

        else:
            qCritical(
                "PatchCanvas::CanvasPort.paint() - invalid port mode '%s'" %
                port_mode2str(self.m_port_mode))
            return

        polygon = QPolygonF()

        if self.m_portgrp_id:
            first_of_portgrp = False
            last_of_portgrp = False

            # look in portgroup if port is the first,
            # the last, or not.
            for portgrp in canvas.portgrp_list:
                if portgrp.portgrp_id == self.m_portgrp_id:
                    if self.m_port_id == portgrp.port_id_list[0]:
                        first_of_portgrp = True
                    if self.m_port_id == portgrp.port_id_list[-1]:
                        last_of_portgrp = True
                    break

            if first_of_portgrp:
                polygon += QPointF(poly_locx[0], lineHinting)
                polygon += QPointF(poly_locx[5], lineHinting)
            else:
                polygon += QPointF(poly_locx[0], 0)
                polygon += QPointF(poly_locx[5], 0)

            if last_of_portgrp:
                polygon += QPointF(poly_locx[5],
                                   canvas.theme.port_height - lineHinting)
                polygon += QPointF(poly_locx[0],
                                   canvas.theme.port_height - lineHinting)
            else:
                polygon += QPointF(poly_locx[5], canvas.theme.port_height)
                polygon += QPointF(poly_locx[0], canvas.theme.port_height)
        else:
            polygon += QPointF(poly_locx[0], lineHinting)
            polygon += QPointF(poly_locx[1], lineHinting)
            polygon += QPointF(poly_locx[2],
                               float(canvas.theme.port_height) / 2)
            polygon += QPointF(poly_locx[3],
                               canvas.theme.port_height - lineHinting)
            polygon += QPointF(poly_locx[4],
                               canvas.theme.port_height - lineHinting)
            polygon += QPointF(poly_locx[0], lineHinting)

        if canvas.theme.port_bg_pixmap:
            portRect = polygon.boundingRect().adjusted(-lineHinting + 1,
                                                       -lineHinting + 1,
                                                       lineHinting - 1,
                                                       lineHinting - 1)
            portPos = portRect.topLeft()
            painter.drawTiledPixmap(portRect, canvas.theme.port_bg_pixmap,
                                    portPos)
        else:
            port_gradient = QLinearGradient(0, 0, 0, self.m_port_height)

            dark_color = poly_color.darker(112)
            light_color = poly_color.lighter(111)

            if poly_color.lightness() > 127:
                port_gradient.setColorAt(0, dark_color)
                port_gradient.setColorAt(0.5, light_color)
                port_gradient.setColorAt(1, dark_color)
            else:
                port_gradient.setColorAt(0, light_color)
                port_gradient.setColorAt(0.5, dark_color)
                port_gradient.setColorAt(1, light_color)
            painter.setBrush(port_gradient)

        painter.setPen(poly_pen)
        painter.drawPolygon(polygon)

        if self.m_is_alternate and not self.m_portgrp_id:
            if is_cv_port:
                poly_pen.setWidthF(2.000001)
                painter.setPen(poly_pen)

                y_line = canvas.theme.port_height / 2.0
                if self.m_port_mode == PORT_MODE_OUTPUT:
                    painter.drawLine(QPointF(0.0, y_line),
                                     QPointF(float(poly_locx[1]), y_line))
                elif self.m_port_mode == PORT_MODE_INPUT:
                    painter.drawLine(QPointF(self.m_port_width + 5.0, y_line),
                                     QPointF(self.m_port_width + 12.0, y_line))
            else:
                # draw the little circle for a2j (or MidiBridge) port
                poly_pen.setWidthF(1.000001)
                painter.setBrush(canvas.theme.box_bg_1)

                ellipse_x = poly_locx[1]
                if self.m_port_mode == PORT_MODE_OUTPUT:
                    ellipse_x -= 2
                elif self.m_port_mode == PORT_MODE_INPUT:
                    ellipse_x += 2

                painter.drawEllipse(
                    QPointF(ellipse_x, canvas.theme.port_height / 2.0), 2, 2)

        painter.setPen(text_pen)
        painter.setFont(self.m_port_font)

        sizer = QFontMetrics(self.m_port_font)
        sep_width = sizer.width(self.m_trunck_sep)

        if self.m_portgrp_id:
            print_name_size = self.get_text_width()

            if self.m_port_mode == PORT_MODE_OUTPUT:
                text_pos = QPointF(self.m_port_width + 9 - print_name_size,
                                   canvas.theme.port_text_ypos)

            if print_name_size > (self.m_port_width - 4):
                painter.setPen(QPen(port_gradient, 3))
                painter.drawLine(
                    QPointF(float(poly_locx[5]), 3.0),
                    QPointF(float(poly_locx[5]),
                            canvas.theme.port_height - 3.0))
                painter.setPen(text_pen)
                painter.setFont(self.m_port_font)

        painter.drawText(text_pos, self.m_print_name)

        if self.m_name_truncked:
            sep_x = text_pos.x() + sizer.width(self.m_print_name)

            painter.drawText(QPointF(sep_x + sep_width, text_pos.y()),
                             self.m_print_name_right)
            painter.setPen(poly_pen)
            painter.drawText(QPointF(sep_x,
                                     text_pos.y() + 1), self.m_trunck_sep)

        if canvas.theme.idx == Theme.THEME_OOSTUDIO and canvas.theme.port_bg_pixmap:
            painter.setPen(Qt.NoPen)
            painter.setBrush(conn_pen.brush())

            if self.m_port_mode == PORT_MODE_INPUT:
                connRect = QRectF(portRect.topLeft(),
                                  QSizeF(2, portRect.height()))
            else:
                connRect = QRectF(
                    QPointF(portRect.right() - 2, portRect.top()),
                    QSizeF(2, portRect.height()))

            painter.drawRect(connRect)

        painter.restore()