Ejemplo n.º 1
0
 def image(cls, **kwargs):
     """
     Returns an image suitable for the palette.
     :rtype: QPixmap
     """
     # INITIALIZATION
     pixmap = QPixmap(kwargs['w'], kwargs['h'])
     pixmap.fill(Qt.transparent)
     painter = QPainter(pixmap)
     # INIT THE LINE
     p1 = QPointF(((kwargs['w'] - 54) / 2), kwargs['h'] / 2)
     p2 = QPointF(((kwargs['w'] - 54) / 2) + 54 - 2, kwargs['h'] / 2)
     line = QLineF(p1, p2)
     # CLACULATE HEAD COORDS
     angle = line.angle()
     p1 = QPointF(line.p2().x() + 2, line.p2().y())
     p2 = p1 - QPointF(sin(angle + M_PI / 3.0) * 8, cos(angle + M_PI / 3.0) * 8)
     p3 = p1 - QPointF(sin(angle + M_PI - M_PI / 3.0) * 8, cos(angle + M_PI - M_PI / 3.0) * 8)
     # INITIALIZE HEAD
     head = QPolygonF([p1, p2, p3])
     # DRAW EDGE LINE
     painter.setRenderHint(QPainter.Antialiasing)
     painter.setPen(QPen(QColor(0, 0, 0), 1.1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
     painter.drawLine(line)
     # DRAW EDGE HEAD
     painter.setPen(QPen(QColor(0, 0, 0), 1.1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
     painter.setBrush(QColor(0, 0, 0))
     painter.drawPolygon(head)
     return pixmap
Ejemplo n.º 2
0
    def plot_vert_line_graph(self, qp, x_line, color, c, arrow_up=False,
                             arrow_down=False):
        if x_line < self._start_date or x_line > self._end_date:
            return

        x_line -= self._start_date

        qp.save()
        qp.setPen(color)
        qp.setBrush(color)
        qp.setRenderHint(QPainter.Antialiasing)
        arrowSize = 2.0
        x, y = self.origGraph(c)
        line = QLineF(x + self.convX(x_line), y + 10, x + self.convX(x_line),
                      y + 50)
        qp.drawLine(line)
        if arrow_up:
            arrowP1 = line.p1() + QPointF(arrowSize, arrowSize * 3)
            arrowP2 = line.p1() + QPointF(-arrowSize, arrowSize * 3)
            qp.drawLine(line.p1(), arrowP1)
            qp.drawLine(line.p1(), arrowP2)
        if arrow_down:
            arrowP1 = line.p2() + QPointF(arrowSize, - arrowSize * 3)
            arrowP2 = line.p2() + QPointF(-arrowSize, - arrowSize * 3)
            qp.drawLine(line.p2(), arrowP1)
            qp.drawLine(line.p2(), arrowP2)
        qp.restore()
Ejemplo n.º 3
0
    def image(cls, **kwargs):
        """
        Returns an image suitable for the palette.
        :rtype: QPixmap
        """
        # INITIALIZATION
        pixmap = QPixmap(kwargs['w'], kwargs['h'])
        pixmap.fill(Qt.transparent)
        painter = QPainter(pixmap)
        # INITIALIZE EDGE LINE
        pp1 = QPointF(((kwargs['w'] - 52) / 2), kwargs['h'] / 2)
        pp2 = QPointF(((kwargs['w'] - 52) / 2) + 52 - 2, kwargs['h'] / 2)
        line = QLineF(pp1, pp2)
        # CALCULATE HEAD COORDINATES
        angle = radians(line.angle())
        p1 = QPointF(line.p2().x() + 2, line.p2().y())
        p2 = p1 - QPointF(sin(angle + M_PI / 3.0) * 8, cos(angle + M_PI / 3.0) * 8)
        p3 = p1 - QPointF(sin(angle + M_PI - M_PI / 3.0) * 8, cos(angle + M_PI - M_PI / 3.0) * 8)
        # INITIALIZE EDGE HEAD
        head = QPolygonF([p1, p2, p3])
        # DRAW THE POLYGON
        painter.setRenderHint(QPainter.Antialiasing)
        painter.setPen(QPen(QColor(0, 0, 0), 1.1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        painter.drawLine(line)
        # DRAW HEAD
        painter.setPen(QPen(QColor(0, 0, 0), 1.1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        painter.setBrush(QColor(0, 0, 0))
        painter.drawPolygon(head)
        # DRAW THE TEXT ON TOP OF THE EDGE
        space = 2 if Platform.identify() is Platform.Darwin else 0
        painter.setFont(Font('Arial', 9, Font.Light))
        painter.drawText(pp1.x() + space, (kwargs['h'] / 2) - 4, 'instanceOf')

        return pixmap
class GuideLine(Guide):
    def __init__(self, line_or_point, follows=None):
        super(GuideLine, self).__init__(follows)

        if isinstance(line_or_point, QLineF):
            self.line = line_or_point
        elif follows is not None:
            self.line = QLineF(self.prevGuide.endPos(), line_or_point)
        else:
            self.line = QLineF(QPointF(0, 0), line_or_point)

    def length(self):
        return self.line.length()

    def startPos(self):
        return QPointF(self.line.p1().x() * self.scaleX,
                self.line.p1().y() * self.scaleY)

    def endPos(self):
        return QPointF(self.line.p2().x() * self.scaleX,
                self.line.p2().y() * self.scaleY)

    def guide(self, item, moveSpeed):
        frame = item.guideFrame - self.startLength
        endX = (self.line.p1().x() + (frame * self.line.dx() / self.length())) * self.scaleX
        endY = (self.line.p1().y() + (frame * self.line.dy() / self.length())) * self.scaleY
        pos = QPointF(endX, endY)
        self.move(item, pos, moveSpeed)
Ejemplo n.º 5
0
    def paint(self, painter, option, widget):
        color = Qt.red if self.isSelected() else Qt.black
        painter.setPen(QPen(color, 2, Qt.SolidLine))
        path = QPainterPath(self.startPoint) # start path
        # iterating over all points of line
        for i in range(len(self.points) - 1):
            x1, y1 = self.points[i].x(), self.points[i].y()
            x2, y2 = self.points[i + 1].x(), self.points[i + 1].y()
            for point in sorted(self.commonPathsCenters, key=lambda x: x.x() + x.y(), reverse=x2 < x1 or y2 < y1):
                x, y = point.x(), point.y()
                if x == x1 == x2:
                    # vertical
                    if min(y1, y2) + 8 <= y < max(y1, y2) - 8:
                        if y2 > y1:
                            path.lineTo(point - QPointF(0, 8))
                            path.arcTo(QRectF(x - 8, y - 8, 16, 16), 90, -180)
                            path.moveTo(point + QPointF(0, 8))
                        else:
                            path.lineTo(point + QPointF(0, 8))
                            path.arcTo(QRectF(x - 8, y - 8, 16, 16), -90, 180)
                            path.moveTo(point - QPointF(0, 8))
                elif y == y1 == y2:
                    # horizontal
                    if min(x1, x2) + 8 <= x < max(x1, x2) - 8:
                        if x2 > x1:
                            path.lineTo(point - QPointF(8, 0))
                            path.arcTo(QRectF(x - 8, y - 8, 16, 16), 180, 180)
                            path.moveTo(point + QPointF(8, 0))
                        else:
                            path.lineTo(point + QPointF(8, 0))
                            path.arcTo(QRectF(x - 8, y - 8, 16, 16), 0, -180)
                            path.lineTo(point - QPointF(8, 0))
            path.lineTo(self.points[i + 1])
            # draw arrow in last segment
            if i == len(self.points) - 2:
                arrow_size = 20.0
                line = QLineF(self.points[i], self.points[i + 1])
                if line.length() < 20:
                    continue
                angle = math.acos(line.dx() / line.length())

                if line.dy() >= 0:
                    angle = (math.pi * 2) - angle

                arrow_p1 = line.p2() - QPointF(math.sin(angle + math.pi / 2.5) * arrow_size,
                                               math.cos(angle + math.pi / 2.5) * arrow_size)

                arrow_p2 = line.p2() - QPointF(math.sin(angle + math.pi - math.pi / 2.5) * arrow_size,
                                               math.cos(angle + math.pi - math.pi / 2.5) * arrow_size)

                arrowHead = QPolygonF()
                arrowHead.append(line.p2())
                arrowHead.append(arrow_p1)
                arrowHead.append(arrow_p2)
                painter.save()
                painter.setBrush(Qt.black)
                painter.drawPolygon(arrowHead)
                painter.restore()

        painter.drawPath(path) # draw final path
Ejemplo n.º 6
0
    def plot_vert_line_graph(self,
                             qp,
                             x_line,
                             color,
                             c,
                             arrow_up=False,
                             arrow_down=False):
        if x_line < self._start_date or x_line > self._end_date:
            return

        x_line -= self._start_date

        qp.save()
        qp.setPen(color)
        qp.setBrush(color)
        qp.setRenderHint(QPainter.Antialiasing)
        arrowSize = 2.0
        x, y = self.origGraph(c)
        line = QLineF(x + self.convX(x_line), y + 10, x + self.convX(x_line),
                      y + 50)
        qp.drawLine(line)
        if arrow_up:
            arrowP1 = line.p1() + QPointF(arrowSize, arrowSize * 3)
            arrowP2 = line.p1() + QPointF(-arrowSize, arrowSize * 3)
            qp.drawLine(line.p1(), arrowP1)
            qp.drawLine(line.p1(), arrowP2)
        if arrow_down:
            arrowP1 = line.p2() + QPointF(arrowSize, -arrowSize * 3)
            arrowP2 = line.p2() + QPointF(-arrowSize, -arrowSize * 3)
            qp.drawLine(line.p2(), arrowP1)
            qp.drawLine(line.p2(), arrowP2)
        qp.restore()
Ejemplo n.º 7
0
def calc_angle_from_l1_to_l2(a0: QLineF, a1: QLineF, degree: bool):
    """ Return the angle vector line a0 needs rotated from current pos to a1,
        Rotate direction: clockwise
        Return value unit: in radians or degrees(degree = True) """
    angle_a0 = calc_angle_from_p1_to_p2(a0.p1(), a0.p2(), False)
    angle_a1 = calc_angle_from_p1_to_p2(a1.p1(), a1.p2(), False)
    angle = angle_a1 - angle_a0
    if degree is True:
        return degrees(angle)
    return angle
 def updatePosition(self, force=False):
     #if self.toNode() is None and self.fromNode() is None:
     #if not force:
     #self.updateArrowHead()
     #self.updateTextPosition()
     #return
     if self.dest() and self.source():
         self._updatingPos = True
         #self.saveTextPosition()
         self.prepareGeometryChange()
         if len(self._points) == 2:
             a = self.source().closestBoundaryPosToItem(self.dest())
             b = self.dest().closestBoundaryPosToItem(self.source())
             a = self.mapFromItem(self.source(), a)
             b = self.mapFromItem(self.dest(), b)
         else:
             a = self.source().closestBoundaryPosToItem(self._points[1])
             b = self.dest().closestBoundaryPosToItem(self._points[-2])
             a = self.mapFromItem(self.source(), a)
             b = self.mapFromItem(self.dest(), b)
         line = QLineF(a, b)
         length = line.length()
         # BUGFIX
         if abs(length) == 0:
             line = QLineF(a, QPointF(a.x() + 1, a.y()))
             length = 1
         dx = line.dx()
         dx /= length
         if dx > 1:
             dx = 1
         elif dx < -1:
             dx = -1
         angle = acos(dx)
         size = self.arrowHeadSize()
         head = self._arrowHead
         if line.dy() >= 0:
             angle = pi * 2 - angle
         p2 = line.p2()
         u = p2 + QPointF(
             sin(angle + pi + pi / 3) * size,
             cos(angle + pi + pi / 3) * size)
         v = p2 + QPointF(
             sin(angle - pi / 3) * size,
             cos(angle - pi / 3) * size)
         if self.dest() != self.toPoint():
             self.toPoint().setPos(line.p2())
         if self.source() != self.fromPoint():
             self.fromPoint().setPos(line.p1())
         self.updateArrowHead()
         #self.updateTextPosition()
         self._updatingPos = False
     else:
         self.updateArrowHead()
         self.updateTextPosition()
Ejemplo n.º 9
0
    def paint(self, painter, option, widget):
        if not self.source or not self.dest:
            return

        # Draw the line itself.
        line = QLineF(self.sourcePoint, self.destPoint)

        if line.length() == 0.0:
            return

        painter.setPen(QPen(Qt.black, 1, Qt.SolidLine, Qt.RoundCap,
                Qt.RoundJoin))
        painter.drawLine(line)

        # Draw the arrows if there's enough room.
        angle = math.acos(line.dx() / line.length())
        if line.dy() >= 0:
            angle = Edge.TwoPi - angle

        sourceArrowP1 = self.sourcePoint + QPointF(math.sin(angle + Edge.Pi / 3) * self.arrowSize,
                                                          math.cos(angle + Edge.Pi / 3) * self.arrowSize)
        sourceArrowP2 = self.sourcePoint + QPointF(math.sin(angle + Edge.Pi - Edge.Pi / 3) * self.arrowSize,
                                                          math.cos(angle + Edge.Pi - Edge.Pi / 3) * self.arrowSize);   
        destArrowP1 = self.destPoint + QPointF(math.sin(angle - Edge.Pi / 3) * self.arrowSize,
                                                      math.cos(angle - Edge.Pi / 3) * self.arrowSize)
        destArrowP2 = self.destPoint + QPointF(math.sin(angle - Edge.Pi + Edge.Pi / 3) * self.arrowSize,
                                                      math.cos(angle - Edge.Pi + Edge.Pi / 3) * self.arrowSize)

        painter.setBrush(Qt.black)
        painter.drawPolygon(QPolygonF([line.p1(), sourceArrowP1, sourceArrowP2]))
        painter.drawPolygon(QPolygonF([line.p2(), destArrowP1, destArrowP2]))
Ejemplo n.º 10
0
    def paint(self, painter, option, widget):
        assert self.fromSquare is not None
        assert self.toSquare is not None
        line = QLineF(self.sourcePoint, self.destPoint)

        assert(line.length() != 0.0)

        # Draw the arrows if there's enough room.
        angle = math.acos(line.dx() / line.length())
        if line.dy() >= 0:
            angle = (math.pi*2.0) - angle

        destArrowP1 = self.destPoint + QPointF(
                math.sin(angle - math.pi / 3) * self.arrowSize,
                math.cos(angle - math.pi / 3) * self.arrowSize
        )
        destArrowP2 = self.destPoint + QPointF(
                math.sin(angle - math.pi + math.pi / 3) * self.arrowSize,
                math.cos(angle - math.pi + math.pi / 3) * self.arrowSize
        )

        painter.setPen(self.pen)
        painter.setBrush(self.brush)
        # arrowhead1 = QPolygonF([line.p1(), sourceArrowP1, sourceArrowP2])
        arrowhead2 = QPolygonF([line.p2(), destArrowP1, destArrowP2])
        painter.drawPolygon(arrowhead2)

        painter.setPen(self.pen)
        painter.drawLine(line)
Ejemplo n.º 11
0
    def paint(self, painter, option, widget):
        if not self.source or not self.dest:
            return

        # Draw the line itself.
        line = QLineF(self.sourcePoint, self.destPoint)

        if line.length() == 0.0:
            return

        painter.setPen(QPen(Qt.black, 1, Qt.SolidLine, Qt.RoundCap,
                Qt.RoundJoin))
        painter.drawLine(line)

        # Draw the arrows if there's enough room.
        angle = math.acos(line.dx() / line.length())
        if line.dy() >= 0:
            angle = Edge.TwoPi - angle

        sourceArrowP1 = self.sourcePoint + QPointF(math.sin(angle + Edge.Pi / 3) * self.arrowSize,
                                                          math.cos(angle + Edge.Pi / 3) * self.arrowSize)
        sourceArrowP2 = self.sourcePoint + QPointF(math.sin(angle + Edge.Pi - Edge.Pi / 3) * self.arrowSize,
                                                          math.cos(angle + Edge.Pi - Edge.Pi / 3) * self.arrowSize);   
        destArrowP1 = self.destPoint + QPointF(math.sin(angle - Edge.Pi / 3) * self.arrowSize,
                                                      math.cos(angle - Edge.Pi / 3) * self.arrowSize)
        destArrowP2 = self.destPoint + QPointF(math.sin(angle - Edge.Pi + Edge.Pi / 3) * self.arrowSize,
                                                      math.cos(angle - Edge.Pi + Edge.Pi / 3) * self.arrowSize)

        painter.setBrush(Qt.black)
        painter.drawPolygon(QPolygonF([line.p1(), sourceArrowP1, sourceArrowP2]))
        painter.drawPolygon(QPolygonF([line.p2(), destArrowP1, destArrowP2]))
Ejemplo n.º 12
0
    def adjust(self):
        if not self.source or not self.dest:
            return

        line = QLineF(
            self.mapFromItem(self.source,
                             self.source.getDrawSize() * -0.5,
                             self.source.getDrawSize() * -0.5),
            self.mapFromItem(self.dest,
                             self.dest.getDrawSize() * -0.5,
                             self.dest.getDrawSize() * -0.5))
        length = line.length()

        self.prepareGeometryChange()

        if length > self.source.getDrawSize():
            edgeOffset = QPointF(
                (line.dx() * self.source.getDrawSize() / 2) / length,
                (line.dy() * self.source.getDrawSize() / 2) / length)

            self.sourcePoint = line.p1() + edgeOffset
            self.destPoint = line.p2() - edgeOffset
        else:
            self.sourcePoint = line.p1()
            self.destPoint = line.p1()
Ejemplo n.º 13
0
 def paint(self,
           painter: QPainter,
           option: QStyleOptionGraphicsItem,
           widget=None):
     if not self.source or not self.dest:
         return
     line = QLineF(self.source_point, self.dest_point)
     if line.length() == 0.0:
         return
     color = self.get_color()
     width = SupremeSettings()['edge_width']
     if option.state & QStyle.State_Sunken:
         color, width = Qt.red, 2
         painter.setPen(QPen(Qt.black, 2, Qt.DashLine))
         painter.drawPolygon(self.getSelectionPolygon())
     elif option.state & QStyle.State_MouseOver:
         color, width = Qt.blue, 2
     painter.setPen(
         QPen(color, width, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
     painter.drawLine(line)
     angle = math.acos(line.dx() / line.length())
     if line.dy() >= 0:
         angle = math.pi * 2 - angle
     if self.arrow_size > 0:
         dest_arrow_p1 = self.dest_point + QPointF(
             math.sin(angle - math.pi / 3) * self.arrow_size,
             math.cos(angle - math.pi / 3) * self.arrow_size)
         dest_arrow_p2 = self.dest_point + QPointF(
             math.sin(angle - math.pi + math.pi / 3) * self.arrow_size,
             math.cos(angle - math.pi + math.pi / 3) * self.arrow_size)
         painter.setBrush(color)
         painter.drawPolygon(
             QPolygonF([line.p2(), dest_arrow_p1, dest_arrow_p2]))
     self.draw_animated_objects()
Ejemplo n.º 14
0
    def __init__(self, position, angle, arrow_size, value, unit):
        super(StressRepresentation, self).__init__()
        arrow_line = QLineF()
        arrow_line.setP1(position)
        arrow_line.setLength(arrow_size)
        arrow_line.setAngle(angle)
        arrow = QGraphicsLineItem()
        arrow.setLine(arrow_line)
        self.addToGroup(arrow)

        arrow_head1_line = QLineF()
        arrow_head1_line.setP1(arrow_line.p1())
        arrow_head1_line.setLength(arrow_size / 4)
        arrow_head1_line.setAngle(arrow_line.angle() + 45)
        arrow_head1 = QGraphicsLineItem()
        arrow_head1.setLine(arrow_head1_line)
        self.addToGroup(arrow_head1)

        arrow_head2_line = QLineF()
        arrow_head2_line.setP1(arrow_line.p1())
        arrow_head2_line.setLength(arrow_size / 4)
        arrow_head2_line.setAngle(arrow_line.angle() - 45)
        arrow_head2 = QGraphicsLineItem()
        arrow_head2.setLine(arrow_head2_line)
        self.addToGroup(arrow_head2)

        text = QGraphicsTextItem()
        text.setPlainText(f'{str(value)}{unit}')
        text.setPos(arrow_line.p2())
        self.addToGroup(text)

        self._set_color()
Ejemplo n.º 15
0
    def setLine(self, line):
        """
        Set the arrow base line (a `QLineF` in object coordinates).
        """
        if self.__line != line:
            self.__line = line

            # local item coordinate system
            geom = self.geometry().translated(-self.pos())

            if geom.isNull() and not line.isNull():
                geom = QRectF(0, 0, 1, 1)

            arrow_shape = arrow_path_concave(line, self.lineWidth())
            arrow_rect = arrow_shape.boundingRect()

            if not (geom.contains(arrow_rect)):
                geom = geom.united(arrow_rect)

            if self.__autoAdjustGeometry:
                # Shrink the geometry if required.
                geom = geom.intersected(arrow_rect)

            # topLeft can move changing the local coordinates.
            diff = geom.topLeft()
            line = QLineF(line.p1() - diff, line.p2() - diff)
            self.__arrowItem.setLine(line)
            self.__line = line

            # parent item coordinate system
            geom.translate(self.pos())
            self.setGeometry(geom)
Ejemplo n.º 16
0
def arrow_path_concave(line, width):
    """
    Return a :class:`QPainterPath` of a pretty looking arrow.
    """
    path = QPainterPath()
    p1, p2 = line.p1(), line.p2()

    if p1 == p2:
        return path

    baseline = QLineF(line)
    # Require some minimum length.
    baseline.setLength(max(line.length() - width * 3, width * 3))

    start, end = baseline.p1(), baseline.p2()
    mid = (start + end) / 2.0
    normal = QLineF.fromPolar(1.0, baseline.angle() + 90).p2()

    path.moveTo(start)
    path.lineTo(start + (normal * width / 4.0))

    path.quadTo(mid + (normal * width / 4.0), end + (normal * width / 1.5))

    path.lineTo(end - (normal * width / 1.5))
    path.quadTo(mid - (normal * width / 4.0), start - (normal * width / 4.0))
    path.closeSubpath()

    arrow_head_len = width * 4
    arrow_head_angle = 50
    line_angle = line.angle() - 180

    angle_1 = line_angle - arrow_head_angle / 2.0
    angle_2 = line_angle + arrow_head_angle / 2.0

    points = [
        p2, p2 + QLineF.fromPolar(arrow_head_len, angle_1).p2(),
        baseline.p2(), p2 + QLineF.fromPolar(arrow_head_len, angle_2).p2(), p2
    ]

    poly = QPolygonF(points)
    path_head = QPainterPath()
    path_head.addPolygon(poly)
    path = path.united(path_head)
    return path
Ejemplo n.º 17
0
    def paint(self, painter, index):
        widget = self.parent()
        if index != widget.activeIndex():
            return
        scale = widget.inverseScale()
        # metrics
        if self._rulerObject is not None:
            line, a = self._rulerObject
            origin = line.p1()
            cursor = line.p2()
            size = 8 * scale
            halfSize = 4 * scale
            color = QColor(255, 85, 127, 170)

            # line
            painter.save()
            painter.setPen(color)
            drawing.drawLine(painter, origin.x(), origin.y(), cursor.x(),
                             cursor.y(), scale)
            # ellipses
            ellipses = [
                (origin.x(), origin.y()),
                (cursor.x(), cursor.y()),
            ]
            path = QPainterPath()
            path.setFillRule(Qt.WindingFill)
            for x, y in itertools.chain(self._rulerPts.values(), ellipses):
                x -= halfSize
                y -= halfSize
                path.addEllipse(x, y, size, size)
            painter.fillPath(path, color)
            painter.restore()
            # text
            line = QLineF(line)
            xAlign = yAlign = "center"
            ellipses.pop(0)
            rp = self._rulerPts
            # XXX: sort shouldn't be performed in paintEvent
            for pt in itertools.chain((rp[k] for k in sorted(rp)), ellipses):
                p = QPointF(*pt)
                line.setP2(p)
                if line.length():
                    d = str(round(line.length(), 1))
                    pos = (line.p1() + line.p2()) / 2
                    drawing.drawTextAtPoint(painter, d, pos.x(), pos.y(),
                                            scale, xAlign, yAlign)
                line.setP1(p)
            xAlign, yAlign = "left", "top"
            dx = cursor.x() - origin.x()
            px = size
            if dx < 0:
                xAlign = "right"
                px = -px
            drawing.drawTextAtPoint(painter, a,
                                    cursor.x() + px,
                                    cursor.y() + size, scale, xAlign, yAlign)
Ejemplo n.º 18
0
 def image(cls, **kwargs):
     """
     Returns an image suitable for the palette.
     :rtype: QPixmap
     """
     # INITIALIZATION
     pixmap = QPixmap(kwargs['w'], kwargs['h'])
     pixmap.fill(Qt.transparent)
     painter = QPainter(pixmap)
     # INITIALIZE EDGE LINE
     p1 = QPointF(((kwargs['w'] - 54) / 2), kwargs['h'] / 2)
     p2 = QPointF(((kwargs['w'] - 54) / 2) + 54 - 2, kwargs['h'] / 2)
     line = QLineF(p1, p2)
     # CALCULATE HEAD COORDS
     angle = radians(line.angle())
     p1 = QPointF(line.p2().x() + 2, line.p2().y())
     p2 = p1 - QPointF(
         sin(angle + M_PI / 4.0) * 8,
         cos(angle + M_PI / 4.0) * 8)
     p3 = p2 - QPointF(
         sin(angle + 3.0 / 4.0 * M_PI) * 8,
         cos(angle + 3.0 / 4.0 * M_PI) * 8)
     p4 = p3 - QPointF(
         sin(angle - 3.0 / 4.0 * M_PI) * 8,
         cos(angle - 3.0 / 4.0 * M_PI) * 8)
     # INITIALIZE HEAD
     head = QPolygonF([p1, p2, p3, p4])
     # INITIALIZE EDGE PEN
     linePen = QPen(QColor(0, 0, 0), 1.1, Qt.CustomDashLine, Qt.RoundCap,
                    Qt.RoundJoin)
     linePen.setDashPattern([3, 3])
     # DRAW EDGE POLYGON
     painter.setRenderHint(QPainter.Antialiasing)
     painter.setPen(linePen)
     painter.drawLine(line)
     # DRAW EDGE HEAD
     painter.setPen(
         QPen(QColor(0, 0, 0), 1.1, Qt.SolidLine, Qt.RoundCap,
              Qt.RoundJoin))
     painter.setBrush(QColor(252, 252, 252))
     painter.drawPolygon(head)
     return pixmap
Ejemplo n.º 19
0
def moveUIPoint(contour, point, delta):
    if point.segmentType is None:
        # point is an offCurve. Get its sibling onCurve and the other
        # offCurve.
        onCurve, otherPoint = _getOffCurveSiblingPoints(contour, point)
        # if the onCurve is selected, the offCurve will move along with it
        if onCurve.selected:
            return
        point.move(delta)
        if not onCurve.smooth:
            contour.dirty = True
            return
        # if the onCurve is smooth, we need to either...
        if otherPoint.segmentType is None and not otherPoint.selected:
            # keep the other offCurve inline
            line = QLineF(point.x, point.y, onCurve.x, onCurve.y)
            otherLine = QLineF(onCurve.x, onCurve.y, otherPoint.x,
                               otherPoint.y)
            line.setLength(line.length() + otherLine.length())
            otherPoint.x = line.x2()
            otherPoint.y = line.y2()
        else:
            # keep point in tangency with onCurve -> otherPoint segment,
            # ie. do an orthogonal projection
            line = QLineF(otherPoint.x, otherPoint.y, onCurve.x, onCurve.y)
            n = line.normalVector()
            n.translate(QPointF(point.x, point.y) - n.p1())
            targetPoint = QPointF()
            n.intersect(line, targetPoint)
            # check that targetPoint is beyond its neighbor onCurve
            # we do this by calculating position of the offCurve and second
            # onCurve relative to the first onCurve. If there is no symmetry
            # in at least one of the axis, then we need to clamp
            onCurvePoint = line.p2()
            onDistance = line.p1() - onCurvePoint
            newDistance = targetPoint - onCurvePoint
            if (onDistance.x() >= 0) != (newDistance.x() <= 0) or \
                    (onDistance.y() >= 0) != (newDistance.y() <= 0):
                targetPoint = onCurvePoint
            # ok, now set pos
            point.x, point.y = targetPoint.x(), targetPoint.y()
    else:
        # point is an onCurve. Move its offCurves along with it.
        index = contour.index(point)
        point.move(delta)
        for d in (-1, 1):
            # edge-case: contour open, trailing offCurve and moving first
            # onCurve in contour
            if contour.open and index == 0 and d == -1:
                continue
            pt = contour.getPoint(index + d)
            if pt.segmentType is None:
                pt.move(delta)
    contour.dirty = True
Ejemplo n.º 20
0
def moveUIPoint(contour, point, delta):
    if point.segmentType is None:
        # point is an offCurve. Get its sibling onCurve and the other
        # offCurve.
        onCurve, otherPoint = _getOffCurveSiblingPoints(contour, point)
        # if the onCurve is selected, the offCurve will move along with it
        if onCurve.selected:
            return
        point.move(delta)
        if not onCurve.smooth:
            contour.dirty = True
            return
        # if the onCurve is smooth, we need to either...
        if otherPoint.segmentType is None and not otherPoint.selected:
            # keep the other offCurve inline
            line = QLineF(point.x, point.y, onCurve.x, onCurve.y)
            otherLine = QLineF(
                onCurve.x, onCurve.y, otherPoint.x, otherPoint.y)
            line.setLength(line.length() + otherLine.length())
            otherPoint.x = line.x2()
            otherPoint.y = line.y2()
        else:
            # keep point in tangency with onCurve -> otherPoint segment,
            # ie. do an orthogonal projection
            line = QLineF(otherPoint.x, otherPoint.y, onCurve.x, onCurve.y)
            n = line.normalVector()
            n.translate(QPointF(point.x, point.y) - n.p1())
            targetPoint = QPointF()
            n.intersect(line, targetPoint)
            # check that targetPoint is beyond its neighbor onCurve
            # we do this by calculating position of the offCurve and second
            # onCurve relative to the first onCurve. If there is no symmetry
            # in at least one of the axis, then we need to clamp
            onCurvePoint = line.p2()
            onDistance = line.p1() - onCurvePoint
            newDistance = targetPoint - onCurvePoint
            if (onDistance.x() >= 0) != (newDistance.x() <= 0) or \
                    (onDistance.y() >= 0) != (newDistance.y() <= 0):
                targetPoint = onCurvePoint
            # ok, now set pos
            point.x, point.y = targetPoint.x(), targetPoint.y()
    else:
        # point is an onCurve. Move its offCurves along with it.
        index = contour.index(point)
        point.move(delta)
        for d in (-1, 1):
            # edge-case: contour open, trailing offCurve and moving first
            # onCurve in contour
            if contour.open and index == 0 and d == -1:
                continue
            pt = contour.getPoint(index + d)
            if pt.segmentType is None:
                pt.move(delta)
    contour.dirty = True
Ejemplo n.º 21
0
    def adjust(self):
        if not self.source or not self.dest:
            return

        line = QLineF(self.mapFromItem(self.source, 0, 0),
                      self.mapFromItem(self.dest, 0, 0))
        length = line.length()

        self.prepareGeometryChange()

        self.sourcePoint = line.p1()
        self.destPoint = line.p2()
Ejemplo n.º 22
0
    def adjust(self):
        if not self._source or not self._dest:
            return

        line = QLineF(self.mapFromItem(self._source, 0, 0),
                      self.mapFromItem(self._dest, 0, 0))
        length = line.length()

        self.prepareGeometryChange()

        min_len = self._source.radius() + self._dest.radius(
        ) + self._source.pen().widthF() + self._dest.pen().widthF()
        if length > min_len:
            offset = QPointF(
                (line.dx() *
                 (self._source.radius() + self._source.pen().widthF() + 1)) /
                length,
                (line.dy() *
                 (self._source.radius() + self._source.pen().widthF() + 1)) /
                length)
            self.source_point = line.p1() + offset
            offset = QPointF(
                (line.dx() *
                 (self._dest.radius() + self._dest.pen().widthF() + 1)) /
                length,
                (line.dy() *
                 (self._dest.radius() + self._dest.pen().widthF() + 1)) /
                length)
            self.dest_point = line.p2() - offset
        else:
            self.source_point = self.dest_point = line.p1()

        path = QPainterPath()
        if self.sourceNode() == self.destNode():  # Draw self-loops
            self.__is_self_loop = True
            radius = self._source.radius()
            path.moveTo(
                self.source_point.x() - radius -
                2 * self._source.pen().widthF(), self.source_point.y())
            path.cubicTo(
                QPointF(self.source_point.x() - 4 * radius,
                        self.source_point.y()),
                QPointF(self.source_point.x(),
                        self.source_point.y() - 4 * radius),
                QPointF(
                    self.dest_point.x(),
                    self.dest_point.y() - radius -
                    2 * self._source.pen().widthF()))
        else:
            self.__is_self_loop = False
            path.moveTo(self.source_point)
            path.lineTo(self.dest_point)
        self.setPath(path)
Ejemplo n.º 23
0
 def image(cls, **kwargs):
     """
     Returns an image suitable for the palette.
     :rtype: QPixmap
     """
     # INITIALIZATION
     pixmap = QPixmap(kwargs['w'], kwargs['h'])
     pixmap.fill(Qt.transparent)
     painter = QPainter(pixmap)
     # INIT THE LINE
     p1 = QPointF(((kwargs['w'] - 54) / 2), kwargs['h'] / 2)
     p2 = QPointF(((kwargs['w'] - 54) / 2) + 54 - 2, kwargs['h'] / 2)
     line = QLineF(p1, p2)
     # CLACULATE HEAD COORDS
     angle = line.angle()
     p1 = QPointF(line.p2().x() + 2, line.p2().y())
     p2 = p1 - QPointF(
         sin(angle + M_PI / 3.0) * 8,
         cos(angle + M_PI / 3.0) * 8)
     p3 = p1 - QPointF(
         sin(angle + M_PI - M_PI / 3.0) * 8,
         cos(angle + M_PI - M_PI / 3.0) * 8)
     # INITIALIZE HEAD
     head = QPolygonF([p1, p2, p3])
     # DRAW EDGE LINE
     painter.setRenderHint(QPainter.Antialiasing)
     painter.setPen(
         QPen(QColor(0, 0, 0), 1.1, Qt.SolidLine, Qt.RoundCap,
              Qt.RoundJoin))
     painter.drawLine(line)
     # DRAW EDGE HEAD
     painter.setPen(
         QPen(QColor(0, 0, 0), 1.1, Qt.SolidLine, Qt.RoundCap,
              Qt.RoundJoin))
     painter.setBrush(QColor(0, 0, 0))
     painter.drawPolygon(head)
     return pixmap
Ejemplo n.º 24
0
 def adjust(self):
     if not self.source or not self.dest:
         return
     line = QLineF(self.mapFromItem(self.source, 0, 0),
                   self.mapFromItem(self.dest, 0, 0))
     length = line.length()
     self.prepareGeometryChange()
     if length > 20:
         edge_offset = QPointF(
             (line.dx() * self.source.size.width() / 2) / length,
             (line.dy() * self.source.size.height() / 2) / length)
         self.source_point = line.p1() + edge_offset
         self.dest_point = line.p2() - edge_offset
     else:
         self.source_point = self.dest_point = line.p1()
Ejemplo n.º 25
0
 def getSelectionPolygon(self):
     line = QLineF(self.source_point, self.dest_point)
     angle = line.angle() * np.pi / 180
     dx = self.selection_offset * np.sin(angle)
     dy = self.selection_offset * np.cos(angle)
     offset1 = QPointF(dx, dy)
     offset2 = QPointF(-dx, -dy)
     points = [
         line.p1() + offset1,
         line.p1() + offset2,
         line.p2() + offset2,
         line.p2() + offset1
     ]
     polygon = QPolygonF(points)
     return polygon
Ejemplo n.º 26
0
    def adjust(self):
        if not self.source or not self.dest:
            return

        line = QLineF(self.mapFromItem(self.source, 0, 0),
                self.mapFromItem(self.dest, 0, 0))
        length = line.length()

        self.prepareGeometryChange()

        if length > 20.0:
            edgeOffset = QPointF((line.dx() * 10) / length,
                    (line.dy() * 10) / length)

            self.sourcePoint = line.p1() + edgeOffset
            self.destPoint = line.p2() - edgeOffset
        else:
            self.sourcePoint = line.p1()
            self.destPoint = line.p1()
Ejemplo n.º 27
0
 def paint(self, painter, option, widget=None):
     """
     Public method to paint the item in local coordinates.
     
     @param painter reference to the painter object (QPainter)
     @param option style options (QStyleOptionGraphicsItem)
     @param widget optional reference to the widget painted on (QWidget)
     """
     if (option.state & QStyle.State_Selected) == \
             QStyle.State(QStyle.State_Selected):
         width = 2
     else:
         width = 1
     
     # draw the line first
     line = QLineF(self._origin, self._end)
     painter.setPen(
         QPen(Qt.black, width, Qt.SolidLine, Qt.FlatCap, Qt.MiterJoin))
     painter.drawLine(line)
     
     # draw the arrow head
     arrowAngle = self._type * ArrowheadAngleFactor
     slope = math.atan2(line.dy(), line.dx())
     
     # Calculate left arrow point
     arrowSlope = slope + arrowAngle
     a1 = QPointF(self._end.x() - self._halfLength * math.cos(arrowSlope),
                  self._end.y() - self._halfLength * math.sin(arrowSlope))
     
     # Calculate right arrow point
     arrowSlope = slope - arrowAngle
     a2 = QPointF(self._end.x() - self._halfLength * math.cos(arrowSlope),
                  self._end.y() - self._halfLength * math.sin(arrowSlope))
     
     if self._filled:
         painter.setBrush(Qt.black)
     else:
         painter.setBrush(Qt.white)
     polygon = QPolygonF()
     polygon.append(line.p2())
     polygon.append(a1)
     polygon.append(a2)
     painter.drawPolygon(polygon)
    def adjust(self):
        if not self.source or not self.dest:
            return

        line = QLineF(self.mapFromItem(self.source, 0, 0),
                      self.mapFromItem(self.dest, 0, 0))
        length = line.length()

        self.prepareGeometryChange()

        if length > 20.0:
            edgeOffset = QPointF((line.dx() * 10) / length,
                                 (line.dy() * 10) / length)

            self.sourcePoint = line.p1() + edgeOffset
            self.destPoint = line.p2() - edgeOffset
        else:
            self.sourcePoint = line.p1()
            self.destPoint = line.p1()
Ejemplo n.º 29
0
    def paint(self, painter, option, widget=None):
        """
        Public method to paint the item in local coordinates.
        
        @param painter reference to the painter object (QPainter)
        @param option style options (QStyleOptionGraphicsItem)
        @param widget optional reference to the widget painted on (QWidget)
        """
        if (option.state & QStyle.State_Selected) == \
                QStyle.State(QStyle.State_Selected):
            width = 2
        else:
            width = 1

        # draw the line first
        line = QLineF(self._origin, self._end)
        painter.setPen(
            QPen(Qt.black, width, Qt.SolidLine, Qt.FlatCap, Qt.MiterJoin))
        painter.drawLine(line)

        # draw the arrow head
        arrowAngle = self._type * ArrowheadAngleFactor
        slope = math.atan2(line.dy(), line.dx())

        # Calculate left arrow point
        arrowSlope = slope + arrowAngle
        a1 = QPointF(self._end.x() - self._halfLength * math.cos(arrowSlope),
                     self._end.y() - self._halfLength * math.sin(arrowSlope))

        # Calculate right arrow point
        arrowSlope = slope - arrowAngle
        a2 = QPointF(self._end.x() - self._halfLength * math.cos(arrowSlope),
                     self._end.y() - self._halfLength * math.sin(arrowSlope))

        if self._filled:
            painter.setBrush(Qt.black)
        else:
            painter.setBrush(Qt.white)
        polygon = QPolygonF()
        polygon.append(line.p2())
        polygon.append(a1)
        polygon.append(a2)
        painter.drawPolygon(polygon)
Ejemplo n.º 30
0
    def adjust(self):
        """
        Draw the arc line
        """
        if not self.source or not self.destination:
            return
        line = QLineF(
            self.mapFromItem(
                self.source,
                self.source.boundingRect().width() -
                (self.source.boundingRect().width() / 2.0),
                self.source.boundingRect().height() / 2.0),
            self.mapFromItem(self.destination,
                             self.destination.boundingRect().width() / 2.0,
                             self.destination.boundingRect().height() / 2.0))
        self.prepareGeometryChange()
        self.source_point = line.p1()
        self.destination_point = line.p2()

        # mouse over on line only
        self.setLine(line)
Ejemplo n.º 31
0
    def paint(self, painter, option, widget):
        if not self.source or not self.dest:
            return

        # Draw the line itself.
        line = QLineF(self.sourcePoint, self.destPoint)

        if line.length() == 0.0:
            return

        painter.setPen(
            QPen(Qt.black, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        painter.drawLine(line)

        # Draw the arrows if there's enough room.
        angle = math.acos(line.dx() / line.length())
        if line.dy() >= 0:
            angle = Edge.TwoPi - angle

        destArrowP1 = self.destPoint + QPointF(
            math.sin(angle - Edge.Pi / 3) * self.arrowSize,
            math.cos(angle - Edge.Pi / 3) * self.arrowSize)
        destArrowP2 = self.destPoint + QPointF(
            math.sin(angle - Edge.Pi + Edge.Pi / 3) * self.arrowSize,
            math.cos(angle - Edge.Pi + Edge.Pi / 3) * self.arrowSize)

        conditionPoint = self.sourcePoint + QPointF(
            math.sin(angle + Edge.Pi / 3) * self.arrowSize * 2,
            math.cos(angle + Edge.Pi / 3) * self.arrowSize * 2)
        textToPrint = self.condition
        for path in self.source.edges():
            if path.destNode(
            ).name == self.dest.name and path.condition != self.condition:
                textToPrint += ", %c" % (path.condition)
                if path.condition > self.condition:
                    return

        painter.setBrush(Qt.black)
        painter.drawPolygon(QPolygonF([line.p2(), destArrowP1, destArrowP2]))
        painter.drawText(conditionPoint, textToPrint)
Ejemplo n.º 32
0
    def paint(self, painter, options, widget=None):
        painter.setPen(self.pen)
        if self.head is not None:
            painter.drawLine(self.head)
        if self.tail is not None:
            painter.drawLine(self.tail)
        painter.drawLine(self.line())
        if self.isSelected():
            painter.setPen(self.dashed_pen)
            painter.drawPolygon(self.selection_polygon)

        # draw the arrow tip
        if self.tail is not None:
            tail_line = self.tail
        else:
            tail_line = self.line()
        intersection_point = QPointF(0, 0)
        for line in self.to_port.lines():
            line = QLineF(self.mapFromScene(line.p1()),
                          self.mapFromScene(line.p2()))
            intersection_type = tail_line.intersect(line, intersection_point)
            if intersection_type == QLineF.BoundedIntersection:
                break
        angle = math.acos(tail_line.dx() / tail_line.length())
        if tail_line.dy() >= 0:
            angle = (math.pi * 2) - angle

        arrow_p1 = intersection_point - QPointF(
            math.sin(angle + math.pi / 3) * self.arrow_size,
            math.cos(angle + math.pi / 3) * self.arrow_size)
        arrow_p2 = intersection_point - QPointF(
            math.sin(angle + math.pi - math.pi / 3) * self.arrow_size,
            math.cos(angle + math.pi - math.pi / 3) * self.arrow_size)
        self.arrow_head.clear()
        for p in [intersection_point, arrow_p1, arrow_p2]:
            self.arrow_head.append(p)
        path = QPainterPath()
        path.addPolygon(self.arrow_head)
        painter.fillPath(path, self.brush)
Ejemplo n.º 33
0
    def adjust(self):
        if not self._handle1 or not self._handle2:
            return

        line = QLineF(self.mapFromItem(self._handle1, 0, 0),
                      self.mapFromItem(self._handle2, 0, 0))
        length = line.length()

        self.prepareGeometryChange()

        if length > self.width() * 0.9:
            offset = QPointF((line.dx() * self.width() / 2) / length,
                             (line.dy() * self.width() / 2) / length)
            p1 = line.p1() + offset
            p2 = line.p2() - offset
        else:
            p1 = p2 = line.p1()

        path = QPainterPath()
        path.moveTo(p1)
        path.lineTo(p2)
        self.setPath(path)
Ejemplo n.º 34
0
    def paint(self, painter):
        line = QLineF(self.sourcePoint, self.destPoint)

        if line.length() == 0.0:
            return

        painter.setPen(
            QPen(Qt.darkGray, 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        painter.drawLine(line)

        angle = acos(line.dx() / line.length())
        if line.dy() >= 0:
            angle = (2 * pi) - angle

        destArrowP1 = self.destPoint + QPointF(
            sin(angle - pi / 3) * self.arrowSize,
            cos(angle - pi / 3) * self.arrowSize)
        destArrowP2 = self.destPoint + QPointF(
            sin(angle - pi + pi / 3) * self.arrowSize,
            cos(angle - pi + pi / 3) * self.arrowSize)

        painter.setBrush(Qt.darkGray)
        painter.drawPolygon(QPolygonF([line.p2(), destArrowP1, destArrowP2]))
Ejemplo n.º 35
0
def arrow_path_plain(line, width):
    """
    Return an :class:`QPainterPath` of a plain looking arrow.
    """
    path = QPainterPath()
    p1, p2 = line.p1(), line.p2()

    if p1 == p2:
        return path

    baseline = QLineF(line)
    # Require some minimum length.
    baseline.setLength(max(line.length() - width * 3, width * 3))
    path.moveTo(baseline.p1())
    path.lineTo(baseline.p2())

    stroker = QPainterPathStroker()
    stroker.setWidth(width)
    path = stroker.createStroke(path)

    arrow_head_len = width * 4
    arrow_head_angle = 50
    line_angle = line.angle() - 180

    angle_1 = line_angle - arrow_head_angle / 2.0
    angle_2 = line_angle + arrow_head_angle / 2.0

    points = [
        p2, p2 + QLineF.fromPolar(arrow_head_len, angle_1).p2(),
        p2 + QLineF.fromPolar(arrow_head_len, angle_2).p2(), p2
    ]

    poly = QPolygonF(points)
    path_head = QPainterPath()
    path_head.addPolygon(poly)
    path = path.united(path_head)
    return path
Ejemplo n.º 36
0
    def adjust(self):
        """
        Draw the arc line
        """
        if not self.source or not self.destination:
            return
        line = QLineF(
            self.mapFromItem(
                self.source,
                self.source.boundingRect().width() - (self.source.boundingRect().width() / 2.0),
                self.source.boundingRect().height() / 2.0
            ),
            self.mapFromItem(
                self.destination,
                self.destination.boundingRect().width() / 2.0,
                self.destination.boundingRect().height() / 2.0
            )
        )
        self.prepareGeometryChange()
        self.source_point = line.p1()
        self.destination_point = line.p2()

        # mouse over on line only
        self.setLine(line)
Ejemplo n.º 37
0
    def adjustGeometry(self):
        """
        Adjust the widget geometry to exactly fit the arrow inside
        while preserving the arrow path scene geometry.

        """
        # local system coordinate
        geom = self.geometry().translated(-self.pos())
        line = self.__line

        arrow_rect = self.__arrowItem.shape().boundingRect()

        if geom.isNull() and not line.isNull():
            geom = QRectF(0, 0, 1, 1)

        if not (geom.contains(arrow_rect)):
            geom = geom.united(arrow_rect)

        geom = geom.intersected(arrow_rect)
        diff = geom.topLeft()
        line = QLineF(line.p1() - diff, line.p2() - diff)
        geom.translate(self.pos())
        self.setGeometry(geom)
        self.setLine(line)
Ejemplo n.º 38
0
    def showWedge(self,
                  angle,
                  color,
                  extended=False,
                  rev_gradient=False,
                  outline_only=False):
        """Summary

        Args:
            angle (TYPE): Description
            color (TYPE): Description
            extended (bool, optional): Description
            rev_gradient (bool, optional): Description
            outline_only (bool, optional): Description
        """
        # Hack to keep wedge in front
        # self.setRotation(self.pre_xover_item_group.rotation())

        self._last_params = (angle, color, extended, rev_gradient,
                             outline_only)
        radius = self._radius
        span = self.pre_xover_item_group.partCrossoverSpanAngle() / 2
        radius_adjusted = radius + (_WEDGE_RECT_GAIN / 2)

        tip = QPointF(radius_adjusted, radius_adjusted)
        EXT = 1.35 if extended else 1.0

        # print("wtf", tip, pos)
        base_p2 = QPointF(1, 1)

        line0 = QLineF(tip, QPointF(base_p2))
        line1 = QLineF(tip, QPointF(base_p2))
        line2 = QLineF(tip, QPointF(base_p2))

        quad_scale = 1 + (.22 *
                          (span - 5) / 55)  # lo+(hi-lo)*(val-min)/(max-min)
        line0.setLength(radius_adjusted * EXT *
                        quad_scale)  # for quadTo control point
        line1.setLength(radius_adjusted * EXT)
        line2.setLength(radius_adjusted * EXT)
        line0.setAngle(angle)
        line1.setAngle(angle - span)
        line2.setAngle(angle + span)

        path = QPainterPath()

        if outline_only:
            self.setPen(getPenObj(color, 0.5, alpha=128, capstyle=Qt.RoundCap))
            path.moveTo(line1.p2())
            path.quadTo(line0.p2(), line2.p2())
        else:
            gradient = QRadialGradient(tip, radius_adjusted * EXT)
            color1 = getColorObj(color, alpha=80)
            color2 = getColorObj(color, alpha=0)
            if rev_gradient:
                color1, color2 = color2, color1

            if extended:
                gradient.setColorAt(0, color1)
                gradient.setColorAt(radius_adjusted / (radius_adjusted * EXT),
                                    color1)
                gradient.setColorAt(
                    radius_adjusted / (radius_adjusted * EXT) + 0.01, color2)
                gradient.setColorAt(1, color2)
            else:
                gradient.setColorAt(0, getColorObj(color, alpha=50))
            brush = QBrush(gradient)
            self.setBrush(brush)

            path.moveTo(line1.p1())
            path.lineTo(line1.p2())
            path.quadTo(line0.p2(), line2.p2())
            path.lineTo(line2.p1())

        self.setPath(path)
        self.show()
Ejemplo n.º 39
0
def _drawGuidelines(painter, glyph, scale, rect, guidelines, drawLines=True,
                    drawText=True, drawSelection=True, color=None):
    if not (drawLines or drawText):
        return
    xMin, yMin, width, height = rect
    xMax = xMin + width
    yMax = yMin + height
    fontSize = painter.font().pointSize()
    for line in guidelines:
        color_ = color
        if color_ is None:
            if line.color:
                color_ = colorToQColor(line.color)
            else:
                color_ = defaultColor("glyphGuideline")
        painter.save()
        painter.setPen(color)
        line1 = None
        if None not in (line.x, line.y):
            if line.angle is not None:
                # make an infinite line that intersects *(line.x, line.y)*
                # 1. make horizontal line from *(line.x, line.y)* of length
                # *diagonal*
                diagonal = math.sqrt(width**2 + height**2)
                line1 = QLineF(line.x, line.y, line.x + diagonal, line.y)
                # 2. set the angle
                # defcon guidelines are clockwise
                line1.setAngle(line.angle)
                # 3. reverse the line and set length to 2 * *diagonal*
                line1.setPoints(line1.p2(), line1.p1())
                line1.setLength(2 * diagonal)
            else:
                line1 = QLineF(xMin, line.y, xMax, line.y)
        textX = 0
        textY = 0
        if drawLines:
            if line1 is not None:
                # line
                drawLine(
                    painter, line1.x1(), line1.y1(), line1.x2(), line1.y2())
                # point
                x, y = line.x, line.y
                smoothWidth = 8 * scale
                smoothHalf = smoothWidth / 2.0
                painter.save()
                pointPath = QPainterPath()
                x -= smoothHalf
                y -= smoothHalf
                pointPath.addEllipse(x, y, smoothWidth, smoothWidth)
                pen = QPen(color_)
                pen.setWidthF(1 * scale)
                painter.setPen(pen)
                if drawSelection and line.selected:
                    painter.fillPath(pointPath, color_)
                painter.drawPath(pointPath)
                painter.restore()
            else:
                if line.y is not None:
                    drawLine(painter, xMin, line.y, xMax, line.y)
                elif line.x is not None:
                    drawLine(painter, line.x, yMin, line.x, yMax)
        if drawText and line.name:
            if line1 is not None:
                textX = line.x
                textY = line.y - 6 * scale
                xAlign = "center"
            else:
                if line.y is not None:
                    textX = glyph.width + 6 * scale
                    textY = line.y - (fontSize / 3.5) * scale
                elif line.x is not None:
                    textX = line.x + 6 * scale
                    textY = 0
                xAlign = "left"
            drawTextAtPoint(
                painter, line.name, textX, textY, scale, xAlign=xAlign)
        painter.restore()
Ejemplo n.º 40
0
    def drawToolButtonMenuIndicator(self, option, painter, widget=None):
        arrow_rect = self.proxy().subControlRect(QStyle.CC_ToolButton, option, QStyle.SC_ToolButtonMenu, widget)

        text_color = option.palette.color(
            QPalette.WindowText if option.state & QStyle.State_AutoRaise else QPalette.ButtonText
        )
        button_color = option.palette.color(QPalette.Button)
        background_color = self.background_color(button_color, 0.5)

        painter.save()

        # draw separating vertical line
        if option.state & (QStyle.State_On | QStyle.State_Sunken):
            top_offset, bottom_offset = 4, 3
        else:
            top_offset, bottom_offset = 2, 2

        if option.direction == Qt.LeftToRight:
            separator_line = QLineF(
                arrow_rect.x() - 3,
                arrow_rect.top() + top_offset,
                arrow_rect.x() - 3,
                arrow_rect.bottom() - bottom_offset,
            )
        else:
            separator_line = QLineF(
                arrow_rect.right() + 3,
                arrow_rect.top() + top_offset,
                arrow_rect.right() + 3,
                arrow_rect.bottom() - bottom_offset,
            )

        light_gradient = QLinearGradient(separator_line.p1(), separator_line.p2())
        light_gradient.setColorAt(
            0.0, ColorScheme.shade(self.background_top_color(button_color), ColorScheme.LightShade, 0.0)
        )
        light_gradient.setColorAt(
            1.0, ColorScheme.shade(self.background_bottom_color(button_color), ColorScheme.MidlightShade, 0.5)
        )
        separator_color = ColorScheme.shade(self.background_bottom_color(button_color), ColorScheme.MidShade, 0.0)

        painter.setRenderHint(QPainter.Antialiasing, False)
        painter.setPen(QPen(light_gradient, 1))
        painter.drawLine(separator_line.translated(-1, 0))
        painter.drawLine(separator_line.translated(+1, 0))
        painter.setPen(QPen(separator_color, 1))
        painter.drawLine(separator_line)

        # draw arrow
        arrow = QPolygonF([QPointF(-3, -1.5), QPointF(0.5, 2.5), QPointF(4, -1.5)])
        if option.direction == Qt.LeftToRight:
            arrow.translate(-2, 1)
        else:
            arrow.translate(+2, 1)
        pen_thickness = 1.6

        painter.setRenderHint(QPainter.Antialiasing, True)
        painter.translate(arrow_rect.center())

        painter.translate(0, +1)
        painter.setPen(
            QPen(self.calc_light_color(background_color), pen_thickness, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)
        )
        painter.drawPolyline(arrow)
        painter.translate(0, -1)
        painter.setPen(
            QPen(self.deco_color(background_color, text_color), pen_thickness, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)
        )
        painter.drawPolyline(arrow)

        painter.restore()
Ejemplo n.º 41
0
    def showWedge(self, angle, color,
                  extended=False, rev_gradient=False, outline_only=False):
        """Summary

        Args:
            angle (TYPE): Description
            color (TYPE): Description
            extended (bool, optional): Description
            rev_gradient (bool, optional): Description
            outline_only (bool, optional): Description
        """
        # Hack to keep wedge in front
        # self.setRotation(self.pre_xover_item_group.rotation())

        self._last_params = (angle, color, extended, rev_gradient, outline_only)
        radius = self._radius
        span = self.pre_xover_item_group.partCrossoverSpanAngle() / 2
        radius_adjusted = radius + (_WEDGE_RECT_GAIN / 2)

        tip = QPointF(radius_adjusted, radius_adjusted)
        EXT = 1.35 if extended else 1.0

        # print("wtf", tip, pos)
        base_p2 = QPointF(1, 1)

        line0 = QLineF(tip, QPointF(base_p2))
        line1 = QLineF(tip, QPointF(base_p2))
        line2 = QLineF(tip, QPointF(base_p2))

        quad_scale = 1 + (.22*(span - 5) / 55)  # lo+(hi-lo)*(val-min)/(max-min)
        line0.setLength(radius_adjusted * EXT*quad_scale)  # for quadTo control point
        line1.setLength(radius_adjusted * EXT)
        line2.setLength(radius_adjusted * EXT)
        line0.setAngle(angle)
        line1.setAngle(angle - span)
        line2.setAngle(angle + span)

        path = QPainterPath()

        if outline_only:
            self.setPen(getPenObj(color, 0.5, alpha=128, capstyle=Qt.RoundCap))
            path.moveTo(line1.p2())
            path.quadTo(line0.p2(), line2.p2())
        else:
            gradient = QRadialGradient(tip, radius_adjusted * EXT)
            color1 = getColorObj(color, alpha=80)
            color2 = getColorObj(color, alpha=0)
            if rev_gradient:
                color1, color2 = color2, color1

            if extended:
                gradient.setColorAt(0, color1)
                gradient.setColorAt(radius_adjusted / (radius_adjusted * EXT), color1)
                gradient.setColorAt(radius_adjusted / (radius_adjusted * EXT) + 0.01, color2)
                gradient.setColorAt(1, color2)
            else:
                gradient.setColorAt(0, getColorObj(color, alpha=50))
            brush = QBrush(gradient)
            self.setBrush(brush)

            path.moveTo(line1.p1())
            path.lineTo(line1.p2())
            path.quadTo(line0.p2(), line2.p2())
            path.lineTo(line2.p1())

        self.setPath(path)
        self.show()