summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjørn Erik Nilsen <bjorn.nilsen@nokia.com>2009-08-28 08:31:31 (GMT)
committerBjørn Erik Nilsen <bjorn.nilsen@nokia.com>2009-08-28 14:34:16 (GMT)
commitd6d49aa56750359012cdf722df27b0a1c3e5b2aa (patch)
treeeac4337828535ff4b8f120ffb03b77efd5a0d812
parentc3df6e12309164a6fa0cf76546a354c5d59c5374 (diff)
downloadQt-d6d49aa56750359012cdf722df27b0a1c3e5b2aa.zip
Qt-d6d49aa56750359012cdf722df27b0a1c3e5b2aa.tar.gz
Qt-d6d49aa56750359012cdf722df27b0a1c3e5b2aa.tar.bz2
Add support for setting an opacity mask on QGraphicsOpacityEffect.
Opacity masks enable you to make portions of an element transparent. More information about opacity masks here: http://msdn.microsoft.com/en-us/library/ms743320.aspx Reviewed-by: Samuel
-rw-r--r--doc/src/snippets/code/src_gui_effects_qgraphicseffect.cpp10
-rw-r--r--src/gui/effects/qgraphicseffect.cpp93
-rw-r--r--src/gui/effects/qgraphicseffect.h5
-rw-r--r--src/gui/effects/qgraphicseffect_p.h4
4 files changed, 106 insertions, 6 deletions
diff --git a/doc/src/snippets/code/src_gui_effects_qgraphicseffect.cpp b/doc/src/snippets/code/src_gui_effects_qgraphicseffect.cpp
index 6265c80..152b04f 100644
--- a/doc/src/snippets/code/src_gui_effects_qgraphicseffect.cpp
+++ b/doc/src/snippets/code/src_gui_effects_qgraphicseffect.cpp
@@ -31,3 +31,13 @@ MyGraphicsEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
}
//! [1]
+//! [2]
+...
+QLinearGradient alphaGradient(rect.topLeft(), rect.bottomLeft());
+alphaGradient.setColorAt(0.0, Qt::transparent);
+alphaGradient.setColorAt(0.5, Qt::black);
+alphaGradient.setColorAt(1.0, Qt::transparent);
+QGraphicsOpacityEffect *effect = new QGraphicsOpacityEffect;
+effect->setOpacityMask(alphaGradient);
+...
+//! [2]
diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp
index 5f64698..62ad44d 100644
--- a/src/gui/effects/qgraphicseffect.cpp
+++ b/src/gui/effects/qgraphicseffect.cpp
@@ -990,6 +990,8 @@ QGraphicsOpacityEffect::~QGraphicsOpacityEffect()
fully transparent and 1.0 is fully opaque.
By default, the opacity is 0.7.
+
+ \sa setOpacityMask()
*/
qreal QGraphicsOpacityEffect::opacity() const
{
@@ -1017,6 +1019,45 @@ void QGraphicsOpacityEffect::setOpacity(qreal opacity)
*/
/*!
+ \property QGraphicsOpacityEffect::opacityMask
+ \brief the opacity mask of the effect.
+
+ An opacity mask allows you apply opacity to portions of an element.
+
+ For example:
+
+ \snippet doc/src/snippets/code/src_gui_effects_qgraphicseffect.cpp 2
+
+ There is no opacity mask by default.
+
+ \sa setOpacity()
+*/
+QBrush QGraphicsOpacityEffect::opacityMask() const
+{
+ Q_D(const QGraphicsOpacityEffect);
+ return d->opacityMask;
+}
+
+void QGraphicsOpacityEffect::setOpacityMask(const QBrush &mask)
+{
+ Q_D(QGraphicsOpacityEffect);
+ if (d->opacityMask == mask)
+ return;
+
+ d->opacityMask = mask;
+ d->hasOpacityMask = (mask.style() != Qt::NoBrush);
+
+ emit opacityMaskChanged(mask);
+}
+
+/*!
+ \fn void QGraphicsOpacityEffect::opacityMaskChanged(const QBrush &mask)
+
+ This signal is emitted whenever the effect's opacity mask changes.
+ The \a mask parameter holds the effect's new opacity mask.
+*/
+
+/*!
\reimp
*/
void QGraphicsOpacityEffect::draw(QPainter *painter, QGraphicsEffectSource *source)
@@ -1039,13 +1080,55 @@ void QGraphicsOpacityEffect::draw(QPainter *painter, QGraphicsEffectSource *sour
QPoint offset;
if (source->isPixmap()) {
// No point in drawing in device coordinates (pixmap will be scaled anyways).
- const QPixmap pixmap = source->pixmap(Qt::LogicalCoordinates, &offset);
- painter->drawPixmap(offset, pixmap);
+ if (!d->hasOpacityMask) {
+ const QPixmap pixmap = source->pixmap(Qt::LogicalCoordinates, &offset);
+ painter->drawPixmap(offset, pixmap);
+ } else {
+ QRectF srcBrect = source->boundingRect();
+ QPixmap pixmap(srcBrect.size().toSize());
+ pixmap.fill(Qt::transparent);
+
+ QPainter pixmapPainter(&pixmap);
+ pixmapPainter.setRenderHints(painter->renderHints());
+ pixmapPainter.translate(-srcBrect.topLeft());
+ source->draw(&pixmapPainter);
+ pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
+ pixmapPainter.fillRect(srcBrect, d->opacityMask);
+ pixmapPainter.end();
+
+ painter->drawPixmap(srcBrect.topLeft(), pixmap);
+ }
} else {
// Draw pixmap in device coordinates to avoid pixmap scaling;
- const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset);
- painter->setWorldTransform(QTransform());
- painter->drawPixmap(offset, pixmap);
+ if (!d->hasOpacityMask) {
+ const QPixmap pixmap = source->pixmap(Qt::DeviceCoordinates, &offset);
+ painter->setWorldTransform(QTransform());
+ painter->drawPixmap(offset, pixmap);
+ } else {
+ QTransform worldTransform = painter->worldTransform();
+
+ // Calculate source bounding rect in logical and device coordinates.
+ QRectF srcBrect = source->boundingRect();
+ QRect srcDeviceBrect = worldTransform.mapRect(srcBrect).toAlignedRect();
+ srcDeviceBrect &= source->deviceRect();
+
+ offset = srcDeviceBrect.topLeft();
+ worldTransform *= QTransform::fromTranslate(-srcDeviceBrect.x(), -srcDeviceBrect.y());
+
+ QPixmap pixmap(srcDeviceBrect.size());
+ pixmap.fill(Qt::transparent);
+
+ QPainter pixmapPainter(&pixmap);
+ pixmapPainter.setRenderHints(painter->renderHints());
+ pixmapPainter.setWorldTransform(worldTransform);
+ source->draw(&pixmapPainter);
+ pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
+ pixmapPainter.fillRect(srcBrect, d->opacityMask);
+ pixmapPainter.end();
+
+ painter->setWorldTransform(QTransform());
+ painter->drawPixmap(offset, pixmap);
+ }
}
painter->restore();
diff --git a/src/gui/effects/qgraphicseffect.h b/src/gui/effects/qgraphicseffect.h
index fef6531..a53357b 100644
--- a/src/gui/effects/qgraphicseffect.h
+++ b/src/gui/effects/qgraphicseffect.h
@@ -46,6 +46,7 @@
#include <QtCore/qpoint.h>
#include <QtCore/qrect.h>
#include <QtGui/qcolor.h>
+#include <QtGui/qbrush.h>
QT_BEGIN_HEADER
@@ -274,17 +275,21 @@ class Q_GUI_EXPORT QGraphicsOpacityEffect: public QGraphicsEffect
{
Q_OBJECT
Q_PROPERTY(int opacity READ opacity WRITE setOpacity NOTIFY opacityChanged)
+ Q_PROPERTY(QBrush opacityMask READ opacityMask WRITE setOpacityMask NOTIFY opacityMaskChanged)
public:
QGraphicsOpacityEffect(QObject *parent = 0);
~QGraphicsOpacityEffect();
qreal opacity() const;
+ QBrush opacityMask() const;
public Q_SLOTS:
void setOpacity(qreal opacity);
+ void setOpacityMask(const QBrush &mask);
Q_SIGNALS:
void opacityChanged(qreal opacity);
+ void opacityMaskChanged(const QBrush &mask);
protected:
void draw(QPainter *painter, QGraphicsEffectSource *source);
diff --git a/src/gui/effects/qgraphicseffect_p.h b/src/gui/effects/qgraphicseffect_p.h
index 6ce5cda..e0a77e7 100644
--- a/src/gui/effects/qgraphicseffect_p.h
+++ b/src/gui/effects/qgraphicseffect_p.h
@@ -164,10 +164,12 @@ class QGraphicsOpacityEffectPrivate : public QGraphicsEffectPrivate
{
Q_DECLARE_PUBLIC(QGraphicsOpacityEffect)
public:
- QGraphicsOpacityEffectPrivate() : opacity(qreal(0.7)) {}
+ QGraphicsOpacityEffectPrivate() : opacity(qreal(0.7)), hasOpacityMask(0) {}
~QGraphicsOpacityEffectPrivate() {}
qreal opacity;
+ QBrush opacityMask;
+ uint hasOpacityMask : 1;
};
QT_END_NAMESPACE