Beispiel #1
0
    def _updateButtons(self):
        """
        Update button icons.
        """
        sz = QSize(32, 32)
        if self.orientation() == Qt.Vertical:
            sz.setHeight(sz.height() / 2)
        pix = QPixmap(sz)
        pix.fill(Qt.transparent)
        pnt = QPainter(pix)
        pnt.setPen(Qt.black)

        path = QPainterPath()
        arrowwidth = pix.width() - 2 * 2
        arrowheight = min(arrowwidth / 2, pix.height() - 2 * 2)
        path.moveTo((pix.width() - arrowwidth) / 2,
                    (pix.height() - arrowheight) / 2)
        path.lineTo((pix.width() + arrowwidth) / 2,
                    (pix.height() - arrowheight) / 2)
        path.lineTo(pix.width() / 2, (pix.height() + arrowheight) / 2)
        path.lineTo((pix.width() - arrowwidth) / 2,
                    (pix.height() - arrowheight) / 2)
        pnt.fillPath(path, Qt.black)
        pnt.end()

        self._inc.setIcon(QIcon(pix))
        self._dec.setIcon(QIcon(QPixmap.fromImage(pix.toImage().mirrored())))
Beispiel #2
0
    def __init__(self, gui):
        QWidget.__init__(self, gui)
        self.setObjectName('jobs_pointer')
        self.setVisible(False)
        self.resize(100, 80)
        self.animation = QPropertyAnimation(self, "geometry", self)
        self.animation.setDuration(750)
        self.animation.setLoopCount(2)
        self.animation.setEasingCurve(QEasingCurve.Linear)
        self.animation.finished.connect(self.hide)

        taily, heady = 0, 55
        self.arrow_path = QPainterPath(QPointF(40, taily))
        self.arrow_path.lineTo(40, heady)
        self.arrow_path.lineTo(20, heady)
        self.arrow_path.lineTo(50, self.height())
        self.arrow_path.lineTo(80, heady)
        self.arrow_path.lineTo(60, heady)
        self.arrow_path.lineTo(60, taily)
        self.arrow_path.closeSubpath()

        c = self.palette().color(QPalette.Active, QPalette.WindowText)
        self.color = QColor(c)
        self.color.setAlpha(100)
        self.brush = QBrush(self.color, Qt.SolidPattern)
Beispiel #3
0
 def _create_crop_elements(self):
     cw, ch, _ = self._crop_size
     path = QPainterPath()
     path.moveTo(0, ch)
     path.lineTo(cw / 2, 0)
     path.lineTo(cw, ch)
     path.lineTo(0, ch)
     self._crop_path = path
     self._crop_brush = QBrush(self.palette().light().color())
Beispiel #4
0
 def paint_background(self, painter):
     br = 12  # border_radius
     bw = 1  # border_width
     c = QColor('#fdfd96')
     p = QPainterPath()
     p.addRoundedRect(QRectF(self.rect()), br, br)
     painter.fillPath(p, c)
     p.addRoundedRect(QRectF(self.rect()).adjusted(bw, bw, -bw, -bw), br, br)
     painter.fillPath(p, QColor('black'))
Beispiel #5
0
 def paint(self, painter, option, index):
     QStyledItemDelegate.paint(self, painter, option, index)
     hovering = index.data(HOVER_ROLE) is True
     painter.save()
     rect = option.rect
     is_current = index.data(Qt.FontRole) is not None
     if not hovering and is_current:
         qpp = QPainterPath()
         qpp.addRoundedRect(QRectF(rect), 6, 6)
         painter.fillPath(qpp, self.current_background)
     icon_rect = QRect(rect.left() + self.MARGIN, rect.top() + self.MARGIN, ICON_SIZE, ICON_SIZE)
     left = icon_rect.right() + 2 * self.MARGIN
     text_rect = QRect(left, icon_rect.top(), rect.width() - left + rect.left(), icon_rect.height())
     mark = index.data(MARK_ROLE)
     if hovering or mark:
         text_rect.adjust(0, 0, -text_rect.height(), 0)
     text = index.data(DISPLAY_ROLE) or ''
     font = index.data(Qt.FontRole)
     if font:
         painter.setFont(font)
     text_flags = Qt.AlignVCenter | Qt.AlignLeft | Qt.TextSingleLine
     text = elided_text(text, font, text_rect.width(), 'right')
     if option.state & QStyle.State_Selected:
         painter.setPen(QPen(self.highlighted_text))
     painter.drawText(text_rect, text_flags, text)
     if mark:
         hrect = QRect(text_rect.right(), text_rect.top(), text_rect.height(), text_rect.height())
         painter.fillRect(hrect, QColor('#ffffaa'))
         painter.drawText(hrect, Qt.AlignCenter, mark)
     elif hovering:
         hrect = QRect(text_rect.right(), text_rect.top(), text_rect.height(), text_rect.height())
         close_hover = index.data(CLOSE_HOVER_ROLE) is True
         if close_hover:
             pen = painter.pen()
             pen.setColor(QColor('red'))
             painter.setPen(pen)
         painter.drawText(hrect, Qt.AlignCenter, '✖ ')
     if index.data(LOADING_ROLE):
         if not self.errored_out:
             angle = index.data(ANGLE_ROLE)
             try:
                 draw_snake_spinner(painter, icon_rect, angle, self.light, self.dark)
             except Exception:
                 import traceback
                 traceback.print_exc()
                 self.errored_out = True
     else:
         icurl = index.data(URL_ROLE)
         if icurl == WELCOME_URL:
             icon = welcome_icon()
         elif icurl == DOWNLOADS_URL:
             icon = downloads_icon()
         else:
             icon = index.data(DECORATION_ROLE)
         icon.paint(painter, icon_rect)
     painter.restore()
Beispiel #6
0
 def create_line(ly, ry, right_to_left=False):
     ' Create path that represents upper or lower line of change marker '
     line = QPainterPath()
     if not right_to_left:
         line.moveTo(0, ly)
         line.cubicTo(C, ly, w - C, ry, w, ry)
     else:
         line.moveTo(w, ry)
         line.cubicTo(w - C, ry, C, ly, 0, ly)
     return line
Beispiel #7
0
 def paint_background(self, painter):
     br = 12  # border_radius
     bw = 1  # border_width
     pal = self.palette()
     c = pal.color(pal.Window)
     c.setAlphaF(0.9)
     p = QPainterPath()
     p.addRoundedRect(QRectF(self.rect()), br, br)
     painter.fillPath(p, c)
     p.addRoundedRect(QRectF(self.rect()).adjusted(bw, bw, -bw, -bw), br, br)
     painter.fillPath(p, pal.color(pal.WindowText))
Beispiel #8
0
 def draw_fold(x, m=1, corner=left_corner):
     ans = p = QPainterPath(QPointF(x, rtop))
     draw_curved_line(p, rwidth*m, 0, 0.1, 0.1*m, 0.5, -0.2*m)
     fold_upper = p.currentPosition()
     p.lineTo(p.currentPosition() + QPointF(-deltax*m, height))
     fold_corner = p.currentPosition()
     draw_curved_line(p, -rwidth*m, 0, 0.2, -0.1*m, 0.8, -0.1*m)
     draw_curved_line(p, deltax*m, -height, 0.2, 0.1*m, 0.8, 0.1*m)
     p = inner_fold = QPainterPath(corner)
     dp = fold_corner - p.currentPosition()
     draw_curved_line(p, dp.x(), dp.y(), 0.5, 0.3*m, 1, 0*m)
     p.lineTo(fold_upper), p.closeSubpath()
     return ans, inner_fold
Beispiel #9
0
def full(p, xmax, ymax):
    p.drawRect(0, 0, xmax, ymax)
    p.drawPolyline(QPoint(0, 0), QPoint(xmax, 0), QPoint(xmax, ymax),
                    QPoint(0, ymax), QPoint(0, 0))
    pp = QPainterPath()
    pp.addRect(0, 0, xmax, ymax)
    p.drawPath(pp)
    p.save()
    for i in range(3):
        col = [0, 0, 0, 200]
        col[i] = 255
        p.setOpacity(0.3)
        p.fillRect(0, 0, xmax/10, xmax/10, QBrush(QColor(*col)))
        p.setOpacity(1)
        p.drawRect(0, 0, xmax/10, xmax/10)
        p.translate(xmax/10, xmax/10)
        p.scale(1, 1.5)
    p.restore()

    # p.scale(2, 2)
    # p.rotate(45)
    p.drawPixmap(0, 0, xmax/4, xmax/4, QPixmap(I('library.png')))
    p.drawRect(0, 0, xmax/4, xmax/4)

    f = p.font()
    f.setPointSize(20)
    # f.setLetterSpacing(f.PercentageSpacing, 200)
    f.setUnderline(True)
    # f.setOverline(True)
    # f.setStrikeOut(True)
    f.setFamily('Calibri')
    p.setFont(f)
    # p.setPen(QColor(0, 0, 255))
    # p.scale(2, 2)
    # p.rotate(45)
    p.drawText(QPoint(xmax/3.9, 30), 'Some—text not By’s ū --- Д AV ff ff')

    b = QBrush(Qt.HorPattern)
    b.setColor(QColor(Qt.blue))
    pix = QPixmap(I('lt.png'))
    w = xmax/4
    p.fillRect(0, ymax/3, w, w, b)
    p.fillRect(xmax/3, ymax/3, w, w, QBrush(pix))
    x, y = 2*xmax/3, ymax/3
    p.drawTiledPixmap(QRectF(x, y, w, w), pix, QPointF(10, 10))

    x, y = 1, ymax/1.9
    g = QLinearGradient(QPointF(x, y), QPointF(x+w, y+w))
    g.setColorAt(0, QColor('#00f'))
    g.setColorAt(1, QColor('#fff'))
    p.fillRect(x, y, w, w, QBrush(g))
Beispiel #10
0
 def create_line(ly, ry, right_to_left=False):
     ' Create path that represents upper or lower line of change marker '
     line = QPainterPath()
     if not right_to_left:
         line.moveTo(0, ly)
         line.cubicTo(C, ly, w - C, ry, w, ry)
     else:
         line.moveTo(w, ry)
         line.cubicTo(w - C, ry, C, ly, 0, ly)
     return line
Beispiel #11
0
 def __call__(self, painter, rect, color_theme, title_block, subtitle_block, footer_block):
     painter.fillRect(rect, self.color1)
     r = QRect(0, int(title_block.position.y), rect.width(),
               title_block.height + subtitle_block.height + subtitle_block.line_spacing // 2 + title_block.leading)
     painter.save()
     p = QPainterPath()
     p.addRoundedRect(QRectF(r), 10, 10 * r.width()/r.height(), Qt.RelativeSize)
     painter.setClipPath(p)
     painter.setRenderHint(QPainter.Antialiasing)
     painter.fillRect(r, self.color2)
     painter.restore()
     r = QRect(0, 0, int(title_block.position.x), rect.height())
     painter.fillRect(r, self.color2)
     return self.ccolor2, self.ccolor2, self.ccolor1
Beispiel #12
0
 def __call__(self, painter, rect, color_theme, title_block, subtitle_block, footer_block):
     painter.fillRect(rect, self.color1)
     r = QRect(0, int(title_block.position.y), rect.width(),
               title_block.height + subtitle_block.height + subtitle_block.line_spacing // 2 + title_block.leading)
     painter.save()
     p = QPainterPath()
     p.addRoundedRect(QRectF(r), 10, 10 * r.width()/r.height(), Qt.RelativeSize)
     painter.setClipPath(p)
     painter.setRenderHint(QPainter.Antialiasing)
     painter.fillRect(r, self.color2)
     painter.restore()
     r = QRect(0, 0, int(title_block.position.x), rect.height())
     painter.fillRect(r, self.color2)
     return self.ccolor2, self.ccolor2, self.ccolor1
Beispiel #13
0
    def createPixmapForSite(self, icon, title, url):
        '''
        @param: icon QIcon
        @param: title QString
        @param: url QString
        @return: QPixmap
        '''
        fontMetrics = QApplication.fontMetrics()
        padding = 4
        text = len(title) > len(url) and title or url
        maxWidth = fontMetrics.width(text) + 3 * padding + 16
        width = min(maxWidth, 150)
        height = fontMetrics.height() * 2 + fontMetrics.leading() + 2 * padding

        pixelRatio = gVar.app.devicePixelRatio()
        pixmap = QPixmap(width * pixelRatio, height * pixelRatio)
        pixmap.setDevicePixelRatio(pixelRatio)

        painter = QPainter(pixmap)
        painter.setRenderHint(QPainter.Antialiasing)

        # Draw background
        pen = QPen(Qt.black)
        pen.setWidth(1)
        painter.setPen(pen)

        path = QPainterPath()
        path.addRect(QRectF(0, 0, width, height))

        painter.fillPath(path, Qt.white)
        painter.drawPath(path)

        # Draw icon
        iconRect = QRect(padding, 0, 16, height)
        icon.paint(painter, iconRect)

        # Draw title
        titleRect = QRectF(iconRect.right() + padding, padding,
                width - padding - iconRect.right(), fontMetrics.height())
        painter.drawText(titleRect, fontMetrics.elidedText(title, Qt.ElideRight, titleRect.width()))

        # Draw url
        urlRect = QRectF(titleRect.x(), titleRect.bottom() + fontMetrics.leading(),
                titleRect.width(), titleRect.height())
        painter.setPen(QApplication.palette().color(QPalette.Link))
        painter.drawText(urlRect, fontMetrics.elidedText(url, Qt.ElideRight, urlRect.width()))

        return pixmap
Beispiel #14
0
    def __init__(self, gui):
        QWidget.__init__(self, gui)
        self.setObjectName('jobs_pointer')
        self.setVisible(False)
        self.resize(100, 80)
        self.animation = QPropertyAnimation(self, "geometry", self)
        self.animation.setDuration(750)
        self.animation.setLoopCount(2)
        self.animation.setEasingCurve(QEasingCurve.Linear)
        self.animation.finished.connect(self.hide)

        taily, heady = 0, 55
        self.arrow_path = QPainterPath(QPointF(40, taily))
        self.arrow_path.lineTo(40, heady)
        self.arrow_path.lineTo(20, heady)
        self.arrow_path.lineTo(50, self.height())
        self.arrow_path.lineTo(80, heady)
        self.arrow_path.lineTo(60, heady)
        self.arrow_path.lineTo(60, taily)
        self.arrow_path.closeSubpath()

        c = self.palette().color(QPalette.Active, QPalette.WindowText)
        self.color = QColor(c)
        self.color.setAlpha(100)
        self.brush = QBrush(self.color, Qt.SolidPattern)
Beispiel #15
0
    def __call__(self, painter, rect, color_theme, title_block, subtitle_block, footer_block):
        painter.fillRect(rect, self.color1)
        top = title_block.position.y + 2
        extra_spacing = subtitle_block.line_spacing // 2 if subtitle_block.line_spacing else title_block.line_spacing // 3
        height = title_block.height + subtitle_block.height + extra_spacing + title_block.leading
        right = rect.right() - self.hmargin
        width = right - self.hmargin

        # Draw main banner
        p = main = QPainterPath(QPointF(self.hmargin, top))
        draw_curved_line(p, rect.width() - 2 * self.hmargin, 0, 0.1, -0.1, 0.9, -0.1)
        deltax = self.GRADE * height
        p.lineTo(right + deltax, top + height)
        right_corner = p.currentPosition()
        draw_curved_line(p, - width - 2 * deltax, 0, 0.1, 0.05, 0.9, 0.05)
        left_corner = p.currentPosition()
        p.closeSubpath()

        # Draw fold rectangles
        rwidth = self.fold_width
        yfrac = 0.1
        width23 = int(0.67 * rwidth)
        rtop = top + height * yfrac

        def draw_fold(x, m=1, corner=left_corner):
            ans = p = QPainterPath(QPointF(x, rtop))
            draw_curved_line(p, rwidth*m, 0, 0.1, 0.1*m, 0.5, -0.2*m)
            fold_upper = p.currentPosition()
            p.lineTo(p.currentPosition() + QPointF(-deltax*m, height))
            fold_corner = p.currentPosition()
            draw_curved_line(p, -rwidth*m, 0, 0.2, -0.1*m, 0.8, -0.1*m)
            draw_curved_line(p, deltax*m, -height, 0.2, 0.1*m, 0.8, 0.1*m)
            p = inner_fold = QPainterPath(corner)
            dp = fold_corner - p.currentPosition()
            draw_curved_line(p, dp.x(), dp.y(), 0.5, 0.3*m, 1, 0*m)
            p.lineTo(fold_upper), p.closeSubpath()
            return ans, inner_fold

        left_fold, left_inner = draw_fold(self.hmargin - width23)
        right_fold, right_inner = draw_fold(right + width23, m=-1, corner=right_corner)

        painter.save()
        painter.setRenderHint(QPainter.Antialiasing)
        pen = QPen(self.ccolor2)
        pen.setWidth(3)
        pen.setJoinStyle(Qt.RoundJoin)
        painter.setPen(pen)
        for r in (left_fold, right_fold):
            painter.fillPath(r, QBrush(self.color2))
            painter.drawPath(r)
        for r in (left_inner, right_inner):
            painter.fillPath(r, QBrush(self.color2.darker()))
            painter.drawPath(r)
        painter.fillPath(main, QBrush(self.color2))
        painter.drawPath(main)
        painter.restore()
        return self.ccolor2, self.ccolor2, self.ccolor1
Beispiel #16
0
    def _draw_column_data(self, painter, color, xcol,
                        ycol, xmin, xmax, ymin, ymax):

        painter.setPen( QPen(QColor(color), 2,
                        Qt.SolidLine, Qt.RoundCap))

        path = QPainterPath()

        row = self.data.rows[0]
        x, y = self._xy_from_data(row[xcol], row[ycol],
                                xmin, xmax, ymin, ymax)
        path.moveTo(x, y)

        for row in self.data.rows[1:]:
            x, y = self._xy_from_data(row[xcol], row[ycol],
                                    xmin, xmax, ymin, ymax)
            path.lineTo(x, y)
            painter.drawPath(path)
Beispiel #17
0
 def start(self):
     if config['disable_animations']:
         return
     self.setVisible(True)
     self.raise_()
     end = self.abspos(self.gui.jobs_button)
     end = QPointF(end.x() + self.gui.jobs_button.width()/3.0, end.y()+20)
     start = QPointF(end.x(), end.y() - 0.5*self.height())
     self.path = QPainterPath(QPointF(start))
     self.path.lineTo(end)
     self.path.closeSubpath()
     self.animation.setStartValue(self.rect_at(0.0))
     self.animation.setEndValue(self.rect_at(1.0))
     self.animation.setDirection(self.animation.Backward)
     num_keys = 100
     for i in range(1, num_keys):
         i /= num_keys
         self.animation.setKeyValueAt(i, self.rect_at(i))
     self.animation.start()
Beispiel #18
0
    def __call__(self, painter, rect, color_theme, title_block, subtitle_block,
                 footer_block):
        if not self.PATH_CACHE:
            from calibre.utils.speedups import svg_path_to_painter_path
            try:
                self.__class__.PATH_CACHE['corner'] = svg_path_to_painter_path(
                    self.CORNER_VECTOR)
            except Exception:
                import traceback
                traceback.print_exc()
        p = painter
        painter.setRenderHint(QPainter.RenderHint.Antialiasing)
        g = QRadialGradient(QPointF(rect.center()), rect.width())
        g.setColorAt(0, self.color1), g.setColorAt(1, self.color2)
        painter.fillRect(rect, QBrush(g))
        painter.save()
        painter.setWindow(0, 0, *self.VIEWPORT)
        try:
            path = self.PATH_CACHE['corner']
        except KeyError:
            path = QPainterPath()
        pen = p.pen()
        pen.setColor(self.ccolor1)
        p.setPen(pen)

        def corner():
            b = QBrush(self.ccolor1)
            p.fillPath(path, b)
            p.rotate(90), p.translate(100, -100), p.scale(1, -1), p.translate(
                -103, -97)
            p.fillPath(path, b)
            p.setWorldTransform(QTransform())

        # Top-left corner
        corner()
        # Top right corner
        p.scale(-1, 1), p.translate(-400, 0), corner()
        # Bottom left corner
        p.scale(1, -1), p.translate(0, -500), corner()
        # Bottom right corner
        p.scale(-1, -1), p.translate(-400, -500), corner()
        for y in (28.4, 471.7):
            p.drawLine(QPointF(160, y), QPointF(240, y))
        for x in (31.3, 368.7):
            p.drawLine(QPointF(x, 155), QPointF(x, 345))
        pen.setWidthF(1.8)
        p.setPen(pen)
        for y in (23.8, 476.7):
            p.drawLine(QPointF(160, y), QPointF(240, y))
        for x in (26.3, 373.7):
            p.drawLine(QPointF(x, 155), QPointF(x, 345))
        painter.restore()

        return self.ccolor2, self.ccolor2, self.ccolor1
Beispiel #19
0
 def drawContents(self, painter):
     self.drawn_once = True
     painter.save()
     painter.setPen(Qt.black)
     painter.setRenderHint(painter.TextAntialiasing, True)
     painter.setRenderHint(painter.Antialiasing, True)
     f = painter.font()
     f.setPixelSize(18)
     painter.setFont(f)
     t = QTransform()
     t.translate(330, 450)
     painter.setTransform(t)
     painter.rotate(-98)
     if iswindows:
         # On windows Qt cannot anti-alias rotated text
         p = QPainterPath()
         p.addText(0, 0, f, self.message())
         painter.fillPath(p, QBrush(Qt.black))
     else:
         painter.drawText(0, 0, self.message())
     painter.restore()
Beispiel #20
0
    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        painter.drawPixmap(0, 0, self._pixmap)
        painter.fillRect(self.rect(), self.palette().midlight().color())

        round_path = QPainterPath()
        round_path.addRoundedRect(0, 0, self.width(), self.height(), 5, 5)
        sq_path = QPainterPath()
        sq_path.addRect(0, 0, 10, self.height())
        draw_path = sq_path - round_path
        painter.setPen(Qt.NoPen)
        painter.setBrush(self.palette().dark().color())
        painter.drawPath(draw_path)
Beispiel #21
0
 def drawContents(self, painter):
     self.drawn_once = True
     painter.save()
     painter.setPen(Qt.black)
     painter.setRenderHint(painter.TextAntialiasing, True)
     painter.setRenderHint(painter.Antialiasing, True)
     f = painter.font()
     f.setPixelSize(18)
     painter.setFont(f)
     t = QTransform()
     t.translate(330, 450)
     painter.setTransform(t)
     painter.rotate(-98)
     left_margin = 25
     if iswindows:
         # On windows Qt cannot anti-alias rotated text
         p = QPainterPath()
         p.addText(left_margin, 0, f, self.message())
         painter.fillPath(p, QBrush(Qt.black))
     else:
         painter.drawText(left_margin, 0, self.message())
     painter.restore()
Beispiel #22
0
 def paint_background(self, painter):
     br = 12  # border_radius
     bw = 1  # border_width
     c = QColor('#fdfd96')
     p = QPainterPath()
     p.addRoundedRect(QRectF(self.rect()), br, br)
     painter.fillPath(p, c)
     p.addRoundedRect(
         QRectF(self.rect()).adjusted(bw, bw, -bw, -bw), br, br)
     painter.fillPath(p, QColor('black'))
Beispiel #23
0
 def paint_background(self, painter):
     br = 12  # border_radius
     bw = 1  # border_width
     pal = self.palette()
     c = pal.color(QPalette.ColorRole.Window)
     c.setAlphaF(0.9)
     p = QPainterPath()
     p.addRoundedRect(QRectF(self.rect()), br, br)
     painter.fillPath(p, c)
     p.addRoundedRect(QRectF(self.rect()).adjusted(bw, bw, -bw, -bw), br, br)
     painter.fillPath(p, pal.color(QPalette.ColorRole.WindowText))
Beispiel #24
0
    def shape(self):
        '''Defines the selection shape of the item.'''
        stroker = QPainterPathStroker()

        # Tolerance on click to update if needed
        stroker.setWidth(12)

        path = QPainterPath()
        path.moveTo(self.line().p1())
        path.lineTo(self.line().p2())

        return stroker.createStroke(path)
Beispiel #25
0
def wavy_path(width, height, y_origin):
    half_height = height / 2
    path = QPainterPath()
    pi2 = math.pi * 2
    num = 100
    num_waves = 4
    wav_limit = num // num_waves
    sin = math.sin
    path.reserve(num)
    for i in range(num):
        x = width * i / num
        rads = pi2 * (i % wav_limit) / wav_limit
        factor = sin(rads)
        y = y_origin + factor * half_height
        path.lineTo(x, y) if i else path.moveTo(x, y)
    return path
Beispiel #26
0
 def start(self):
     if config['disable_animations']:
         return
     self.setVisible(True)
     self.raise_()
     end = self.abspos(self.gui.jobs_button)
     end = QPointF( end.x() + self.gui.jobs_button.width()/3.0, end.y()+20)
     start = QPointF(end.x(), end.y() - 0.5*self.height())
     self.path = QPainterPath(QPointF(start))
     self.path.lineTo(end)
     self.path.closeSubpath()
     self.animation.setStartValue(self.rect_at(0.0))
     self.animation.setEndValue(self.rect_at(1.0))
     self.animation.setDirection(self.animation.Backward)
     num_keys = 100
     for i in xrange(1, num_keys):
         i /= num_keys
         self.animation.setKeyValueAt(i, self.rect_at(i))
     self.animation.start()
Beispiel #27
0
class Pointer(QWidget):
    def __init__(self, gui):
        QWidget.__init__(self, gui)
        self.setObjectName('jobs_pointer')
        self.setVisible(False)
        self.resize(100, 80)
        self.animation = QPropertyAnimation(self, "geometry", self)
        self.animation.setDuration(750)
        self.animation.setLoopCount(2)
        self.animation.setEasingCurve(QEasingCurve.Linear)
        self.animation.finished.connect(self.hide)

        taily, heady = 0, 55
        self.arrow_path = QPainterPath(QPointF(40, taily))
        self.arrow_path.lineTo(40, heady)
        self.arrow_path.lineTo(20, heady)
        self.arrow_path.lineTo(50, self.height())
        self.arrow_path.lineTo(80, heady)
        self.arrow_path.lineTo(60, heady)
        self.arrow_path.lineTo(60, taily)
        self.arrow_path.closeSubpath()

        c = self.palette().color(QPalette.Active, QPalette.WindowText)
        self.color = QColor(c)
        self.color.setAlpha(100)
        self.brush = QBrush(self.color, Qt.SolidPattern)

        # from PyQt5.Qt import QTimer
        # QTimer.singleShot(1000, self.start)

    @property
    def gui(self):
        return self.parent()

    def point_at(self, frac):
        return (self.path.pointAtPercent(frac).toPoint() -
                QPoint(self.rect().center().x(), self.height()))

    def rect_at(self, frac):
        return QRect(self.point_at(frac), self.size())

    def abspos(self, widget):
        pos = widget.pos()
        parent = widget.parent()
        while parent is not self.gui:
            pos += parent.pos()
            parent = parent.parent()
        return pos

    def start(self):
        if config['disable_animations']:
            return
        self.setVisible(True)
        self.raise_()
        end = self.abspos(self.gui.jobs_button)
        end = QPointF(end.x() + self.gui.jobs_button.width() / 3.0,
                      end.y() + 20)
        start = QPointF(end.x(), end.y() - 0.5 * self.height())
        self.path = QPainterPath(QPointF(start))
        self.path.lineTo(end)
        self.path.closeSubpath()
        self.animation.setStartValue(self.rect_at(0.0))
        self.animation.setEndValue(self.rect_at(1.0))
        self.animation.setDirection(self.animation.Backward)
        num_keys = 100
        for i in xrange(1, num_keys):
            i /= num_keys
            self.animation.setKeyValueAt(i, self.rect_at(i))
        self.animation.start()

    def paintEvent(self, ev):
        p = QPainter(self)
        p.setRenderHints(p.Antialiasing)
        p.setBrush(self.brush)
        p.setPen(Qt.NoPen)
        p.drawPath(self.arrow_path)
        p.end()
Beispiel #28
0
class Pointer(QWidget):

    def __init__(self, gui):
        QWidget.__init__(self, gui)
        self.setObjectName('jobs_pointer')
        self.setVisible(False)
        self.resize(100, 80)
        self.animation = QPropertyAnimation(self, "geometry", self)
        self.animation.setDuration(750)
        self.animation.setLoopCount(2)
        self.animation.setEasingCurve(QEasingCurve.Linear)
        self.animation.finished.connect(self.hide)

        taily, heady = 0, 55
        self.arrow_path = QPainterPath(QPointF(40, taily))
        self.arrow_path.lineTo(40, heady)
        self.arrow_path.lineTo(20, heady)
        self.arrow_path.lineTo(50, self.height())
        self.arrow_path.lineTo(80, heady)
        self.arrow_path.lineTo(60, heady)
        self.arrow_path.lineTo(60, taily)
        self.arrow_path.closeSubpath()

        c = self.palette().color(QPalette.Active, QPalette.WindowText)
        self.color = QColor(c)
        self.color.setAlpha(100)
        self.brush = QBrush(self.color, Qt.SolidPattern)

        # from PyQt5.Qt import QTimer
        # QTimer.singleShot(1000, self.start)

    @property
    def gui(self):
        return self.parent()

    def point_at(self, frac):
        return (self.path.pointAtPercent(frac).toPoint() -
                QPoint(self.rect().center().x(), self.height()))

    def rect_at(self, frac):
        return QRect(self.point_at(frac), self.size())

    def abspos(self, widget):
        pos = widget.pos()
        parent = widget.parent()
        while parent is not self.gui:
            pos += parent.pos()
            parent = parent.parent()
        return pos

    def start(self):
        if config['disable_animations']:
            return
        self.setVisible(True)
        self.raise_()
        end = self.abspos(self.gui.jobs_button)
        end = QPointF( end.x() + self.gui.jobs_button.width()/3.0, end.y()+20)
        start = QPointF(end.x(), end.y() - 0.5*self.height())
        self.path = QPainterPath(QPointF(start))
        self.path.lineTo(end)
        self.path.closeSubpath()
        self.animation.setStartValue(self.rect_at(0.0))
        self.animation.setEndValue(self.rect_at(1.0))
        self.animation.setDirection(self.animation.Backward)
        num_keys = 100
        for i in xrange(1, num_keys):
            i /= num_keys
            self.animation.setKeyValueAt(i, self.rect_at(i))
        self.animation.start()

    def paintEvent(self, ev):
        p = QPainter(self)
        p.setRenderHints(p.Antialiasing)
        p.setBrush(self.brush)
        p.setPen(Qt.NoPen)
        p.drawPath(self.arrow_path)
        p.end()
def svg_path_to_painter_path(d):
    '''
    Convert a tiny SVG 1.2 path into a QPainterPath.

    :param d: The value of the d attribute of an SVG <path> tag
    '''
    from PyQt5.Qt import QPainterPath
    cmd = last_cmd = b''
    path = QPainterPath()
    moveto_abs, moveto_rel = b'M', b'm'
    closepath1, closepath2 = b'Z', b'z'
    lineto_abs, lineto_rel = b'L', b'l'
    hline_abs, hline_rel = b'H', b'h'
    vline_abs, vline_rel = b'V', b'v'
    curveto_abs, curveto_rel = b'C', b'c'
    smoothcurveto_abs, smoothcurveto_rel = b'S', b's'
    quadcurveto_abs, quadcurveto_rel = b'Q', b'q'
    smoothquadcurveto_abs, smoothquadcurveto_rel = b'T', b't'

    # Store the last parsed values
    # x/y = end position
    # x1/y1 and x2/y2 = bezier control points
    x = y = x1 = y1 = x2 = y2 = 0

    if isinstance(d, unicode_type):
        d = d.encode('ascii')
    d = d.replace(b',', b' ').replace(b'\n', b' ')
    end = len(d)
    pos = [0]

    def read_byte():
        p = pos[0]
        pos[0] += 1
        return d[p:p + 1]

    def parse_float():
        chars = []
        while pos[0] < end:
            c = read_byte()
            if c == b' ' and not chars:
                continue
            if c in b'-.0123456789':
                chars.append(c)
            else:
                break
        if not chars:
            raise ValueError('Premature end of input while expecting a number')
        return float(b''.join(chars))

    def parse_floats(num, x_offset=0, y_offset=0):
        for i in range(num):
            val = parse_float()
            yield val + (x_offset if i % 2 == 0 else y_offset)

    repeated_command = None

    while pos[0] < end:
        last_cmd = cmd
        cmd = read_byte() if repeated_command is None else repeated_command
        repeated_command = None

        if cmd == b' ':
            continue
        if cmd == moveto_abs:
            x, y = parse_float(), parse_float()
            path.moveTo(x, y)
        elif cmd == moveto_rel:
            x += parse_float()
            y += parse_float()
            path.moveTo(x, y)
        elif cmd == closepath1 or cmd == closepath2:
            path.closeSubpath()
        elif cmd == lineto_abs:
            x, y = parse_floats(2)
            path.lineTo(x, y)
        elif cmd == lineto_rel:
            x += parse_float()
            y += parse_float()
            path.lineTo(x, y)
        elif cmd == hline_abs:
            x = parse_float()
            path.lineTo(x, y)
        elif cmd == hline_rel:
            x += parse_float()
            path.lineTo(x, y)
        elif cmd == vline_abs:
            y = parse_float()
            path.lineTo(x, y)
        elif cmd == vline_rel:
            y += parse_float()
            path.lineTo(x, y)
        elif cmd == curveto_abs:
            x1, y1, x2, y2, x, y = parse_floats(6)
            path.cubicTo(x1, y1, x2, y2, x, y)
        elif cmd == curveto_rel:
            x1, y1, x2, y2, x, y = parse_floats(6, x, y)
            path.cubicTo(x1, y1, x2, y2, x, y)
        elif cmd == smoothcurveto_abs:
            if last_cmd == curveto_abs or last_cmd == curveto_rel or last_cmd == smoothcurveto_abs or last_cmd == smoothcurveto_rel:
                x1 = 2 * x - x2
                y1 = 2 * y - y2
            else:
                x1, y1 = x, y
            x2, y2, x, y = parse_floats(4)
            path.cubicTo(x1, y1, x2, y2, x, y)
        elif cmd == smoothcurveto_rel:
            if last_cmd == curveto_abs or last_cmd == curveto_rel or last_cmd == smoothcurveto_abs or last_cmd == smoothcurveto_rel:
                x1 = 2 * x - x2
                y1 = 2 * y - y2
            else:
                x1, y1 = x, y
            x2, y2, x, y = parse_floats(4, x, y)
            path.cubicTo(x1, y1, x2, y2, x, y)
        elif cmd == quadcurveto_abs:
            x1, y1, x, y = parse_floats(4)
            path.quadTo(x1, y1, x, y)
        elif cmd == quadcurveto_rel:
            x1, y1, x, y = parse_floats(4, x, y)
            path.quadTo(x1, y1, x, y)
        elif cmd == smoothquadcurveto_abs:
            if last_cmd in (quadcurveto_abs, quadcurveto_rel,
                            smoothquadcurveto_abs, smoothquadcurveto_rel):
                x1 = 2 * x - x1
                y1 = 2 * y - y1
            else:
                x1, y1 = x, y
            x, y = parse_floats(2)
            path.quadTo(x1, y1, x, y)
        elif cmd == smoothquadcurveto_rel:
            if last_cmd in (quadcurveto_abs, quadcurveto_rel,
                            smoothquadcurveto_abs, smoothquadcurveto_rel):
                x1 = 2 * x - x1
                y1 = 2 * y - y1
            else:
                x1, y1 = x, y
            x, y = parse_floats(2, x, y)
            path.quadTo(x1, y1, x, y)
        elif cmd in b'-.0123456789':
            # A new number begins
            # In this case, multiple parameters tuples are specified for the last command
            # We rewind to reparse data correctly
            pos[0] -= 1

            # Handle extra parameters
            if last_cmd == moveto_abs:
                repeated_command = cmd = lineto_abs
            elif last_cmd == moveto_rel:
                repeated_command = cmd = lineto_rel
            elif last_cmd in (closepath1, closepath2):
                raise ValueError('Extra parameters after close path command')
            elif last_cmd in (lineto_abs, lineto_rel, hline_abs, hline_rel,
                              vline_abs, vline_rel, curveto_abs, curveto_rel,
                              smoothcurveto_abs, smoothcurveto_rel,
                              quadcurveto_abs, quadcurveto_rel,
                              smoothquadcurveto_abs, smoothquadcurveto_rel):
                repeated_command = cmd = last_cmd
        else:
            raise ValueError('Unknown path command: %s' % cmd)
    return path
Beispiel #30
0
    def paintEvent(self, event):
        QSplitterHandle.paintEvent(self, event)
        left, right = self.parent().left, self.parent().right
        painter = QPainter(self)
        painter.setClipRect(event.rect())
        w = self.width()
        h = self.height()
        painter.setRenderHints(QPainter.Antialiasing, True)

        C = 16  # Curve factor.

        def create_line(ly, ry, right_to_left=False):
            ' Create path that represents upper or lower line of change marker '
            line = QPainterPath()
            if not right_to_left:
                line.moveTo(0, ly)
                line.cubicTo(C, ly, w - C, ry, w, ry)
            else:
                line.moveTo(w, ry)
                line.cubicTo(w - C, ry, C, ly, 0, ly)
            return line

        ldoc, rdoc = left.document(), right.document()
        lorigin, rorigin = left.contentOffset(), right.contentOffset()
        lfv, rfv = left.firstVisibleBlock().blockNumber(), right.firstVisibleBlock().blockNumber()
        lines = []

        for (ltop, lbot, kind), (rtop, rbot, kind) in zip(left.changes, right.changes):
            if lbot < lfv and rbot < rfv:
                continue
            ly_top = left.blockBoundingGeometry(ldoc.findBlockByNumber(ltop)).translated(lorigin).y()
            ly_bot = left.blockBoundingGeometry(ldoc.findBlockByNumber(lbot)).translated(lorigin).y()
            ry_top = right.blockBoundingGeometry(rdoc.findBlockByNumber(rtop)).translated(rorigin).y()
            ry_bot = right.blockBoundingGeometry(rdoc.findBlockByNumber(rbot)).translated(rorigin).y()
            if max(ly_top, ly_bot, ry_top, ry_bot) < 0:
                continue
            if min(ly_top, ly_bot, ry_top, ry_bot) > h:
                break

            upper_line = create_line(ly_top, ry_top)
            lower_line = create_line(ly_bot, ry_bot, True)

            region = QPainterPath()
            region.moveTo(0, ly_top)
            region.connectPath(upper_line)
            region.lineTo(w, ry_bot)
            region.connectPath(lower_line)
            region.closeSubpath()

            painter.fillPath(region, left.diff_backgrounds[kind])
            for path, aa in zip((upper_line, lower_line), (ly_top != ry_top, ly_bot != ry_bot)):
                lines.append((kind, path, aa))

        for kind, path, aa in sorted(lines, key=lambda x:{'replace':0}.get(x[0], 1)):
            painter.setPen(left.diff_foregrounds[kind])
            painter.setRenderHints(QPainter.Antialiasing, aa)
            painter.drawPath(path)

        painter.setFont(left.heading_font)
        for (lnum, text), (rnum, text) in zip(left.headers, right.headers):
            ltop, lbot, rtop, rbot = lnum, lnum + 3, rnum, rnum + 3
            if lbot < lfv and rbot < rfv:
                continue
            ly_top = left.blockBoundingGeometry(ldoc.findBlockByNumber(ltop)).translated(lorigin).y()
            ly_bot = left.blockBoundingGeometry(ldoc.findBlockByNumber(lbot)).translated(lorigin).y()
            ry_top = right.blockBoundingGeometry(rdoc.findBlockByNumber(rtop)).translated(rorigin).y()
            ry_bot = right.blockBoundingGeometry(rdoc.findBlockByNumber(rbot)).translated(rorigin).y()
            if max(ly_top, ly_bot, ry_top, ry_bot) < 0:
                continue
            if min(ly_top, ly_bot, ry_top, ry_bot) > h:
                break
            ly = painter.boundingRect(3, ly_top, left.width(), ly_bot - ly_top - 5, Qt.TextSingleLine, text).bottom() + 3
            ry = painter.boundingRect(3, ry_top, right.width(), ry_bot - ry_top - 5, Qt.TextSingleLine, text).bottom() + 3
            line = create_line(ly, ry)
            painter.setPen(QPen(left.palette().text(), 2))
            painter.setRenderHints(QPainter.Antialiasing, ly != ry)
            painter.drawPath(line)

        painter.end()
        # Paint the splitter without the change lines if the mouse is over the
        # splitter
        if getattr(self, 'hover', False):
            QSplitterHandle.paintEvent(self, event)
Beispiel #31
0
def svg_path_to_painter_path(d):
    '''
    Convert a tiny SVG 1.2 path into a QPainterPath.

    :param d: The value of the d attribute of an SVG <path> tag
    '''
    from PyQt5.Qt import QPainterPath
    cmd = last_cmd = b''
    path = QPainterPath()
    moveto_abs, moveto_rel = b'Mm'
    closepath1, closepath2 = b'Zz'
    lineto_abs, lineto_rel = b'Ll'
    hline_abs, hline_rel = b'Hh'
    vline_abs, vline_rel = b'Vv'
    curveto_abs, curveto_rel = b'Cc'
    smoothcurveto_abs, smoothcurveto_rel = b'Ss'
    quadcurveto_abs, quadcurveto_rel = b'Qq'
    smoothquadcurveto_abs, smoothquadcurveto_rel = b'Tt'

    # Store the last parsed values
    # x/y = end position
    # x1/y1 and x2/y2 = bezier control points
    x = y = x1 = y1 = x2 = y2 = 0

    data = d.replace(b',', b' ').replace(b'\n', b' ')
    if isinstance(data, type('')):
        data = data.encode('ascii')
    end = len(data)
    data = ReadOnlyFileBuffer(data)

    def parse_float():
        chars = []
        while data.tell() < end:
            c = data.read(1)
            if c == b' ' and not chars:
                continue
            if c == b'-' or b'0' <= c[0] <= b'9' or c == b'.':
                chars.append(c[0])
            else:
                break
        if not chars:
            raise ValueError('Premature end of input while expecting a number')
        return float(b''.join(chars))

    def parse_floats(num, x_offset=0, y_offset=0):
        for i in xrange(num):
            val = parse_float()
            yield val + (x_offset if i % 2 == 0 else y_offset)

    repeated_command = None

    while data.tell() < end:
        last_cmd = cmd
        cmd = data.read(1) if repeated_command is None else repeated_command
        repeated_command = None

        if cmd == b' ':
            continue
        elif cmd == moveto_abs:
            x, y = parse_float(), parse_float()
            path.moveTo(x, y)
        elif cmd == moveto_rel:
            x += parse_float()
            y += parse_float()
            path.moveTo(x, y)
        elif cmd == closepath1 or cmd == closepath2:
            path.closeSubpath()
        elif cmd == lineto_abs:
            x, y = parse_floats(2)
            path.lineTo(x, y)
        elif cmd == lineto_rel:
            x += parse_float()
            y += parse_float()
            path.lineTo(x, y)
        elif cmd == hline_abs:
            x = parse_float()
            path.lineTo(x, y)
        elif cmd == hline_rel:
            x += parse_float()
            path.lineTo(x, y)
        elif cmd == vline_abs:
            y = parse_float()
            path.lineTo(x, y)
        elif cmd == vline_rel:
            y += parse_float()
            path.lineTo(x, y)
        elif cmd == curveto_abs:
            x1, y1, x2, y2, x, y = parse_floats(6)
            path.cubicTo(x1, y1, x2, y2, x, y)
        elif cmd == curveto_rel:
            x1, y1, x2, y2, x, y = parse_floats(6, x, y)
            path.cubicTo(x1, y1, x2, y2, x, y)
        elif cmd == smoothcurveto_abs:
            if last_cmd == curveto_abs or last_cmd == curveto_rel or last_cmd == smoothcurveto_abs or last_cmd == smoothcurveto_rel:
                x1 = 2 * x - x2
                y1 = 2 * y - y2
            else:
                x1, y1 = x, y
            x2, y2, x, y = parse_floats(4)
            path.cubicTo(x1, y1, x2, y2, x, y)
        elif cmd == smoothcurveto_rel:
            if last_cmd == curveto_abs or last_cmd == curveto_rel or last_cmd == smoothcurveto_abs or last_cmd == smoothcurveto_rel:
                x1 = 2 * x - x2
                y1 = 2 * y - y2
            else:
                x1, y1 = x, y
            x2, y2, x, y = parse_floats(4, x, y)
            path.cubicTo(x1, y1, x2, y2, x, y)
        elif cmd == quadcurveto_abs:
            x1, y1, x, y = parse_floats(4)
            path.quadTo(x1, y1, x, y)
        elif cmd == quadcurveto_rel:
            x1, y1, x, y = parse_floats(4, x, y)
            path.quadTo(x1, y1, x, y)
        elif cmd == smoothquadcurveto_abs:
            if last_cmd in (quadcurveto_abs, quadcurveto_rel, smoothquadcurveto_abs, smoothquadcurveto_rel):
                x1 = 2 * x - x1
                y1 = 2 * y - y1
            else:
                x1, y1 = x, y
            x, y = parse_floats(2)
            path.quadTo(x1, y1, x, y)
        elif cmd == smoothquadcurveto_rel:
            if last_cmd in (quadcurveto_abs, quadcurveto_rel, smoothquadcurveto_abs, smoothquadcurveto_rel):
                x1 = 2 * x - x1
                y1 = 2 * y - y1
            else:
                x1, y1 = x, y
            x, y = parse_floats(2, x, y)
            path.quadTo(x1, y1, x, y)
        elif cmd[0] in b'-.' or b'0' <= cmd[0] <= b'9':
            # A new number begins
            # In this case, multiple parameters tuples are specified for the last command
            # We rewind to reparse data correctly
            data.seek(-1, os.SEEK_CUR)

            # Handle extra parameters
            if last_cmd == moveto_abs:
                repeated_command = cmd = lineto_abs
            elif last_cmd == moveto_rel:
                repeated_command = cmd = lineto_rel
            elif last_cmd in (closepath1, closepath2):
                raise ValueError('Extra parameters after close path command')
            elif last_cmd in (
                lineto_abs, lineto_rel, hline_abs, hline_rel, vline_abs,
                vline_rel, curveto_abs, curveto_rel,smoothcurveto_abs,
                smoothcurveto_rel, quadcurveto_abs, quadcurveto_rel,
                smoothquadcurveto_abs, smoothquadcurveto_rel
            ):
                repeated_command = cmd = last_cmd
        else:
            raise ValueError('Unknown path command: %s' % cmd)
    return path
Beispiel #32
0
    def paintEvent(self, event):
        QSplitterHandle.paintEvent(self, event)
        left, right = self.parent().left, self.parent().right
        painter = QPainter(self)
        painter.setClipRect(event.rect())
        w = self.width()
        h = self.height()
        painter.setRenderHints(QPainter.Antialiasing, True)

        C = 16  # Curve factor.

        def create_line(ly, ry, right_to_left=False):
            ' Create path that represents upper or lower line of change marker '
            line = QPainterPath()
            if not right_to_left:
                line.moveTo(0, ly)
                line.cubicTo(C, ly, w - C, ry, w, ry)
            else:
                line.moveTo(w, ry)
                line.cubicTo(w - C, ry, C, ly, 0, ly)
            return line

        ldoc, rdoc = left.document(), right.document()
        lorigin, rorigin = left.contentOffset(), right.contentOffset()
        lfv, rfv = left.firstVisibleBlock().blockNumber(), right.firstVisibleBlock().blockNumber()
        lines = []

        for (ltop, lbot, kind), (rtop, rbot, kind) in zip(left.changes, right.changes):
            if lbot < lfv and rbot < rfv:
                continue
            ly_top = left.blockBoundingGeometry(ldoc.findBlockByNumber(ltop)).translated(lorigin).y()
            ly_bot = left.blockBoundingGeometry(ldoc.findBlockByNumber(lbot)).translated(lorigin).y()
            ry_top = right.blockBoundingGeometry(rdoc.findBlockByNumber(rtop)).translated(rorigin).y()
            ry_bot = right.blockBoundingGeometry(rdoc.findBlockByNumber(rbot)).translated(rorigin).y()
            if max(ly_top, ly_bot, ry_top, ry_bot) < 0:
                continue
            if min(ly_top, ly_bot, ry_top, ry_bot) > h:
                break

            upper_line = create_line(ly_top, ry_top)
            lower_line = create_line(ly_bot, ry_bot, True)

            region = QPainterPath()
            region.moveTo(0, ly_top)
            region.connectPath(upper_line)
            region.lineTo(w, ry_bot)
            region.connectPath(lower_line)
            region.closeSubpath()

            painter.fillPath(region, left.diff_backgrounds[kind])
            for path, aa in zip((upper_line, lower_line), (ly_top != ry_top, ly_bot != ry_bot)):
                lines.append((kind, path, aa))

        for kind, path, aa in sorted(lines, key=lambda x:{'replace':0}.get(x[0], 1)):
            painter.setPen(left.diff_foregrounds[kind])
            painter.setRenderHints(QPainter.Antialiasing, aa)
            painter.drawPath(path)

        painter.setFont(left.heading_font)
        for (lnum, text), (rnum, text) in zip(left.headers, right.headers):
            ltop, lbot, rtop, rbot = lnum, lnum + 3, rnum, rnum + 3
            if lbot < lfv and rbot < rfv:
                continue
            ly_top = left.blockBoundingGeometry(ldoc.findBlockByNumber(ltop)).translated(lorigin).y()
            ly_bot = left.blockBoundingGeometry(ldoc.findBlockByNumber(lbot)).translated(lorigin).y()
            ry_top = right.blockBoundingGeometry(rdoc.findBlockByNumber(rtop)).translated(rorigin).y()
            ry_bot = right.blockBoundingGeometry(rdoc.findBlockByNumber(rbot)).translated(rorigin).y()
            if max(ly_top, ly_bot, ry_top, ry_bot) < 0:
                continue
            if min(ly_top, ly_bot, ry_top, ry_bot) > h:
                break
            ly = painter.boundingRect(3, ly_top, left.width(), ly_bot - ly_top - 5, Qt.TextSingleLine, text).bottom() + 3
            ry = painter.boundingRect(3, ry_top, right.width(), ry_bot - ry_top - 5, Qt.TextSingleLine, text).bottom() + 3
            line = create_line(ly, ry)
            painter.setPen(QPen(left.palette().text(), 2))
            painter.setRenderHints(QPainter.Antialiasing, ly != ry)
            painter.drawPath(line)

        painter.end()
        # Paint the splitter without the change lines if the mouse is over the
        # splitter
        if getattr(self, 'hover', False):
            QSplitterHandle.paintEvent(self, event)
Beispiel #33
0
    def _contour(self):
        """Returns contour path."""
        ppath = QPainterPath()
        rect = self.contentsRect()
        margin = 5
        ppath.addRoundedRect(rect.left() - margin, rect.top() - margin,
                             rect.width() + 2 * margin,
                             rect.height() + 2 * margin, 15, 15)

        arrowpath = QPainterPath()
        arrowpath.moveTo(rect.center().x(), self.height())
        arrowpath.lineTo(rect.center().x() - 10, rect.bottom())
        arrowpath.lineTo(rect.center().x() + 10, rect.bottom())
        arrowpath.lineTo(rect.center().x(), self.height())

        ppath = ppath.united(arrowpath)
        return ppath
Beispiel #34
0
def svg_path_to_painter_path(d):
    '''
    Convert a tiny SVG 1.2 path into a QPainterPath.

    :param d: The value of the d attribute of an SVG <path> tag
    '''
    from PyQt5.Qt import QPainterPath
    cmd = last_cmd = b''
    path = QPainterPath()
    moveto_abs, moveto_rel = b'Mm'
    closepath1, closepath2 = b'Zz'
    lineto_abs, lineto_rel = b'Ll'
    hline_abs, hline_rel = b'Hh'
    vline_abs, vline_rel = b'Vv'
    curveto_abs, curveto_rel = b'Cc'
    smoothcurveto_abs, smoothcurveto_rel = b'Ss'
    quadcurveto_abs, quadcurveto_rel = b'Qq'
    smoothquadcurveto_abs, smoothquadcurveto_rel = b'Tt'

    # Store the last parsed values
    # x/y = end position
    # x1/y1 and x2/y2 = bezier control points
    x = y = x1 = y1 = x2 = y2 = 0

    data = d.replace(b',', b' ').replace(b'\n', b' ')
    if isinstance(data, type('')):
        data = data.encode('ascii')
    end = len(data)
    data = ReadOnlyFileBuffer(data)

    def parse_float():
        chars = []
        while data.tell() < end:
            c = data.read(1)
            if c == b' ' and not chars:
                continue
            if c == b'-' or b'0' <= c[0] <= b'9' or c == b'.':
                chars.append(c[0])
            else:
                break
        if not chars:
            raise ValueError('Premature end of input while expecting a number')
        return float(b''.join(chars))

    def parse_floats(num, x_offset=0, y_offset=0):
        for i in range(num):
            val = parse_float()
            yield val + (x_offset if i % 2 == 0 else y_offset)

    repeated_command = None

    while data.tell() < end:
        last_cmd = cmd
        cmd = data.read(1) if repeated_command is None else repeated_command
        repeated_command = None

        if cmd == b' ':
            continue
        elif cmd == moveto_abs:
            x, y = parse_float(), parse_float()
            path.moveTo(x, y)
        elif cmd == moveto_rel:
            x += parse_float()
            y += parse_float()
            path.moveTo(x, y)
        elif cmd == closepath1 or cmd == closepath2:
            path.closeSubpath()
        elif cmd == lineto_abs:
            x, y = parse_floats(2)
            path.lineTo(x, y)
        elif cmd == lineto_rel:
            x += parse_float()
            y += parse_float()
            path.lineTo(x, y)
        elif cmd == hline_abs:
            x = parse_float()
            path.lineTo(x, y)
        elif cmd == hline_rel:
            x += parse_float()
            path.lineTo(x, y)
        elif cmd == vline_abs:
            y = parse_float()
            path.lineTo(x, y)
        elif cmd == vline_rel:
            y += parse_float()
            path.lineTo(x, y)
        elif cmd == curveto_abs:
            x1, y1, x2, y2, x, y = parse_floats(6)
            path.cubicTo(x1, y1, x2, y2, x, y)
        elif cmd == curveto_rel:
            x1, y1, x2, y2, x, y = parse_floats(6, x, y)
            path.cubicTo(x1, y1, x2, y2, x, y)
        elif cmd == smoothcurveto_abs:
            if last_cmd == curveto_abs or last_cmd == curveto_rel or last_cmd == smoothcurveto_abs or last_cmd == smoothcurveto_rel:
                x1 = 2 * x - x2
                y1 = 2 * y - y2
            else:
                x1, y1 = x, y
            x2, y2, x, y = parse_floats(4)
            path.cubicTo(x1, y1, x2, y2, x, y)
        elif cmd == smoothcurveto_rel:
            if last_cmd == curveto_abs or last_cmd == curveto_rel or last_cmd == smoothcurveto_abs or last_cmd == smoothcurveto_rel:
                x1 = 2 * x - x2
                y1 = 2 * y - y2
            else:
                x1, y1 = x, y
            x2, y2, x, y = parse_floats(4, x, y)
            path.cubicTo(x1, y1, x2, y2, x, y)
        elif cmd == quadcurveto_abs:
            x1, y1, x, y = parse_floats(4)
            path.quadTo(x1, y1, x, y)
        elif cmd == quadcurveto_rel:
            x1, y1, x, y = parse_floats(4, x, y)
            path.quadTo(x1, y1, x, y)
        elif cmd == smoothquadcurveto_abs:
            if last_cmd in (quadcurveto_abs, quadcurveto_rel,
                            smoothquadcurveto_abs, smoothquadcurveto_rel):
                x1 = 2 * x - x1
                y1 = 2 * y - y1
            else:
                x1, y1 = x, y
            x, y = parse_floats(2)
            path.quadTo(x1, y1, x, y)
        elif cmd == smoothquadcurveto_rel:
            if last_cmd in (quadcurveto_abs, quadcurveto_rel,
                            smoothquadcurveto_abs, smoothquadcurveto_rel):
                x1 = 2 * x - x1
                y1 = 2 * y - y1
            else:
                x1, y1 = x, y
            x, y = parse_floats(2, x, y)
            path.quadTo(x1, y1, x, y)
        elif cmd[0] in b'-.' or b'0' <= cmd[0] <= b'9':
            # A new number begins
            # In this case, multiple parameters tuples are specified for the last command
            # We rewind to reparse data correctly
            data.seek(-1, os.SEEK_CUR)

            # Handle extra parameters
            if last_cmd == moveto_abs:
                repeated_command = cmd = lineto_abs
            elif last_cmd == moveto_rel:
                repeated_command = cmd = lineto_rel
            elif last_cmd in (closepath1, closepath2):
                raise ValueError('Extra parameters after close path command')
            elif last_cmd in (lineto_abs, lineto_rel, hline_abs, hline_rel,
                              vline_abs, vline_rel, curveto_abs, curveto_rel,
                              smoothcurveto_abs, smoothcurveto_rel,
                              quadcurveto_abs, quadcurveto_rel,
                              smoothquadcurveto_abs, smoothquadcurveto_rel):
                repeated_command = cmd = last_cmd
        else:
            raise ValueError('Unknown path command: %s' % cmd)
    return path