예제 #1
0
    def draw_selection_rect(self, painter):
        cr, sr = self.target, self.selection_state.rect
        painter.setPen(self.SELECT_PEN)
        painter.setRenderHint(QPainter.RenderHint.Antialiasing, False)
        if self.selection_state.current_mode == 'selected':
            # Shade out areas outside the selection rect
            for r in (
                    QRectF(cr.topLeft(), QPointF(sr.left(),
                                                 cr.bottom())),  # left
                    QRectF(QPointF(sr.left(), cr.top()), sr.topRight()),  # top
                    QRectF(QPointF(sr.right(), cr.top()),
                           cr.bottomRight()),  # right
                    QRectF(sr.bottomLeft(), QPointF(sr.right(),
                                                    cr.bottom())),  # bottom
            ):
                painter.fillRect(r, self.SHADE_COLOR)

            dr = self.get_drag_rect()
            if self.selection_state.in_selection and dr is not None:
                # Draw the resize rectangle
                painter.save()
                painter.setCompositionMode(
                    QPainter.CompositionMode.RasterOp_SourceAndNotDestination)
                painter.setClipRect(sr.adjusted(1, 1, -1, -1))
                painter.drawRect(dr)
                painter.restore()

        # Draw the selection rectangle
        painter.setCompositionMode(
            QPainter.CompositionMode.RasterOp_SourceAndNotDestination)
        painter.drawRect(sr)
예제 #2
0
def draw_curved_line(painter_path, dx, dy, c1_frac, c1_amp, c2_frac, c2_amp):
    length = sqrt(dx * dx + dy * dy)
    angle = atan2(dy, dx)
    c1 = QPointF(*rotate_vector(angle, c1_frac * length, c1_amp * length))
    c2 = QPointF(*rotate_vector(angle, c2_frac * length, c2_amp * length))
    pos = painter_path.currentPosition()
    painter_path.cubicTo(pos + c1, pos + c2, pos + QPointF(dx, dy))
예제 #3
0
def _cell_polys():
    poly = QPolygonF()
    l = 0.46/cos30
    inner_poly = QPolygonF()
    il = 0.75*l
    for i in range(6):
        a = i*tau/6 - tau/12
        poly.append(QPointF(l*math.sin(a), -l*math.cos(a)))
        inner_poly.append(QPointF(il*math.sin(a), -il*math.cos(a)))
    return poly, inner_poly
예제 #4
0
 def draw(self, painter):
     for l in self.layouts:
         if hasattr(l, 'draw'):
             # Etch effect for the text
             painter.save()
             painter.setRenderHints(QPainter.RenderHint.TextAntialiasing | QPainter.RenderHint.Antialiasing)
             painter.save()
             painter.setPen(QColor(255, 255, 255, 125))
             l.draw(painter, QPointF(1, 1))
             painter.restore()
             l.draw(painter, QPointF())
             painter.restore()
예제 #5
0
def _cell_polys():
    # It will be 0.49*2+0.03 = 1.01 units high, so neighbors will slightly collide.
    poly = QPolygonF()
    l = 0.49 / cos30
    # There is also a smaller inner part, for looks.
    inner_poly = QPolygonF()
    il = 0.77 * l
    for i in range(6):
        a = i * tau / 6 - tau / 12
        poly.append(QPointF(l * math.sin(a), -l * math.cos(a)))
        inner_poly.append(QPointF(il * math.sin(a), -il * math.cos(a)))
    return poly, inner_poly
예제 #6
0
 def __init__(self, scene):
     QGraphicsView.__init__(self, scene)
     self.scene = scene
     self.setBackgroundBrush(QBrush(qt.white))
     self.setResizeAnchor(QGraphicsView.AnchorViewCenter)
     self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse)
     self.setRenderHints(self.renderHints()|QPainter.Antialiasing)
     self.setHorizontalScrollBarPolicy(qt.ScrollBarAlwaysOff)
     self.setVerticalScrollBarPolicy(qt.ScrollBarAlwaysOff)
     inf = -1e10
     self.setSceneRect(QRectF(QPointF(-inf, -inf), QPointF(inf, inf)))
     self.scale(50, 50) #*1.00955
예제 #7
0
 def position(self, new_pos):
     (x, y) = new_pos
     self._position = Point(x, y)
     if self.layouts:
         self.layouts[0].setPosition(QPointF(x, y))
         y += self.layouts[0].boundingRect().height()
         for l in self.layouts[1:]:
             if isinstance(l, numbers.Number):
                 y += l
             else:
                 l.setPosition(QPointF(x, y))
                 y += l.boundingRect().height()
예제 #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
예제 #9
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
예제 #10
0
def fit_inside(parent, item, k):
    "Fit one QGraphicsItem inside another, scale by height and center it"
    sb = parent.boundingRect()
    tb = item.boundingRect()
    item.setScale(sb.height()/tb.height()*k)
    tb = item.mapRectToItem(parent, item.boundingRect())
    item.setPos(sb.center() - QPointF(tb.size().width()/2, tb.size().height()/2))
예제 #11
0
def hex1():
    result = QPolygonF()
    l = 0.5/cos30
    for i in range(6):
        a = i*tau/6 - tau/12
        result.append(QPointF(l*math.sin(a), -l*math.cos(a)))
    return result
예제 #12
0
파일: editor.py 프로젝트: Oaz/sixcells
 def flower_neighbors(self):
     if not self.scene():
         return
     for dx, dy in [  # order: (clockwise, closest) starting from north
         (0, -1),
         (0, -2),
         (1, -1.5),
         (1, -0.5),
         (2, -1),
         (2, 0),
         (1, 0.5),
         (2, 1),
         (1, 1.5),
         (0, 1),
         (0, 2),
         (-1, 1.5),
         (-1, 0.5),
         (-2, 1),
         (-2, 0),
         (-1, -0.5),
         (-2, -1),
         (-1, -1.5),
     ]:
         dx *= cos30
         pos = self.scenePos() + QPointF(dx, dy)
         it = self.scene().itemAt(pos, QTransform())
         if not it:
             continue
         if distance(pos, it.scenePos()) < 1e-2:
             yield it
예제 #13
0
    def __init__(self, text='', width=0, font=None, img=None, max_height=100, align=Qt.AlignmentFlag.AlignCenter):
        self.layouts = []
        self._position = Point(0, 0)
        self.leading = self.line_spacing = 0
        if font is not None:
            fm = QFontMetrics(font, img)
            self.leading = fm.leading()
            self.line_spacing = fm.lineSpacing()
        for text in text.split('<br>') if text else ():
            text, formats = parse_text_formatting(sanitize(text))
            l = QTextLayout(unescape_formatting(text), font, img)
            l.setAdditionalFormats(formats)
            to = QTextOption(align)
            to.setWrapMode(QTextOption.WrapMode.WrapAtWordBoundaryOrAnywhere)
            l.setTextOption(to)

            l.beginLayout()
            height = 0
            while height + 3*self.leading < max_height:
                line = l.createLine()
                if not line.isValid():
                    break
                line.setLineWidth(width)
                height += self.leading
                line.setPosition(QPointF(0, height))
                height += line.height()
            max_height -= height
            l.endLayout()
            if self.layouts:
                self.layouts.append(self.leading)
            else:
                self._position = Point(l.position().x(), l.position().y())
            self.layouts.append(l)
        if self.layouts:
            self.layouts.append(self.leading)
예제 #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, b"geometry", self)
        self.animation.setDuration(750)
        self.animation.setLoopCount(2)
        self.animation.setEasingCurve(QEasingCurve.Type.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.ColorGroup.Active,
                                 QPalette.ColorRole.WindowText)
        self.color = QColor(c)
        self.color.setAlpha(100)
        self.brush = QBrush(self.color, Qt.BrushStyle.SolidPattern)
예제 #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.RenderHint.Antialiasing)
        pen = QPen(self.ccolor2)
        pen.setWidth(3)
        pen.setJoinStyle(Qt.PenJoinStyle.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
예제 #16
0
 def paintEvent(self, ev):
     if self.last_layout_rect != self.rect():
         self.do_layout()
     p = QPainter(self)
     br = self.layout.boundingRect()
     y = 0
     if br.height() < self.height():
         y = (self.height() - br.height()) / 2
     self.layout.draw(p, QPointF(0, y))
예제 #17
0
 def __init__(self):
     self.fill = QBrush(Qt.GlobalColor.white)
     self.stroke = QPen()
     self.opacity = 1.0
     self.transform = QTransform()
     self.brush_origin = QPointF()
     self.clip_updated = False
     self.do_fill = False
     self.do_stroke = True
     self.qt_pattern_cache = {}
예제 #18
0
 def copy(self):
     ans = GraphicsState()
     ans.fill = QBrush(self.fill)
     ans.stroke = QPen(self.stroke)
     ans.opacity = self.opacity
     ans.transform = self.transform * QTransform()
     ans.brush_origin = QPointF(self.brush_origin)
     ans.clip_updated = self.clip_updated
     ans.do_fill, ans.do_stroke = self.do_fill, self.do_stroke
     return ans
예제 #19
0
    def upd(self, first=False):
        self.reset_cache()
        
        if self.display is Cell.unknown:
            self.setBrush(Color.yellow_border)
            self._inner.setBrush(Color.yellow)
            self._text.setText('')
        elif self.display is Cell.empty:
            self.setBrush(Color.black_border)
            self._inner.setBrush(Color.black)
        elif self.display is Cell.full:
            self.setBrush(Color.blue_border)
            self._inner.setBrush(Color.blue)
        
        if not self.placed:
            return
        
        if self.display is not Cell.unknown and self.value is not None:
            txt = str(self.value)
            if self.together is not None:
                txt = ('{{{}}}' if self.together else '-{}-').format(txt)
        else:
            txt = '?' if self.display is Cell.empty else ''
        
        self._text.setText(txt)
        if txt:
            fit_inside(self, self._text, 0.48)
        
        if self.extra_text:
            unknown = self.display is Cell.unknown
            fit_inside(self, self._extra_text, 0.31)
            self._extra_text.setPos(self._extra_text.pos() + QPointF(0, -0.2))
            self._extra_text.setBrush(Color.dark_text if unknown else Color.light_text)
        
        if txt and self.extra_text:
            self._text.setPos(self._text.pos() + QPointF(0, 0.1))

        self.update()
        
        if first:
            with self.upd_neighbors():
                pass
예제 #20
0
 def flower_neighbors(self):
     if not self.scene():
         return
     poly = QPolygonF()
     l = 1.7
     for i in range(6):
         a = i*tau/6
         poly.append(QPointF(self.x()+l*math.sin(a), self.y()+l*math.cos(a)))
     for it in self.scene().items(poly):
         if isinstance(it, Cell) and it is not self:
             yield it
예제 #21
0
    def __init__(self):
        # The collision box is rectangular
        poly = QPolygonF()
        poly.append(QPointF(-0.25, 0.48))
        poly.append(QPointF(-0.25, 0.02))
        poly.append(QPointF(0.25, 0.02))
        poly.append(QPointF(0.25, 0.48))
        #l = 0.49/cos30
        #for i in range(6):
        #a = i*tau/6-tau/12
        #poly.append(QPointF(l*math.sin(a), -l*math.cos(a)))

        QGraphicsPolygonItem.__init__(self, poly)

        self.setBrush(QColor(255, 255, 255, 0))
        #self.setPen(QPen(qt.red, 0))
        self.setPen(no_pen)

        self._text = QGraphicsSimpleTextItem('v')
        self._text.setBrush(Color.dark_text)
        fit_inside(self, self._text, 0.8)
예제 #22
0
 def move_selection_rect(self, x, y):
     sr = self.selection_state.rect
     half_width = sr.width() / 2.0
     half_height = sr.height() / 2.0
     c = sr.center()
     nx = c.x() + x
     ny = c.y() + y
     minx = self.target.left() + half_width
     maxx = self.target.right() - half_width
     miny, maxy = self.target.top() + half_height, self.target.bottom() - half_height
     nx = max(minx, min(maxx, nx))
     ny = max(miny, min(maxy, ny))
     sr.moveCenter(QPointF(nx, ny))
예제 #23
0
 def do_layout(self):
     ly = self.layout
     ly.beginLayout()
     w = self.width() - 5
     height = 0
     leading = self.fontMetrics().leading()
     while True:
         line = ly.createLine()
         if not line.isValid():
             break
         line.setLineWidth(w)
         height += leading
         line.setPosition(QPointF(5, height))
         height += line.height()
     ly.endLayout()
예제 #24
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(QAbstractAnimation.Direction.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()
예제 #25
0
 def update(self, tp):
     self.current_position = tp.pos()
     now = monotonic()
     self.time_since_last_update = now - self.last_update_time
     self.last_update_time = now
     self.previous_screen_position, self.current_screen_position = self.current_screen_position, QPointF(
         tp.screenPos())
     movement = (self.current_screen_position -
                 self.previous_screen_position).manhattanLength()
     self.total_movement += movement
     if movement > 5:
         self.time_of_last_move = now
예제 #26
0
 def __init__(self, tp):
     self.creation_time = self.last_update_time = self.time_of_last_move = monotonic(
     )
     self.start_screen_position = self.current_screen_position = self.previous_screen_position = QPointF(
         tp.screenPos())
     self.time_since_last_update = -1
     self.total_movement = 0
     self.start_position = self.current_position = tp.pos()
     self.extra_data = None
예제 #27
0
    def spread_gradient(self, gradient, pixel_page_width, pixel_page_height,
                        matrix):
        start = gradient.start()
        stop = gradient.finalStop()
        stops = list(map(lambda x: [x[0], x[1].getRgbF()], gradient.stops()))
        spread = gradient.spread()
        if spread != gradient.PadSpread:
            inv = matrix.inverted()[0]
            page_rect = tuple(
                map(inv.map, (QPointF(0, 0), QPointF(
                    pixel_page_width, 0), QPointF(0, pixel_page_height),
                              QPointF(pixel_page_width, pixel_page_height))))
            maxx = maxy = -sys.maxsize - 1
            minx = miny = sys.maxsize

            for p in page_rect:
                minx, maxx = min(minx, p.x()), max(maxx, p.x())
                miny, maxy = min(miny, p.y()), max(maxy, p.y())

            def in_page(point):
                return (minx <= point.x() <= maxx
                        and miny <= point.y() <= maxy)

            offset = stop - start
            llimit, rlimit = start, stop

            reflect = False
            base_stops = copy.deepcopy(stops)
            reversed_stops = list(reversed(stops))
            do_reflect = spread == gradient.ReflectSpread
            totl = abs(stops[-1][0] - stops[0][0])
            intervals = [
                abs(stops[i + 1][0] - stops[i][0]) / totl
                for i in range(len(stops) - 1)
            ]

            while in_page(llimit):
                reflect ^= True
                llimit -= offset
                estops = reversed_stops if (reflect
                                            and do_reflect) else base_stops
                stops = copy.deepcopy(estops) + stops

            first_is_reflected = reflect
            reflect = False

            while in_page(rlimit):
                reflect ^= True
                rlimit += offset
                estops = reversed_stops if (reflect
                                            and do_reflect) else base_stops
                stops = stops + copy.deepcopy(estops)

            start, stop = llimit, rlimit

            num = len(stops) // len(base_stops)
            if num > 1:
                # Adjust the stop parameter values
                t = base_stops[0][0]
                rlen = totl / num
                reflect = first_is_reflected ^ True
                intervals = [i * rlen for i in intervals]
                rintervals = list(reversed(intervals))

                for i in range(num):
                    reflect ^= True
                    pos = i * len(base_stops)
                    tvals = [t]
                    for ival in (rintervals
                                 if reflect and do_reflect else intervals):
                        tvals.append(tvals[-1] + ival)
                    for j in range(len(base_stops)):
                        stops[pos + j][0] = tvals[j]
                    t = tvals[-1]

                # In case there were rounding errors
                stops[-1][0] = base_stops[-1][0]

        return start, stop, tuple(Stop(s[0], s[1]) for s in stops)
예제 #28
0
        if self.display!=self.kind:
            r.append('({})'.format(repr(self.kind).split('.')[1]))
        r.append(self._text.text())
        try:
            r.append('#{}'.format(self.id))
        except AttributeError: pass
        if first:
            r.append('neighbors:[{}]'.format(' '.join(m.__repr__(False) for m in self.neighbors)))
            if self.members:
                r.append('members:[{}]'.format(' '.join(m.__repr__(False) for m in self.members)))
        return '<{}>'.format(' '.join(str(p) for p in r if str(p)))


_col_poly = QPolygonF()
for x, y in [(-0.25, 0.48), (-0.25, 0.02), (0.25, 0.02), (0.25, 0.48)]:
    _col_poly.append(QPointF(x, y))

_col_angle_deltas = {-60: (1, 1), 0: (0, 1), 60: (-1, 1)}

class Column(QGraphicsPolygonItem, Item):
    "Column number marker"
    def __init__(self):
        QGraphicsPolygonItem.__init__(self, _col_poly)

        self.show_info = False

        self.setBrush(QColor(255, 255, 255, 0))
        self.setPen(no_pen)
        
        self._text = QGraphicsSimpleTextItem('v')
        self._text.setBrush(Color.dark_text)
예제 #29
0
 def __call__(self, painter, rect, color_theme, title_block, subtitle_block, footer_block):
     g = QLinearGradient(QPointF(0, 0), QPointF(0, rect.height()))
     g.setStops([(0, self.color1), (0.7, self.color2), (1, self.color1)])
     painter.fillRect(rect, QBrush(g))
     return self.ccolor1, self.ccolor1, self.ccolor1