Ejemplo n.º 1
0
class StyleHelper(object):
    DEFAULT_BASE_COLOR = 0x666666

    def __init__(self):
        # Invalid by default, setBaseColor needs to be called at least once
        self._baseColor = QColor()
        self._requestedBaseColor = QColor()

    def sidebarFontSize(self):
        '''
        @brief: Height of the project explorer navigation bar
        '''
        if const.OS_MACOS:
            return 10
        else:
            return 7.5

    def requestedBaseColor(self):
        '''
        @brief: This is our color table, all colors derive from baseColor
        @return: QColor
        '''
        return self._requestedBaseColor

    def baseColor(self, lightColored=False):
        '''
        @return: QColor
        '''
        if not lightColored:
            return self._baseColor
        else:
            return self._baseColor.lighter(230)

    def panelTextColor(self, lightColored=False):
        '''
        @return: QColor
        '''
        if not lightColored:
            return Qt.white
        else:
            return Qt.black

    def highlightColor(self, lightColored=False):
        '''
        @return: QColor
        '''
        result = self.baseColor(lightColored)
        if not lightColored:
            result.setHsv(result.hue(), clamp(result.saturation()),
                          clamp(result.value() * 1.16))
        else:
            result.setHsv(result.hue(), clamp(result.saturation()),
                          clamp(result.value() * 1.06))
        return result

    def shadowColor(self, lightColored=False):
        '''
        @return: QColor
        '''
        result = self.baseColor(lightColored)
        result.setHsv(result.hue(), clamp(result.saturation() * 1.1),
                      clamp(result.value() * 0.70))
        return result

    def borderColor(self, lightColored=False):
        '''
        @return: QColor
        '''
        result = self.baseColor(lightColored)
        result.setHsv(result.hue(), result.saturation(),
                      clamp(result.value() / 2))
        return result

    def sidebarHighlight(self):
        '''
        @return: QColor
        '''
        return QColor(255, 255, 255, 40)

    def sidebarShadow(self):
        '''
        @return: QColor
        '''
        return QColor(0, 0, 0, 40)

    def setBaseColor(self, newColor):
        '''
        @brief: Sets the base color and makes sure all top level widgets are updated
        @note: We try to ensure that the actual color used are within
            reasonable bounds while generating the actual baseColor
            from the import user request.
        @param: color QColor
        '''
        self._requestedBaseColor = newColor

        color = QColor()
        color.setHsv(newColor.hue(),
                     newColor.saturation() * 0.7, 64 + newColor.value() / 3)

        if color.isValid() and color != self._baseColor:
            self._baseColor = color
            for widget in QApplication.topLevelWidgets():
                widget.update()

    def verticalGradientHelper(self,
                               painter,
                               spanRect,
                               rect,
                               lightColored=False):
        '''
        @brief: Gradients used for panels
        @param: painter QPainter
        @param: spanRect QRect
        @param: rect QRect
        @param: lightColored bool
        '''
        highlight = self.highlightColor(lightColored)
        shadow = self.shadowColor(lightColored)
        grad = QLinearGradient(spanRect.topRight(), spanRect.topLeft())
        grad.setColorAt(0, highlight.lighter(117))
        grad.setColorAt(1, shadow.darker(109))
        painter.fillRect(rect, grad)

        light = QColor(255, 255, 255, 80)
        painter.setPen(light)
        painter.drawLine(rect.topRight() - QPoint(1, 0),
                         rect.bottomRight() - QPoint(1, 0))
        dark = QColor(0, 0, 0, 90)
        painter.setPen(dark)
        painter.drawLine(rect.topLeft(), rect.bottomLeft())

    def verticalGradient(self,
                         painter,
                         spanRect,
                         clipRect,
                         lightColored=False):
        '''
        @brief: Gradients used for panels
        @param: painter QPainter
        @param: spanRect QRect
        @param: clipRect QRect
        @param: lightColored bool
        '''
        if self.usePixmapCache():
            key = ''
            keyColor = self.baseColor(lightColored)
            key = 'mh_vertical %s %s %s %s %s' % (
                spanRect.width(), spanRect.height(), clipRect.width(),
                clipRect.height(), keyColor.rgb())

            pixmap = QPixmapCache.find(key)
            if not pixmap:
                pixmap = QPixmap(clipRect.size())
                p = QPainter(pixmap)
                rect = QRect(0, 0, clipRect.width(), clipRect.height())
                self.verticalGradientHelper(p, spanRect, rect, lightColored)
                p.end()
                QPixmapCache.insert(key, pixmap)

            painter.drawPixmap(clipRect.topLeft(), pixmap)
        else:
            self.verticalGradientHelper(painter, spanRect, clipRect,
                                        lightColored)

    def usePixmapCache(self):
        return False

    def drawIconWithShadow(self,
                           icon,
                           rect,
                           painter,
                           iconMode,
                           radius=3,
                           color=QColor(0, 0, 0, 130),
                           offset=QPoint(1, -2)):
        '''
        @brief: Draw a cached pixmap with shadow
        @param: icon QIcon
        @param: rect QRect
        @param: painter QPainter
        @param: iconMode QIcon.Mode
        @param: radius int
        @param: color QColor
        @param: offset QPoint
        '''
        cache = QPixmap()
        pixmapName = 'icon %s %s %s' % (icon.cacheKey(), iconMode,
                                        rect.height())

        cache = QPixmapCache.find(pixmapName)
        if not cache:
            px = icon.pixmap(rect.size(), iconMode)
            px.setDevicePixelRatio(gVar.app.devicePixelRatio())
            cache = QPixmap(px.size() + QSize(radius * 2, radius * 2))
            cache.setDevicePixelRatio(px.devicePixelRatioF())
            cache.fill(Qt.transparent)

            cachePainter = QPainter(cache)

            # Draw shadow
            tmp = QImage(px.size() + QSize(radius * 2, radius * 2 + 1),
                         QImage.Format_ARGB32_Premultiplied)
            tmp.setDevicePixelRatio(px.devicePixelRatioF())
            tmp.fill(Qt.transparent)

            tmpPainter = QPainter(tmp)

            tmpPainter.setCompositionMode(QPainter.CompositionMode_Source)
            tmpPainter.drawPixmap(QPoint(radius, radius), px)
            tmpPainter.end()

            # blur the alpha channel
            blurred = QImage(tmp.size(), QImage.Format_ARGB32_Premultiplied)
            blurred.fill(Qt.transparent)
            blurPainter = QPainter(blurred)
            # TODO:
            #qt_blurImage(blurPainter, tmp, radius, False, True)
            blurPainter.end()

            tmp = blurred

            # blacken the image...
            tmpPainter.begin(tmp)
            tmpPainter.setCompositionMode(QPainter.CompositionMode_SourceIn)
            tmpPainter.fillRect(tmp.rect(), color)
            tmpPainter.end()

            tmpPainter.begin(tmp)
            tmpPainter.setCompositionMode(QPainter.CompositionMode_SourceIn)
            tmpPainter.fillRect(tmp.rect(), color)
            tmpPainter.end()

            # draw the blurred drop shadow...
            cachePainter.drawImage(
                QRect(0, 0,
                      cache.rect().width() / cache.devicePixelRatioF(),
                      cache.rect().height() / cache.devicePixelRatioF()), tmp)
            # Draw the actual pixmap...
            cachePainter.drawPixmap(QPoint(radius, radius) + offset, px)
            if self.usePixmapCache():
                QPixmapCache.insert(pixmapName, cache)

            sip.delete(cachePainter)
            sip.delete(tmpPainter)
            sip.delete(blurPainter)

        targetRect = QRect(cache.rect())
        targetRect.setWidth(cache.rect().width() / cache.devicePixelRatioF())
        targetRect.setHeight(cache.rect().height() / cache.devicePixelRatioF())
        targetRect.moveCenter(rect.center())
        painter.drawPixmap(targetRect.topLeft() - offset, cache)