Example #1
0
    def draw(self, painter, rect, flags, text):
        """
        Draw the text in a clipping rectangle

        :param QPainter painter: Painter
        :param QRectF rect: Clipping rectangle
        :param int flags: Bitwise OR of the flags like in for QPainter::drawText()
        :param str text: Text to be rendered
        """
        txt = QwtRichTextDocument(text, flags, painter.font())
        painter.save()
        unscaledRect = QRectF(rect)
        if painter.font().pixelSize() < 0:
            res = qwtScreenResolution()
            pd = painter.device()
            if pd.logicalDpiX() != res.width() or pd.logicalDpiY(
            ) != res.height():
                transform = QTransform()
                transform.scale(
                    res.width() / float(pd.logicalDpiX()),
                    res.height() / float(pd.logicalDpiY()),
                )
                painter.setWorldTransform(transform, True)
                invtrans, _ok = transform.inverted()
                unscaledRect = invtrans.mapRect(rect)
        txt.setDefaultFont(painter.font())
        txt.setPageSize(QSizeF(unscaledRect.width(), QWIDGETSIZE_MAX))
        layout = txt.documentLayout()
        height = layout.documentSize().height()
        y = unscaledRect.y()
        if flags & Qt.AlignBottom:
            y += unscaledRect.height() - height
        elif flags & Qt.AlignVCenter:
            y += (unscaledRect.height() - height) / 2
        context = QAbstractTextDocumentLayout.PaintContext()
        context.palette.setColor(QPalette.Text, painter.pen().color())
        painter.translate(unscaledRect.x(), y)
        layout.draw(painter, context)
        painter.restore()
Example #2
0
    def create_high_dpi_drop_indicator_pixmap(
            self, size: QSizeF, area: DockWidgetArea,
            mode: OverlayMode) -> QPixmap:
        '''
        Create high dpi drop indicator pixmap

        Parameters
        ----------
        size : QSizeF
        area : DockWidgetArea
        mode : OverlayMode

        Returns
        -------
        value : QPixmap
        '''
        border_color = self.icon_color(IconColor.frame_color)
        background_color = self.icon_color(IconColor.window_background_color)

        window = self.public.window()

        # QT version compatibility (TODO necessary for qtpy?)
        device_pixel_ratio = (window.devicePixelRatioF()
                              if hasattr(window, 'devicePixelRatioF')
                              else window.devicePixelRatio())

        pixmap_size = QSizeF(size * device_pixel_ratio)
        pm = QPixmap(pixmap_size.toSize())
        pm.fill(QColor(0, 0, 0, 0))
        p = QPainter(pm)
        pen = p.pen()
        shadow_rect = QRectF(pm.rect())

        base_rect = QRectF()
        base_rect.setSize(shadow_rect.size() * 0.7)
        base_rect.moveCenter(shadow_rect.center())

        # Fill
        shadow_color = self.icon_color(IconColor.shadow_color)
        if shadow_color.alpha() == 255:
            shadow_color.setAlpha(64)

        p.fillRect(shadow_rect, shadow_color)

        # Drop area rect.
        p.save()
        area_rect = QRectF()
        area_line = QLineF()
        non_area_rect = QRectF()

        if area == DockWidgetArea.top:
            area_rect = QRectF(base_rect.x(), base_rect.y(), base_rect.width(),
                               base_rect.height()*.5)
            non_area_rect = QRectF(base_rect.x(), shadow_rect.height()*.5,
                                   base_rect.width(), base_rect.height()*.5)
            area_line = QLineF(area_rect.bottomLeft(), area_rect.bottomRight())
        elif area == DockWidgetArea.right:
            area_rect = QRectF(shadow_rect.width()*.5, base_rect.y(),
                               base_rect.width()*.5, base_rect.height())
            non_area_rect = QRectF(base_rect.x(), base_rect.y(),
                                   base_rect.width()*.5, base_rect.height())
            area_line = QLineF(area_rect.topLeft(), area_rect.bottomLeft())
        elif area == DockWidgetArea.bottom:
            area_rect = QRectF(base_rect.x(), shadow_rect.height()*.5,
                               base_rect.width(), base_rect.height()*.5)
            non_area_rect = QRectF(base_rect.x(), base_rect.y(),
                                   base_rect.width(), base_rect.height()*.5)
            area_line = QLineF(area_rect.topLeft(), area_rect.topRight())
        elif area == DockWidgetArea.left:
            area_rect = QRectF(base_rect.x(), base_rect.y(),
                               base_rect.width()*.5, base_rect.height())
            non_area_rect = QRectF(shadow_rect.width()*.5, base_rect.y(),
                                   base_rect.width()*.5, base_rect.height())
            area_line = QLineF(area_rect.topRight(), area_rect.bottomRight())

        baseSize = base_rect.size()
        if (OverlayMode.container == mode
                and area != DockWidgetArea.center):
            base_rect = area_rect

        p.fillRect(base_rect, background_color)
        if area_rect.isValid():
            pen = p.pen()
            pen.setColor(border_color)
            Color = self.icon_color(IconColor.overlay_color)
            if Color.alpha() == 255:
                Color.setAlpha(64)

            p.setBrush(Color)
            p.setPen(Qt.NoPen)
            p.drawRect(area_rect)
            pen = p.pen()
            pen.setWidth(1)
            pen.setColor(border_color)
            pen.setStyle(Qt.DashLine)
            p.setPen(pen)
            p.drawLine(area_line)

        p.restore()
        p.save()

        # Draw outer border
        pen = p.pen()
        pen.setColor(border_color)
        pen.setWidth(1)
        p.setBrush(Qt.NoBrush)
        p.setPen(pen)
        p.drawRect(base_rect)

        # draw window title bar
        p.setBrush(border_color)
        frame_rect = QRectF(base_rect.topLeft(),
                            QSizeF(base_rect.width(), baseSize.height()/10))
        p.drawRect(frame_rect)
        p.restore()

        # Draw arrow for outer container drop indicators
        if (OverlayMode.container == mode and
                area != DockWidgetArea.center):
            arrow_rect = QRectF()
            arrow_rect.setSize(baseSize)
            arrow_rect.setWidth(arrow_rect.width()/4.6)
            arrow_rect.setHeight(arrow_rect.height()/2)
            arrow_rect.moveCenter(QPointF(0, 0))

            arrow = QPolygonF()
            arrow.append(arrow_rect.topLeft())
            arrow.append(QPointF(arrow_rect.right(), arrow_rect.center().y()))
            arrow.append(arrow_rect.bottomLeft())

            p.setPen(Qt.NoPen)
            p.setBrush(self.icon_color(IconColor.arrow_color))
            p.setRenderHint(QPainter.Antialiasing, True)
            p.translate(non_area_rect.center().x(), non_area_rect.center().y())
            if area == DockWidgetArea.top:
                p.rotate(-90)
            elif area == DockWidgetArea.right:
                ...
            elif area == DockWidgetArea.bottom:
                p.rotate(90)
            elif area == DockWidgetArea.left:
                p.rotate(180)

            p.drawPolygon(arrow)

        pm.setDevicePixelRatio(device_pixel_ratio)
        return pm
Example #3
0
    def activate(self, plot, plotRect, options=0x00):
        """
        Recalculate the geometry of all components.
        
        :param qwt.plot.QwtPlot plot: Plot to be layout
        :param QRectF plotRect: Rectangle where to place the components
        :param options: Layout options
        """
        self.invalidate()
        rect = QRectF(plotRect)
        self.__data.layoutData.init(plot, rect)
        if (not (options & self.IgnoreLegend) and plot.legend()
                and not plot.legend().isEmpty()):
            self.__data.legendRect = self.layoutLegend(options, rect)
            region = QRegion(rect.toRect())
            rect = region.subtracted(QRegion(
                self.__data.legendRect.toRect())).boundingRect()
            if self.__data.legendPos == QwtPlot.LeftLegend:
                rect.setLeft(rect.left() + self.__data.spacing)
            elif self.__data.legendPos == QwtPlot.RightLegend:
                rect.setRight(rect.right() - self.__data.spacing)
            elif self.__data.legendPos == QwtPlot.TopLegend:
                rect.setTop(rect.top() + self.__data.spacing)
            elif self.__data.legendPos == QwtPlot.BottomLegend:
                rect.setBottom(rect.bottom() - self.__data.spacing)

        #     +---+-----------+---+
        #     |       Title       |
        #     +---+-----------+---+
        #     |   |   Axis    |   |
        #     +---+-----------+---+
        #     | A |           | A |
        #     | x |  Canvas   | x |
        #     | i |           | i |
        #     | s |           | s |
        #     +---+-----------+---+
        #     |   |   Axis    |   |
        #     +---+-----------+---+
        #     |      Footer       |
        #     +---+-----------+---+

        #  title, footer and axes include text labels. The height of each
        #  label depends on its line breaks, that depend on the width
        #  for the label. A line break in a horizontal text will reduce
        #  the available width for vertical texts and vice versa.
        #  expandLineBreaks finds the height/width for title, footer and axes
        #  including all line breaks.

        dimTitle, dimFooter, dimAxes = self.expandLineBreaks(options, rect)
        if dimTitle > 0:
            self.__data.titleRect.setRect(rect.left(), rect.top(),
                                          rect.width(), dimTitle)
            rect.setTop(self.__data.titleRect.bottom() + self.__data.spacing)
            if (self.__data.layoutData.scale[QwtPlot.yLeft].isEnabled !=
                    self.__data.layoutData.scale[QwtPlot.yRight].isEnabled):
                self.__data.titleRect.setX(rect.left() +
                                           dimAxes[QwtPlot.yLeft])
                self.__data.titleRect.setWidth(rect.width() -
                                               dimAxes[QwtPlot.yLeft] -
                                               dimAxes[QwtPlot.yRight])
        if dimFooter > 0:
            self.__data.footerRect.setRect(rect.left(),
                                           rect.bottom() - dimFooter,
                                           rect.width(), dimFooter)
            rect.setBottom(self.__data.footerRect.top() - self.__data.spacing)
            if (self.__data.layoutData.scale[QwtPlot.yLeft].isEnabled !=
                    self.__data.layoutData.scale[QwtPlot.yRight].isEnabled):
                self.__data.footerRect.setX(rect.left() +
                                            dimAxes[QwtPlot.yLeft])
                self.__data.footerRect.setWidth(rect.width() -
                                                dimAxes[QwtPlot.yLeft] -
                                                dimAxes[QwtPlot.yRight])
        self.__data.canvasRect.setRect(
            rect.x() + dimAxes[QwtPlot.yLeft],
            rect.y() + dimAxes[QwtPlot.xTop],
            rect.width() - dimAxes[QwtPlot.yRight] - dimAxes[QwtPlot.yLeft],
            rect.height() - dimAxes[QwtPlot.xBottom] - dimAxes[QwtPlot.xTop],
        )
        for axis in QwtPlot.AXES:
            if dimAxes[axis]:
                dim = dimAxes[axis]
                scaleRect = self.__data.scaleRect[axis]
                scaleRect.setRect(*self.__data.canvasRect.getRect())
                if axis == QwtPlot.yLeft:
                    scaleRect.setX(self.__data.canvasRect.left() - dim)
                    scaleRect.setWidth(dim)
                elif axis == QwtPlot.yRight:
                    scaleRect.setX(self.__data.canvasRect.right())
                    scaleRect.setWidth(dim)
                elif axis == QwtPlot.xBottom:
                    scaleRect.setY(self.__data.canvasRect.bottom())
                    scaleRect.setHeight(dim)
                elif axis == QwtPlot.xTop:
                    scaleRect.setY(self.__data.canvasRect.top() - dim)
                    scaleRect.setHeight(dim)
                scaleRect = scaleRect.normalized()

        #       +---+-----------+---+
        #       |  <-   Axis   ->   |
        #       +-^-+-----------+-^-+
        #       | | |           | | |
        #       |   |           |   |
        #       | A |           | A |
        #       | x |  Canvas   | x |
        #       | i |           | i |
        #       | s |           | s |
        #       |   |           |   |
        #       | | |           | | |
        #       +-V-+-----------+-V-+
        #       |   <-  Axis   ->   |
        #       +---+-----------+---+

        #  The ticks of the axes - not the labels above - should
        #  be aligned to the canvas. So we try to use the empty
        #  corners to extend the axes, so that the label texts
        #  left/right of the min/max ticks are moved into them.

        self.alignScales(options, self.__data.canvasRect,
                         self.__data.scaleRect)
        if not self.__data.legendRect.isEmpty():
            self.__data.legendRect = self.alignLegend(self.__data.canvasRect,
                                                      self.__data.legendRect)