def __grabRegion(self):
     """
     Private method to grab the selected region (i.e. do the snapshot).
     """
     pol = QPolygon(self.__selection)
     if not pol.isEmpty():
         self.__grabbing = True
         
         xOffset = self.__pixmap.rect().x() - pol.boundingRect().x()
         yOffset = self.__pixmap.rect().y() - pol.boundingRect().y()
         translatedPol = pol.translated(xOffset, yOffset)
         
         pixmap2 = QPixmap(pol.boundingRect().size())
         pixmap2.fill(Qt.transparent)
         
         pt = QPainter()
         pt.begin(pixmap2)
         if pt.paintEngine().hasFeature(QPaintEngine.PorterDuff):
             pt.setRenderHints(
                 QPainter.Antialiasing |
                 QPainter.HighQualityAntialiasing |
                 QPainter.SmoothPixmapTransform,
                 True)
             pt.setBrush(Qt.black)
             pt.setPen(QPen(QBrush(Qt.black), 0.5))
             pt.drawPolygon(translatedPol)
             pt.setCompositionMode(QPainter.CompositionMode_SourceIn)
         else:
             pt.setClipRegion(QRegion(translatedPol))
             pt.setCompositionMode(QPainter.CompositionMode_Source)
         
         pt.drawPixmap(pixmap2.rect(), self.__pixmap, pol.boundingRect())
         pt.end()
         
         self.grabbed.emit(pixmap2)
예제 #2
0
    def paintEvent(self, ev):
        color = self.palette().color(QPalette.Highlight)
        painter = QPainter(self)

        # Filled rectangle.
        painter.setClipRect(self.rect())
        color.setAlpha(50)
        painter.fillRect(self.rect().adjusted(2,2,-2,-2), color)

        # Thin rectangle outside.
        color.setAlpha(150)
        painter.setPen(color)
        painter.drawRect(self.rect().adjusted(0,0,-1,-1))

        # Pseudo-handles at the corners and sides
        color.setAlpha(100)
        pen = QPen(color)
        pen.setWidth(8)
        painter.setPen(pen)
        painter.setBackgroundMode(Qt.OpaqueMode)
        # Clip at 4 corners
        region = QRegion(QRect(0,0,20,20))
        region += QRect(self.rect().width()-20, 0, 20, 20)
        region += QRect(self.rect().width()-20, self.rect().height()-20, 20, 20)
        region += QRect(0, self.rect().height()-20, 20, 20)
        # Clip middles
        region += QRect(0, self.rect().height() // 2 - 10, self.rect().width(), 20)
        region += QRect(self.rect().width() // 2 - 10, 0, 20, self.rect().height())
        
        # Draw thicker rectangles, clipped at corners and sides.
        painter.setClipRegion(region)
        painter.drawRect(self.rect())
예제 #3
0
    def paintEvent(self, ev):
        ### Paint code contributed by Richard Cognot Jun 2012
        color = self.palette().color(QPalette.Highlight)
        painter = QPainter(self)

        # Filled rectangle.
        painter.setClipRect(self.rect())
        color.setAlpha(50)
        painter.fillRect(self.rect().adjusted(2,2,-2,-2), color)

        # Thin rectangle outside.
        color.setAlpha(150)
        painter.setPen(color)
        painter.drawRect(self.rect().adjusted(0,0,-1,-1))

        # Pseudo-handles at the corners and sides
        color.setAlpha(100)
        pen = QPen(color)
        pen.setWidth(8)
        painter.setPen(pen)
        painter.setBackgroundMode(Qt.OpaqueMode)
        # Clip at 4 corners
        region = QRegion(QRect(0,0,20,20))
        region += QRect(self.rect().width()-20, 0, 20, 20)
        region += QRect(self.rect().width()-20, self.rect().height()-20, 20, 20)
        region += QRect(0, self.rect().height()-20, 20, 20)
        # Clip middles
        region += QRect(0, self.rect().height() // 2 - 10, self.rect().width(), 20)
        region += QRect(self.rect().width() // 2 - 10, 0, 20, self.rect().height())

        # Draw thicker rectangles, clipped at corners and sides.
        painter.setClipRegion(region)
        painter.drawRect(self.rect())
예제 #4
0
    def draw(self, painter: QPainter):
        assert self.crop, 'crop must be set'

        # Compute painter regions for the crop and the blur
        all_region = QRegion(painter.viewport())
        crop_region = QRegion(self.crop)
        blur_region = all_region.subtracted(crop_region)

        # Let the QGraphicsBlurEffect only paint in blur_region
        painter.setClipRegion(blur_region)

        # Fill with black and set opacity so that the blurred region is drawn darker
        if self.BLUR_DARKEN > 0.0:
            painter.fillRect(painter.viewport(), Qt.black)
            painter.setOpacity(1 - self.BLUR_DARKEN)

        # Draw the blur effect
        super().draw(painter)

        # Restore clipping and opacity
        painter.setClipping(False)
        painter.setOpacity(1.0)

        # Get the source pixmap
        pixmap, offset = self.sourcePixmap(Qt.DeviceCoordinates, QGraphicsEffect.NoPad)
        painter.setWorldTransform(QTransform())

        # Get the source by adding the offset to the crop location
        source = self.crop
        if self.CROP_OFFSET_ENABLED:
            source = source.translated(self.CROP_OFFSET)
        painter.drawPixmap(self.crop.topLeft() + offset, pixmap, source)
예제 #5
0
 def render_mask(self, mask):
     size = QSize(mask.width(), mask.height())
     rect = QRect(QPoint(0, 0), size)
     pixmap = QPixmap(size)
     painter = QPainter(pixmap)
     for mask_colour, texture_pixmap in self._palette.items():
         qcolour = QColor(*mask_colour)
         mask_bitmap = mask.createMaskFromColor(qcolour, Qt.MaskOutColor)
         mask_region = QRegion(mask_bitmap)
         painter.setClipRegion(mask_region)
         painter.drawTiledPixmap(rect, texture_pixmap)
     return pixmap
예제 #6
0
    def mask(self, image: QImage) -> QImage:
        clip_rect = self._build_clip_rect(image)

        masked = QImage(self.size, QImage.Format_RGB32)

        painter = QPainter(masked)
        painter.setRenderHints(QPainter.Antialiasing, QPainter.SmoothPixmapTransform)
        painter.setClipRegion(self.clip_region)
        painter.drawImage(masked.rect(), image, clip_rect)

        painter.end()

        return masked
		def paintEvent(self, evt):
			"""Visualise update rects."""
			super().paintEvent(evt)
			
			p = QPainter(self)
			p.setClipRegion(evt.region())
			p.fillRect(
				0,0, 10000,10000,
				QColor.fromHsv(
					randrange(0,360),
					randrange(200,256),
					randrange(200,256),
					100
				)
			)
예제 #8
0
    def paintEvent(self, e):
        #// Draw the popup here
        #// You can always pick an image and use drawPixmap to
        #// draw it in order to make things simpler

        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        painter.setClipRegion(e.region())
        painter.fillRect(e.rect(), QColor(0, 0, 0, 0))

        #// Prepare the popup dimensions
        roundedRectDimensions = QRectF()
        roundedRectDimensions.setX(self.rect().x() + self.LR_MARGIN)
        roundedRectDimensions.setY(self.rect().y() + self.TB_MARGIN)
        roundedRectDimensions.setWidth(self.rect().width() -
                                       self.LR_MARGIN * 2.0)
        roundedRectDimensions.setHeight(self.rect().height() -
                                        self.TB_MARGIN * 2.0)

        pal = QPalette(self.palette())

        painter.setBrush(
            QBrush(
                pal.color(
                    QPalette.Window if self.dark_mode else QPalette.Mid)))

        pen = QPen()
        pen.setColor(
            pal.color(QPalette.Light if self.dark_mode else QPalette.Button))
        pen.setWidth(3)
        painter.setPen(pen)

        #// Draw the popup body
        painter.drawRoundedRect(roundedRectDimensions, self.LR_MARGIN * 2.0,
                                self.TB_MARGIN * 2.0)

        painter.setPen(Qt.NoPen)
        painter.setBrush(
            QBrush(
                pal.color(
                    QPalette.BrightText if self.dark_mode else QPalette.Dark)))
        #// Draw the popup pointer based on relPos
        self.drawPopupPointer(painter)

        e.accept()
예제 #9
0
 def __grabRect(self):
     """
     Private method to grab the selected rectangle (i.e. do the snapshot).
     """
     if self.__mode == SnapshotRegionGrabber.Ellipse:
         ell = QRegion(self.__selection, QRegion.Ellipse)
         if not ell.isEmpty():
             self.__grabbing = True
             
             xOffset = self.__pixmap.rect().x() - ell.boundingRect().x()
             yOffset = self.__pixmap.rect().y() - ell.boundingRect().y()
             translatedEll = ell.translated(xOffset, yOffset)
             
             pixmap2 = QPixmap(ell.boundingRect().size())
             pixmap2.fill(Qt.transparent)
             
             pt = QPainter()
             pt.begin(pixmap2)
             if pt.paintEngine().hasFeature(QPaintEngine.PorterDuff):
                 pt.setRenderHints(
                     QPainter.Antialiasing |
                     QPainter.HighQualityAntialiasing |
                     QPainter.SmoothPixmapTransform,
                     True)
                 pt.setBrush(Qt.black)
                 pt.setPen(QPen(QBrush(Qt.black), 0.5))
                 pt.drawEllipse(translatedEll.boundingRect())
                 pt.setCompositionMode(QPainter.CompositionMode_SourceIn)
             else:
                 pt.setClipRegion(translatedEll)
                 pt.setCompositionMode(QPainter.CompositionMode_Source)
             
             pt.drawPixmap(pixmap2.rect(), self.__pixmap,
                           ell.boundingRect())
             pt.end()
             
             self.grabbed.emit(pixmap2)
     else:
         r = QRect(self.__selection)
         if not r.isNull() and r.isValid():
             self.__grabbing = True
             self.grabbed.emit(self.__pixmap.copy(r))
예제 #10
0
    def __grabRect(self):
        """
        Private method to grab the selected rectangle (i.e. do the snapshot).
        """
        if self.__mode == SnapshotRegionGrabber.Ellipse:
            ell = QRegion(self.__selection, QRegion.Ellipse)
            if not ell.isEmpty():
                self.__grabbing = True

                xOffset = self.__pixmap.rect().x() - ell.boundingRect().x()
                yOffset = self.__pixmap.rect().y() - ell.boundingRect().y()
                translatedEll = ell.translated(xOffset, yOffset)

                pixmap2 = QPixmap(ell.boundingRect().size())
                pixmap2.fill(Qt.transparent)

                pt = QPainter()
                pt.begin(pixmap2)
                if pt.paintEngine().hasFeature(QPaintEngine.PorterDuff):
                    pt.setRenderHints(
                        QPainter.Antialiasing
                        | QPainter.HighQualityAntialiasing
                        | QPainter.SmoothPixmapTransform, True)
                    pt.setBrush(Qt.black)
                    pt.setPen(QPen(QBrush(Qt.black), 0.5))
                    pt.drawEllipse(translatedEll.boundingRect())
                    pt.setCompositionMode(QPainter.CompositionMode_SourceIn)
                else:
                    pt.setClipRegion(translatedEll)
                    pt.setCompositionMode(QPainter.CompositionMode_Source)

                pt.drawPixmap(pixmap2.rect(), self.__pixmap,
                              ell.boundingRect())
                pt.end()

                self.grabbed.emit(pixmap2)
        else:
            r = QRect(self.__selection)
            if not r.isNull() and r.isValid():
                self.__grabbing = True
                self.grabbed.emit(self.__pixmap.copy(r))
예제 #11
0
 def paintEvent(self, event=None):
     painter = QPainter(self)
     if self.box_dim != (0, 0):
         l, r, t, b = self.get_mouse_coords()
         painter.setClipRegion(
             QRegion(
                 QPolygon([
                     QPoint(0, 0),
                     QPoint(self.screen_dim[0], 0),
                     QPoint(self.screen_dim[0], t),
                     QPoint(l, t),
                     QPoint(l, b),
                     QPoint(r, b),
                     QPoint(r, t),
                     QPoint(self.screen_dim[0], t),
                     QPoint(self.screen_dim[0], self.screen_dim[1]),
                     QPoint(0, self.screen_dim[1]),
                     QPoint(0, 0)
                 ]), Qt.OddEvenFill))
     painter.setOpacity(0.4)
     painter.setBrush(Qt.black)
     painter.setPen(QPen(Qt.black))
     painter.drawRect(self.rect())
예제 #12
0
    def paintEvent(self, evt):
        """
        Protected method handling paint events.
        
        @param evt paint event (QPaintEvent)
        """
        if self.__grabbing:  # grabWindow() should just get the background
            return

        painter = QPainter(self)
        pal = QPalette(QToolTip.palette())
        font = QToolTip.font()

        handleColor = pal.color(QPalette.Active, QPalette.Highlight)
        handleColor.setAlpha(160)
        overlayColor = QColor(0, 0, 0, 160)
        textColor = pal.color(QPalette.Active, QPalette.Text)
        textBackgroundColor = pal.color(QPalette.Active, QPalette.Base)
        painter.drawPixmap(0, 0, self.__pixmap)
        painter.setFont(font)

        r = QRect(self.__selection)
        if not self.__selection.isNull():
            grey = QRegion(self.rect())
            if self.__mode == SnapshotRegionGrabber.Ellipse:
                reg = QRegion(r, QRegion.Ellipse)
            else:
                reg = QRegion(r)
            grey = grey.subtracted(reg)
            painter.setClipRegion(grey)
            painter.setPen(Qt.NoPen)
            painter.setBrush(overlayColor)
            painter.drawRect(self.rect())
            painter.setClipRect(self.rect())
            drawRect(painter, r, handleColor)

        if self.__showHelp:
            painter.setPen(textColor)
            painter.setBrush(textBackgroundColor)
            self.__helpTextRect = painter.boundingRect(
                self.rect().adjusted(2, 2, -2, -2), Qt.TextWordWrap,
                self.__helpText).translated(-self.__desktop.x(),
                                            -self.__desktop.y())
            self.__helpTextRect.adjust(-2, -2, 4, 2)
            drawRect(painter, self.__helpTextRect, textColor,
                     textBackgroundColor)
            painter.drawText(self.__helpTextRect.adjusted(3, 3, -3, -3),
                             Qt.TextWordWrap, self.__helpText)

        if self.__selection.isNull():
            return

        # The grabbed region is everything which is covered by the drawn
        # rectangles (border included). This means that there is no 0px
        # selection, since a 0px wide rectangle will always be drawn as a line.
        txt = "{0}, {1} ({2} x {3})".format(
            self.__locale.toString(self.__selection.x()),
            self.__locale.toString(self.__selection.y()),
            self.__locale.toString(self.__selection.width()),
            self.__locale.toString(self.__selection.height()))
        textRect = painter.boundingRect(self.rect(), Qt.AlignLeft, txt)
        boundingRect = textRect.adjusted(-4, 0, 0, 0)

        if textRect.width() < r.width() - 2 * self.__handleSize and \
           textRect.height() < r.height() - 2 * self.__handleSize and \
           r.width() > 100 and \
           r.height() > 100:
            # center, unsuitable for small selections
            boundingRect.moveCenter(r.center())
            textRect.moveCenter(r.center())
        elif r.y() - 3 > textRect.height() and \
                r.x() + textRect.width() < self.rect().width():
            # on top, left aligned
            boundingRect.moveBottomLeft(QPoint(r.x(), r.y() - 3))
            textRect.moveBottomLeft(QPoint(r.x() + 2, r.y() - 3))
        elif r.x() - 3 > textRect.width():
            # left, top aligned
            boundingRect.moveTopRight(QPoint(r.x() - 3, r.y()))
            textRect.moveTopRight(QPoint(r.x() - 5, r.y()))
        elif r.bottom() + 3 + textRect.height() < self.rect().bottom() and \
                r.right() > textRect.width():
            # at bottom, right aligned
            boundingRect.moveTopRight(QPoint(r.right(), r.bottom() + 3))
            textRect.moveTopRight(QPoint(r.right() - 2, r.bottom() + 3))
        elif r.right() + textRect.width() + 3 < self.rect().width():
            # right, bottom aligned
            boundingRect.moveBottomLeft(QPoint(r.right() + 3, r.bottom()))
            textRect.moveBottomLeft(QPoint(r.right() + 5, r.bottom()))

        # If the above didn't catch it, you are running on a very
        # tiny screen...
        drawRect(painter, boundingRect, textColor, textBackgroundColor)
        painter.drawText(textRect, Qt.AlignHCenter, txt)

        if (r.height() > self.__handleSize * 2 and
            r.width() > self.__handleSize * 2) or \
           not self.__mouseDown:
            self.__updateHandles()
            painter.setPen(Qt.NoPen)
            painter.setBrush(handleColor)
            painter.setClipRegion(
                self.__handleMask(SnapshotRegionGrabber.StrokeMask))
            painter.drawRect(self.rect())
            handleColor.setAlpha(60)
            painter.setBrush(handleColor)
            painter.setClipRegion(
                self.__handleMask(SnapshotRegionGrabber.FillMask))
            painter.drawRect(self.rect())
예제 #13
0
class PoincareViewModel(QWidget):
	def __init__(self, parent):
		super().__init__()
		self.parent = parent
		self.centerVertices = []
		self.origin = QPointF()

		self.drawnTiles = defaultdict(defaultdict)
		self.tiles = []
		self.tilesToUpdate = False
		self.sideCount = 5
		self.adjacentCount = 4
		self.renderDepth = 4
		self.fillMode = True


	#Formula to calculate distance from center of disk to any vertex of the
	#initial polygon is from:
	#http://www.malinc.se/math/noneuclidean/poincaretilingen.php
	def getCenterVertices(self):
		p = self.sideCount
		q = self.adjacentCount
		dist = (self.diskDiameter/2) * math.sqrt(math.cos(math.pi * (1/p + 1/q)) / math.cos(math.pi * (1/p - 1/q)))
		alpha = 2*math.pi/p

		centerVertices = []
		for i in range(p):
			x = self.origin.x() + (dist) * math.cos(i * alpha)
			y = self.origin.y() + (dist) * math.sin(i * alpha)

			centerVertices.append(QPointF(x, y))
		return centerVertices
		
	#Since tiles are indexed by their centers (floating point), we need some leeway
	#with how 'close' two points need to be to be considered the same
	def hasBeenDrawn(self, aPoint):
		precision = 1000
		x = round(precision * aPoint.x())/precision
		y = round(precision * aPoint.y())/precision

		try:
			return self.drawnTiles[x][y]
		except:
			return None

	def addDrawnTile(self, aTile):
		precision = 1000
		x = round(precision * aTile.center.x())/precision
		y = round(precision * aTile.center.y())/precision

		self.drawnTiles[x][y] = aTile

	# Breadth-first construction of tiles by reflection about each side, with the 
	# initial tile centered on the origin. This viewmodel is passed to each tile
	# since the disk's origin and diskDiameter are needed to calculate the arcs that 
	# make up the sides of a tile.
	def drawTiling(self):
		self.drawnCount = 0
		self.drawnTiles.clear()
		self.tiles.clear()
		self.centerVertices.clear()

		centerTile = Tile(self.getCenterVertices(), self, self.renderDepth)
		self.addDrawnTile(centerTile)

		queue = [centerTile]
		while queue:
			curTile = queue.pop()
			curTile.draw(self.painter)
			self.tiles.append(curTile)
			if curTile.layer == 1:
				continue

			for edge in curTile.edges:
				#First reflect the center of the current tile to check if the reflected
				#tile has been drawn before
				reflectedCenter = edge.reflectPoint(curTile.center)
				neighbor = self.hasBeenDrawn(reflectedCenter)

				if neighbor is None:
					#draw and log the new tile
					reflectedVertices = edge.reflectTile(curTile)
					neighbor = Tile(reflectedVertices, self, curTile.layer-1, reflectedCenter)
					queue.insert(0, neighbor)
					self.addDrawnTile(neighbor)

				#construct the list of neighbors
				if neighbor not in curTile.neighbors:
					curTile.neighbors.append(neighbor)
				if curTile not in neighbor.neighbors:
					neighbor.neighbors.append(curTile)

	def paintEvent(self, anEvent):
		self.painter = QPainter(self)
		self.painter.setRenderHint(QPainter.Antialiasing, on=True)

		self.diskDiameter = min(self.size().width(), self.size().height()) - 10
		self.origin.setX(self.size().width()/2)
		self.origin.setY(self.size().height()/2)

		self.painter.setPen(QPen(QColor(122, 0, 127, 255), 3))
		radius = self.diskDiameter/2
		x = self.origin.x()
		y = self.origin.y()
		diskRect = QRect(x - radius, y - radius, self.diskDiameter, self.diskDiameter)
		self.diskRegion = QRegion(diskRect, QRegion.Ellipse)
		self.painter.setClipRegion(self.diskRegion)
		
		if self.tilesToUpdate:
			for tile in self.tiles:
				tile.update(self.painter)
			self.tilesToUpdate = False
		else:
			self.drawTiling()
		
		self.painter.setClipping(False)

		self.painter.setPen(QPen(QColor(5, 0, 127, 255), 3))
		self.painter.drawEllipse(diskRect)
		self.painter.drawPoint(self.origin)
		
		self.painter.end()

	def updateTiles(self):
		self.tilesToUpdate = True
		self.update()

	def areHyperbolicDims(self, p, q):
		 return (p-2)*(q-2) > 4

	def setSideCount(self, count):
		if self.areHyperbolicDims(count, self.adjacentCount):
			self.sideCount = count
			self.update()
			return 0

		return -1

	def setAdjCount(self, count):
		if self.areHyperbolicDims(self.sideCount, count):
			self.adjacentCount = count
			self.update()
			return 0
			
		return -1

	def setRenderDepth(self, depth):
		self.renderDepth = depth
		self.update()

	def mousePressEvent(self, e):
		if self.diskRegion.contains(QPoint(e.x(), e.y())):
			self.parent.controller.clicked(e)

	def toggleFillMode(self):
		self.fillMode = not self.fillMode
		self.update()
예제 #14
0
 def paintEvent(self, evt):
     """
     Protected method handling paint events.
     
     @param evt paint event (QPaintEvent)
     """
     if self.__grabbing:     # grabWindow() should just get the background
         return
     
     painter = QPainter(self)
     pal = QPalette(QToolTip.palette())
     font = QToolTip.font()
     
     handleColor = pal.color(QPalette.Active, QPalette.Highlight)
     handleColor.setAlpha(160)
     overlayColor = QColor(0, 0, 0, 160)
     textColor = pal.color(QPalette.Active, QPalette.Text)
     textBackgroundColor = pal.color(QPalette.Active, QPalette.Base)
     painter.drawPixmap(0, 0, self.__pixmap)
     painter.setFont(font)
     
     r = QRect(self.__selection)
     if not self.__selection.isNull():
         grey = QRegion(self.rect())
         if self.__mode == SnapshotRegionGrabber.Ellipse:
             reg = QRegion(r, QRegion.Ellipse)
         else:
             reg = QRegion(r)
         grey = grey.subtracted(reg)
         painter.setClipRegion(grey)
         painter.setPen(Qt.NoPen)
         painter.setBrush(overlayColor)
         painter.drawRect(self.rect())
         painter.setClipRect(self.rect())
         drawRect(painter, r, handleColor)
     
     if self.__showHelp:
         painter.setPen(textColor)
         painter.setBrush(textBackgroundColor)
         self.__helpTextRect = painter.boundingRect(
             self.rect().adjusted(2, 2, -2, -2),
             Qt.TextWordWrap, self.__helpText).translated(
             -self.__desktop.x(), -self.__desktop.y())
         self.__helpTextRect.adjust(-2, -2, 4, 2)
         drawRect(painter, self.__helpTextRect, textColor,
                  textBackgroundColor)
         painter.drawText(
             self.__helpTextRect.adjusted(3, 3, -3, -3),
             Qt.TextWordWrap, self.__helpText)
     
     if self.__selection.isNull():
         return
     
     # The grabbed region is everything which is covered by the drawn
     # rectangles (border included). This means that there is no 0px
     # selection, since a 0px wide rectangle will always be drawn as a line.
     txt = "{0:n}, {1:n} ({2:n} x {3:n})".format(
         self.__selection.x(), self.__selection.y(),
         self.__selection.width(), self.__selection.height())
     textRect = painter.boundingRect(self.rect(), Qt.AlignLeft, txt)
     boundingRect = textRect.adjusted(-4, 0, 0, 0)
     
     if textRect.width() < r.width() - 2 * self.__handleSize and \
        textRect.height() < r.height() - 2 * self.__handleSize and \
        r.width() > 100 and \
        r.height() > 100:
         # center, unsuitable for small selections
         boundingRect.moveCenter(r.center())
         textRect.moveCenter(r.center())
     elif r.y() - 3 > textRect.height() and \
             r.x() + textRect.width() < self.rect().width():
         # on top, left aligned
         boundingRect.moveBottomLeft(QPoint(r.x(), r.y() - 3))
         textRect.moveBottomLeft(QPoint(r.x() + 2, r.y() - 3))
     elif r.x() - 3 > textRect.width():
         # left, top aligned
         boundingRect.moveTopRight(QPoint(r.x() - 3, r.y()))
         textRect.moveTopRight(QPoint(r.x() - 5, r.y()))
     elif r.bottom() + 3 + textRect.height() < self.rect().bottom() and \
             r.right() > textRect.width():
         # at bottom, right aligned
         boundingRect.moveTopRight(QPoint(r.right(), r.bottom() + 3))
         textRect.moveTopRight(QPoint(r.right() - 2, r.bottom() + 3))
     elif r.right() + textRect.width() + 3 < self.rect().width():
         # right, bottom aligned
         boundingRect.moveBottomLeft(QPoint(r.right() + 3, r.bottom()))
         textRect.moveBottomLeft(QPoint(r.right() + 5, r.bottom()))
     
     # If the above didn't catch it, you are running on a very
     # tiny screen...
     drawRect(painter, boundingRect, textColor, textBackgroundColor)
     painter.drawText(textRect, Qt.AlignHCenter, txt)
     
     if (r.height() > self.__handleSize * 2 and
         r.width() > self.__handleSize * 2) or \
        not self.__mouseDown:
         self.__updateHandles()
         painter.setPen(Qt.NoPen)
         painter.setBrush(handleColor)
         painter.setClipRegion(
             self.__handleMask(SnapshotRegionGrabber.StrokeMask))
         painter.drawRect(self.rect())
         handleColor.setAlpha(60)
         painter.setBrush(handleColor)
         painter.setClipRegion(
             self.__handleMask(SnapshotRegionGrabber.FillMask))
         painter.drawRect(self.rect())
예제 #15
0
 def paintEvent(self, event):
     if self._background:
         painter = QPainter(self)
         painter.setClipRegion(event.region())
         painter.drawPixmap(event.rect(), self._background, event.rect())
         painter.end()
예제 #16
0
 def paintEvent(self, evt):
     """
     Protected method handling paint events.
     
     @param evt paint event (QPaintEvent)
     """
     if self.__grabbing:     # grabWindow() should just get the background
         return
     
     painter = QPainter(self)
     pal = QPalette(QToolTip.palette())
     font = QToolTip.font()
     
     handleColor = pal.color(QPalette.Active, QPalette.Highlight)
     handleColor.setAlpha(160)
     overlayColor = QColor(0, 0, 0, 160)
     textColor = pal.color(QPalette.Active, QPalette.Text)
     textBackgroundColor = pal.color(QPalette.Active, QPalette.Base)
     painter.drawPixmap(0, 0, self.__pixmap)
     painter.setFont(font)
     
     pol = QPolygon(self.__selection)
     if not self.__selection.boundingRect().isNull():
         # Draw outline around selection.
         # Important: the 1px-wide outline is *also* part of the
         # captured free-region
         pen = QPen(handleColor, 1, Qt.SolidLine, Qt.SquareCap,
                    Qt.BevelJoin)
         painter.setPen(pen)
         painter.drawPolygon(pol)
         
         # Draw the grey area around the selection.
         grey = QRegion(self.rect())
         grey = grey - QRegion(pol)
         painter.setClipRegion(grey)
         painter.setPen(Qt.NoPen)
         painter.setBrush(overlayColor)
         painter.drawRect(self.rect())
         painter.setClipRect(self.rect())
         drawPolygon(painter, pol, handleColor)
     
     if self.__showHelp:
         painter.setPen(textColor)
         painter.setBrush(textBackgroundColor)
         self.__helpTextRect = painter.boundingRect(
             self.rect().adjusted(2, 2, -2, -2),
             Qt.TextWordWrap, self.__helpText).translated(
             -self.__desktop.x(), -self.__desktop.y())
         self.__helpTextRect.adjust(-2, -2, 4, 2)
         drawPolygon(painter, self.__helpTextRect, textColor,
                     textBackgroundColor)
         painter.drawText(
             self.__helpTextRect.adjusted(3, 3, -3, -3),
             Qt.TextWordWrap, self.__helpText)
     
     if self.__selection.isEmpty():
         return
     
     # The grabbed region is everything which is covered by the drawn
     # rectangles (border included). This means that there is no 0px
     # selection, since a 0px wide rectangle will always be drawn as a line.
     boundingRect = self.__selection.boundingRect()
     txt = "{0}, {1} ({2} x {3})".format(
         self.__locale.toString(boundingRect.x()),
         self.__locale.toString(boundingRect.y()),
         self.__locale.toString(boundingRect.width()),
         self.__locale.toString(boundingRect.height())
     )
     textRect = painter.boundingRect(self.rect(), Qt.AlignLeft, txt)
     boundingRect = textRect.adjusted(-4, 0, 0, 0)
     
     polBoundingRect = pol.boundingRect()
     if (textRect.width() <
         polBoundingRect.width() - 2 * self.__handleSize) and \
        (textRect.height() <
         polBoundingRect.height() - 2 * self.__handleSize) and \
        polBoundingRect.width() > 100 and \
        polBoundingRect.height() > 100:
         # center, unsuitable for small selections
         boundingRect.moveCenter(polBoundingRect.center())
         textRect.moveCenter(polBoundingRect.center())
     elif polBoundingRect.y() - 3 > textRect.height() and \
             polBoundingRect.x() + textRect.width() < self.rect().width():
         # on top, left aligned
         boundingRect.moveBottomLeft(
             QPoint(polBoundingRect.x(), polBoundingRect.y() - 3))
         textRect.moveBottomLeft(
             QPoint(polBoundingRect.x() + 2, polBoundingRect.y() - 3))
     elif polBoundingRect.x() - 3 > textRect.width():
         # left, top aligned
         boundingRect.moveTopRight(
             QPoint(polBoundingRect.x() - 3, polBoundingRect.y()))
         textRect.moveTopRight(
             QPoint(polBoundingRect.x() - 5, polBoundingRect.y()))
     elif (polBoundingRect.bottom() + 3 + textRect.height() <
           self.rect().bottom()) and \
             polBoundingRect.right() > textRect.width():
         # at bottom, right aligned
         boundingRect.moveTopRight(
             QPoint(polBoundingRect.right(), polBoundingRect.bottom() + 3))
         textRect.moveTopRight(
             QPoint(polBoundingRect.right() - 2,
                    polBoundingRect.bottom() + 3))
     elif polBoundingRect.right() + textRect.width() + 3 < \
             self.rect().width():
         # right, bottom aligned
         boundingRect.moveBottomLeft(
             QPoint(polBoundingRect.right() + 3, polBoundingRect.bottom()))
         textRect.moveBottomLeft(
             QPoint(polBoundingRect.right() + 5, polBoundingRect.bottom()))
     
     # If the above didn't catch it, you are running on a very
     # tiny screen...
     drawPolygon(painter, boundingRect, textColor, textBackgroundColor)
     painter.drawText(textRect, Qt.AlignHCenter, txt)
     
     if (polBoundingRect.height() > self.__handleSize * 2 and
         polBoundingRect.width() > self.__handleSize * 2) or \
        not self.__mouseDown:
         painter.setBrush(Qt.transparent)
         painter.setClipRegion(QRegion(pol))
         painter.drawPolygon(QPolygon(self.rect()))
예제 #17
0
 def paintEvent(self, event):
     if self._background:
         painter = QPainter(self)
         painter.setClipRegion(event.region())
         painter.drawPixmap(event.rect(), self._background, event.rect())
         painter.end()
예제 #18
0
    def paintEvent(self, event: QPaintEvent):
        _start = perf_counter()
        num = self.num_tabs
        selected = self.selected
        arrow_width = self._arrow_width
        height = self.height()
        width = self._button_width
        first_width = self._first_button_width
        button = self._button_path
        button_box = QRect(0, 0, width + arrow_width, height)
        first_box = QRect(0, 0, first_width + arrow_width, height)
        icon_area = QRect(arrow_width + 10, 0, max(48, width / 2), height)
        text_box = QRect(arrow_width, 0, width - arrow_width, height)
        text_flags = Qt.AlignCenter | Qt.AlignVCenter
        states = self.states

        painter = QPainter(self)
        region = event.region()
        painter.setClipRegion(region)
        #torender = self._tabs_within(event.region())
        #print("regions:")
        #for rect in event.region().rects():
        #    print(" -  ", rect)
        #painter.setPen(Qt.NoPen)
        painter.setPen(
            QPen(Qt.black, 2, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        titleFont = painter.font()
        titleFont.setPointSizeF(14)
        titleFont.setBold(True)
        painter.setFont(titleFont)

        painter.translate(num * width + first_width, 0)

        if region.intersects(painter.transform().mapRect(button_box)):
            painter.setBrush(states[num].get_color(num == selected))
            painter.drawPath(self._last_button_path)

        for i in reversed(range(num)):
            painter.translate(-width, 0)
            if not region.intersects(painter.transform().mapRect(button_box)):
                continue

            painter.setBrush(states[i].get_color(i == selected))
            painter.drawPath(button)

            if states[i].state == State.ACTIVE:
                painter.save()
                painter.setPen(Qt.NoPen)
                gw = (width + self._arrow_width) * 2
                gradient = QLinearGradient(0, 0, gw, 0)
                value = self._working_anim.value
                gradient.setColorAt(max(0.0, value - 0.2),
                                    QColor(255, 255, 255, 0))
                gradient.setColorAt(value, QColor(255, 255, 255, 180))
                gradient.setColorAt(min(1.0, value + 0.2),
                                    QColor(255, 255, 255, 0))
                brush = QBrush(gradient)
                brush.setTransform(brush.transform().translate(-gw / 4, 0))
                gradient_height = int(height * 0.2)
                painter.setBrush(brush)
                #painter.setClipRect(0, 0, width+self._arrow_width, gradient_height)
                #painter.drawPath(button)
                #painter.setClipRect(0, height-gradient_height, width+self._arrow_width, gradient_height)
                painter.drawPath(button)
                self._active_box = painter.transform().mapRect(button_box)
                painter.restore()

            #if states[i].icon:
            #    states[i].icon.paint(painter, icon_area)

            text = states[i].text
            if text:
                _, _, short = text.rpartition('-')
                painter.drawText(text_box, text_flags, short.capitalize())

        if region.intersects(first_box):
            painter.resetTransform()
            painter.setBrush(State.UNKNOWN.get_color(-1 == selected))
            painter.drawPath(self._first_button_path)

            if self.is_running:
                icon = self.style().standardIcon(QStyle.SP_MediaStop)
            else:
                icon = self.style().standardIcon(QStyle.SP_MediaPlay)

            size = min(self._first_button_width, self.height()) * 0.8
            painter.translate(5, (self.height() - size) / 2)
            icon.paint(painter, QRect(0, 0, size, size))

        _end = perf_counter()
        if not self._paint_times:
            self._paint_times = times = []
        else:
            times = self._paint_times
        times.append(_end - _start)
        if len(times) > 60:
            avg = sum(times) / len(times) * 1000000
            print("Average render time %.2fns" % (avg, ))
            self._paint_times = None
예제 #19
0
class CaptureWidget(QWidget):
    captured = pyqtSignal(QPixmap)

    def __init__(self):
        """
        CapturedWidget __init__
        """
        super().__init__()
        self.painter = QPainter()
        self.setCursor(Qt.CursorShape.CrossCursor)
        # Make widget stay on top & fullscreen
        self.setWindowState(Qt.WindowState.WindowFullScreen)
        self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint
                            | Qt.Tool | Qt.BypassWindowManagerHint)
        self.screenshot = ScreenGrabber().grab_entire_desktop()
        self._clipping_state = 0
        self._startpos: Optional[QPoint] = None
        self._endpos: Optional[QPoint] = None
        self.move(0, 0)
        self.resize(self.screenshot.size())

    def keyPressEvent(self, event: QKeyEvent):
        """
        Keypress event
        This allows capture widget escape to close, return or enter to capture
        :param event: QKeyEvent instance
        :type event: QKeyEvent
        """
        if event.key() == Qt.Key.Key_Escape:
            self.close()
        if event.key() in [Qt.Key.Key_Return, Qt.Key.Key_Enter]:
            if self._startpos is None or self._endpos is None:
                return
            screen = QApplication.screenAt(self._startpos)
            ratio = screen.devicePixelRatio()
            cropped = self.screenshot.copy(
                QRect(
                    int(self._startpos.x() * ratio),
                    int(self._startpos.y() * ratio),
                    int((self._endpos.x() - self._startpos.x()) * ratio),
                    int((self._endpos.y() - self._startpos.y()) * ratio),
                ))
            # noinspection PyUnresolvedReferences
            self.captured.emit(cropped)

    def mousePressEvent(self, event: QMouseEvent):
        """
        Mouse press event, this marks capture start
        :param event: QMouseEvent instance
        :type event: QMouseEvent
        """
        self._clipping_state = 1
        self._startpos = event.pos()

    def mouseMoveEvent(self, event: QMouseEvent):
        """
        Mouse move event, this marks capture area
        :param event: QMouseEvent instance
        :type event: QMouseEvent
        """
        if self._clipping_state != 1:
            return
        self._endpos = event.pos()
        self.repaint()

    def mouseReleaseEvent(self, event: QMouseEvent):
        """
        Mouse release event, this marks capture stop
        :param event: QMouseEvent instance
        :type event: QMouseEvent
        """
        self._clipping_state = 2
        self._endpos = event.pos()
        self.repaint()

    def paintEvent(self, event: QPaintEvent):
        """
        Paint event, draw cropped area
        :param event: QPaintEvent instance
        :type event: QPaintEvent
        """
        self.painter.begin(self)
        self.painter.drawPixmap(0, 0, self.screenshot)
        overlay = QColor(0, 0, 0, 120)
        self.painter.setBrush(overlay)
        grey = QRegion(self.rect())
        if self._clipping_state != 0:
            grey = grey.subtracted(
                QRegion(self._startpos.x(), self._startpos.y(),
                        self._endpos.x() - self._startpos.x(),
                        self._endpos.y() - self._startpos.y()))
        self.painter.setClipRegion(grey)
        self.painter.drawRect(0, 0, self.rect().width(), self.rect().height())
        self.painter.setClipRegion(QRegion(self.rect()))
        self.painter.end()