############################################################################ ## ## Copyright (C) 2004-2005 Trolltech AS. All rights reserved. ## ## This file is part of the example classes of the Qt Toolkit. ## ## This file may be used under the terms of the GNU General Public ## License version 2.0 as published by the Free Software Foundation ## and appearing in the file LICENSE.GPL included in the packaging of ## this file. Please review the following information to ensure GNU ## General Public Licensing requirements will be met: ## http://www.trolltech.com/products/qt/opensource.html ## ## If you are unsure which license is appropriate for your use, please ## review the following information: ## http://www.trolltech.com/products/qt/licensing.html or contact the ## sales department at sales@trolltech.com. ## ## This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ## WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ## ############################################################################ from math import ceil from PyQt4 import QtCore, QtGui, QtNetwork, QtXml class DisplayShape: def __init__(self, position, maxSize): self.metadata = {} self.image = QtGui.QImage() self.pos = position self.targetPos = QtCore.QPointF() self.maxSize = maxSize self.interactive = False def animate(self): if not self.targetPos.isNull(): displacement = QtCore.QLineF(self.pos, self.targetPos) newPosition = displacement.pointAt(0.25) if displacement.length() <= 1.0: self.pos = self.targetPos self.targetPos = QtCore.QPointF() else: self.pos = newPosition return True return False def isInteractive(self): return self.interactive def paint(self, painter): painter.save() painter.drawImage(self.pos, self.image) painter.restore() def position(self): return self.pos def rect(self): return QtCore.QRectF(self.pos, self.image.size()) def setInteractive(self, enable): self.interactive = enable def setPosition(self, position): self.pos = position def setSize(self, size): self.maxSize = size def setTarget(self, position): self.targetPos = position def size(self): return self.maxSize def target(self): return self.targetPos class PanelShape(DisplayShape): def __init__(self, path, normal, highlighted, pen, position, maxSize): DisplayShape.__init__(self, position, maxSize) self.normalBrush = normal self.path = path self.highlightedBrush = highlighted self.pen = pen self.brush = QtGui.QBrush(self.normalBrush) def animate(self): updated = False if not "destroy" in self.metadata: if "fade" in self.metadata: penColor = self.pen.color() brushColor = self.brush.color() penAlpha = penColor.alpha() brushAlpha = brushColor.alpha() fadeMinimum = int(self.metadata.get("fade minimum", "0")) if penAlpha != fadeMinimum or brushAlpha != fadeMinimum or self.metadata["fade"] > 0: penAlpha = max(fadeMinimum, min(penAlpha + self.metadata["fade"], 255)) brushAlpha = max(fadeMinimum, min(brushAlpha + self.metadata["fade"], 255)) penColor.setAlpha(penAlpha) brushColor.setAlpha(brushAlpha) self.pen.setColor(penColor) self.brush.setColor(brushColor) if penAlpha == 0 and brushAlpha == 0: self.metadata["destroy"] = True del self.metadata["fade"] elif penAlpha == 255 and brushAlpha == 255: del self.metadata["fade"] updated = True elif "highlight" in self.metadata: scale = float(self.metadata.get("highlight scale", "0.0")) color = QtGui.QColor(self.brush.color()) if self.metadata["highlight"]: scale = max(0.0, min(scale + 0.5, 1.0)) else: scale = max(0.0, min(scale - 0.2, 1.0)) if scale == 0.0: self.brush = QtGui.QBrush(self.normalBrush) del self.metadata["highlight"] try: del self.metadata["highlight scale"] except KeyError: pass updated = True elif scale != float(self.metadata.get("highlight scale", "0.0")): self.metadata["highlight scale"] = scale if scale == 1.0: self.brush = QtGui.QBrush(self.highlightedBrush) else: normal = self.normalBrush.color() highlighted = self.highlightedBrush.color() color.setRedF((1.0 - scale) * normal.redF() + scale * highlighted.redF()) color.setGreenF((1.0 - scale) * normal.greenF() + scale * highlighted.greenF()) color.setBlueF((1.0 - scale) * normal.blueF() + scale * highlighted.blueF()) self.brush.setColor(color) updated = True return (DisplayShape.animate(self) or updated) def paint(self, painter): painter.save() painter.setRenderHint(QtGui.QPainter.Antialiasing) painter.setBrush(self.brush) painter.setPen(self.pen) painter.translate(self.pos) painter.drawPath(self.path) painter.restore() def rect(self): return QtCore.QRectF(self.pos + self.path.boundingRect().topLeft(), self.path.boundingRect().size()) class TitleShape(DisplayShape): def __init__(self, text, font, pen, position, maxSize, alignment=QtCore.Qt.AlignVCenter|QtCore.Qt.AlignLeft): DisplayShape.__init__(self, position, maxSize) self.font = QtGui.QFont(font) self.text = QtCore.QString(text) self.pen = pen self.alignment = alignment fm = QtGui.QFontMetricsF(self.font) self.textRect = fm.boundingRect(QtCore.QRectF(QtCore.QPointF(0, 0), maxSize), self.alignment, self.text) textWidth = max(fm.width(self.text), self.textRect.width()) textHeight = max(fm.height(), self.textRect.height()) scale = min(maxSize.width() / textWidth, maxSize.height() / textHeight) self.font.setPointSizeF(self.font.pointSizeF() * scale) fm = QtGui.QFontMetricsF(self.font) self.textRect = fm.boundingRect(QtCore.QRectF(QtCore.QPointF(0, 0), maxSize), self.alignment, self.text) self.baselineStart = QtCore.QPointF(self.textRect.left(), self.textRect.bottom() - fm.descent()) def animate(self): updated = False if "destroy" not in self.metadata: if "fade" in self.metadata: penColor = self.pen.color() penAlpha = penColor.alpha() penAlpha = max(int(self.metadata.get("fade minimum", "0")), min(penAlpha + self.metadata["fade"], 255)) penColor.setAlpha(penAlpha) self.pen.setColor(penColor) if penAlpha == 0: self.metadata["destroy"] = True del self.metadata["fade"] elif penAlpha == 255: del self.metadata["fade"] updated = True return (DisplayShape.animate(self) or updated) def paint(self, painter): rect = QtCore.QRectF(self.textRect) rect.translate(self.pos) painter.save() painter.setRenderHint(QtGui.QPainter.TextAntialiasing) painter.setPen(self.pen) painter.setFont(self.font) painter.drawText(self.pos + self.baselineStart, self.text) painter.restore() def rect(self): rect = QtCore.QRectF(self.textRect) return rect.translated(self.pos) class ImageShape(DisplayShape): def __init__(self, original, position, maxSize, alpha=0, alignment=QtCore.Qt.AlignCenter): DisplayShape.__init__(self, position, maxSize) self.alpha = alpha self.alignment = alignment self.source = original.convertToFormat(QtGui.QImage.Format_ARGB32_Premultiplied) scale = min(min(self.maxSize.width() / self.source.width(), self.maxSize.height() / self.source.height()), 1.0) self.source = self.source.scaled(int(ceil(self.source.width() * scale)), int(ceil(self.source.height() * scale)), QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation) self.image = QtGui.QImage(self.source.size(), QtGui.QImage.Format_ARGB32_Premultiplied) self.offset = QtCore.QPointF(0.0, 0.0) if self.alignment & QtCore.Qt.AlignHCenter: self.offset.setX((self.maxSize.width() - self.image.width()) / 2) elif self.alignment & QtCore.Qt.AlignRight: self.offset.setX(self.maxSize.width() - self.image.width()) if alignment & QtCore.Qt.AlignVCenter: self.offset.setY((self.maxSize.height() - self.image.height()) / 2) elif self.alignment & QtCore.Qt.AlignBottom: self.offset.setY(self.maxSize.height() - self.image.height()) self.redraw() def redraw(self): self.image.fill(QtGui.qRgba(self.alpha, self.alpha, self.alpha, self.alpha)) painter = QtGui.QPainter() painter.begin(self.image) painter.setCompositionMode(QtGui.QPainter.CompositionMode_SourceIn) painter.drawImage(0, 0, self.source) painter.end() def paint(self, painter): painter.drawImage(self.pos + self.offset, self.image) def rect(self): return QtCore.QRectF(self.pos, self.maxSize) def animate(self): updated = False if "destroy" not in self.metadata: if "fade" in self.metadata: self.alpha = max(int(self.metadata.get("fade minimum", "0")), min(self.alpha + self.metadata["fade"], 255)) self.redraw() if self.alpha == 0: self.metadata["destroy"] = True del self.metadata["fade"] elif self.alpha == 255: del self.metadata["fade"] updated = True return (DisplayShape.animate(self) or updated) class DocumentShape(DisplayShape): def __init__(self, text, font, position, maxSize, alpha=0): DisplayShape.__init__(self, position, maxSize) self.alpha = alpha self.textDocument = QtGui.QTextDocument() self.textDocument.setHtml(text) self.textDocument.setDefaultFont(font) self.textDocument.setPageSize(maxSize) documentSize = self.textDocument.documentLayout().documentSize() self.setSize(QtCore.QSizeF(self.maxSize.width(), min(self.maxSize.height(), documentSize.height()))) self.source = QtGui.QImage(int(ceil(documentSize.width())), int(ceil(documentSize.height())), QtGui.QImage.Format_ARGB32_Premultiplied) self.source.fill(QtGui.qRgba(255, 255, 255, 255)) context = QtGui.QAbstractTextDocumentLayout.PaintContext() self.textDocument.documentLayout().setPaintDevice(self.source) painter = QtGui.QPainter() painter.begin(self.source) painter.setRenderHint(QtGui.QPainter.TextAntialiasing) painter.setRenderHint(QtGui.QPainter.Antialiasing) self.textDocument.documentLayout().draw(painter, context) painter.end() self.source = self.source.scaled(int(ceil(self.maxSize.width())), int(ceil(self.maxSize.height())), QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation) self.image = QtGui.QImage(self.source.size(), self.source.format()) self.redraw() def animate(self): updated = False if "destroy" not in self.metadata: if "fade" in self.metadata: self.alpha = max(int(self.metadata.get("fade minimum", "0")), min(self.alpha + self.metadata["fade"], 255)) self.redraw() if self.alpha == 0: self.metadata["destroy"] = True del self.metadata["fade"] elif self.alpha == 255: del self.metadata["fade"] updated = True return (DisplayShape.animate(self) or updated) def redraw(self): self.image.fill(QtGui.qRgba(self.alpha, self.alpha, self.alpha, self.alpha)) painter = QtGui.QPainter() painter.begin(self.image) painter.setCompositionMode(QtGui.QPainter.CompositionMode_SourceIn) painter.drawImage(0, 0, self.source) painter.end() def paint(self, painter): painter.drawImage(self.pos, self.image) def rect(self): return QtCore.QRectF(self.pos, self.maxSize)