summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/graphicsview/blurpicker/blureffect.cpp19
-rw-r--r--examples/graphicsview/blurpicker/blureffect.h11
-rw-r--r--examples/graphicsview/blurpicker/blurpicker.cpp6
-rw-r--r--examples/graphicsview/blurpicker/blurpicker.h1
-rw-r--r--examples/graphicsview/lighting/lighting.cpp4
-rw-r--r--examples/graphicsview/lighting/lighting.h1
-rw-r--r--examples/graphicsview/lighting/shadoweffect.cpp21
-rw-r--r--examples/graphicsview/lighting/shadoweffect.h11
-rw-r--r--src/gui/graphicsview/graphicsview.pri3
-rw-r--r--src/gui/graphicsview/qgraphicseffect.cpp396
-rw-r--r--src/gui/graphicsview/qgraphicseffect.h93
-rw-r--r--src/gui/graphicsview/qgraphicseffect_p.h171
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp100
-rw-r--r--src/gui/graphicsview/qgraphicsitem.h6
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h45
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp72
-rw-r--r--src/gui/graphicsview/qgraphicsscene.h5
17 files changed, 488 insertions, 477 deletions
diff --git a/examples/graphicsview/blurpicker/blureffect.cpp b/examples/graphicsview/blurpicker/blureffect.cpp
index 8345d0b..43791c6 100644
--- a/examples/graphicsview/blurpicker/blureffect.cpp
+++ b/examples/graphicsview/blurpicker/blureffect.cpp
@@ -43,28 +43,27 @@
#include <QDebug>
-BlurEffect::BlurEffect(QObject *parent)
+BlurEffect::BlurEffect(QGraphicsItem *item)
: QGraphicsBlurEffect()
- , m_baseLine(200)
+ , m_baseLine(200), item(item)
{
}
-void BlurEffect::adjustForItem(const QGraphicsItem *item)
+void BlurEffect::adjustForItem()
{
qreal y = m_baseLine - item->pos().y();
qreal radius = qBound(0.0, y / 32, 16.0);
setBlurRadius(radius);
}
-QRectF BlurEffect::boundingRectFor(const QGraphicsItem *item)
+QRectF BlurEffect::boundingRect() const
{
- adjustForItem(item);
- return QGraphicsBlurEffect::boundingRectFor(item);
+ const_cast<BlurEffect *>(this)->adjustForItem();
+ return QGraphicsBlurEffect::boundingRect();
}
-void BlurEffect::drawItem(QGraphicsItem *item, QPainter *painter,
- const QStyleOptionGraphicsItem *option, QWidget *widget)
+void BlurEffect::draw(QPainter *painter)
{
- adjustForItem(item);
- QGraphicsBlurEffect::drawItem(item, painter, option, widget);
+ adjustForItem();
+ QGraphicsBlurEffect::draw(painter);
}
diff --git a/examples/graphicsview/blurpicker/blureffect.h b/examples/graphicsview/blurpicker/blureffect.h
index 24a6867..2aea8bf 100644
--- a/examples/graphicsview/blurpicker/blureffect.h
+++ b/examples/graphicsview/blurpicker/blureffect.h
@@ -48,21 +48,20 @@
class BlurEffect: public QGraphicsBlurEffect
{
public:
- BlurEffect(QObject *parent = 0);
+ BlurEffect(QGraphicsItem *item);
void setBaseLine(qreal y) { m_baseLine = y; }
- QRectF boundingRectFor(const QGraphicsItem *item);
+ QRectF boundingRect() const;
- void drawItem(QGraphicsItem *item, QPainter *painter,
- const QStyleOptionGraphicsItem *option = 0,
- QWidget *widget = 0);
+ void draw(QPainter *painter);
private:
- void adjustForItem(const QGraphicsItem *item);
+ void adjustForItem();
private:
qreal m_baseLine;
+ QGraphicsItem *item;
};
#endif // BLUREFFECT_H
diff --git a/examples/graphicsview/blurpicker/blurpicker.cpp b/examples/graphicsview/blurpicker/blurpicker.cpp
index 887d7ef..9904dfa 100644
--- a/examples/graphicsview/blurpicker/blurpicker.cpp
+++ b/examples/graphicsview/blurpicker/blurpicker.cpp
@@ -79,9 +79,9 @@ void BlurPicker::updateIconPositions()
pos -= QPointF(40, 40);
icon->setPos(pos);
baseline = qMax(baseline, ys);
+ static_cast<BlurEffect *>(icon->graphicsEffect())->setBaseLine(baseline);
}
- m_blurEffect->setBaseLine(baseline);
m_scene.update();
}
@@ -89,8 +89,6 @@ void BlurPicker::setupScene()
{
m_scene.setSceneRect(-200, -120, 400, 240);
- m_blurEffect = new BlurEffect(this);
-
QStringList names;
names << ":/images/accessories-calculator.png";
names << ":/images/accessories-text-editor.png";
@@ -105,7 +103,7 @@ void BlurPicker::setupScene()
QPixmap pixmap(names[i]);
QGraphicsPixmapItem *icon = m_scene.addPixmap(pixmap);
icon->setZValue(1);
- icon->setEffect(m_blurEffect);
+ icon->setGraphicsEffect(new BlurEffect(icon));
m_icons << icon;
}
diff --git a/examples/graphicsview/blurpicker/blurpicker.h b/examples/graphicsview/blurpicker/blurpicker.h
index e41c608..b7ea3b4 100644
--- a/examples/graphicsview/blurpicker/blurpicker.h
+++ b/examples/graphicsview/blurpicker/blurpicker.h
@@ -67,7 +67,6 @@ private:
private:
qreal m_index;
QGraphicsScene m_scene;
- BlurEffect *m_blurEffect;
QList<QGraphicsItem*> m_icons;
QTimeLine m_timeLine;
};
diff --git a/examples/graphicsview/lighting/lighting.cpp b/examples/graphicsview/lighting/lighting.cpp
index 445d7f9..63f0a6c 100644
--- a/examples/graphicsview/lighting/lighting.cpp
+++ b/examples/graphicsview/lighting/lighting.cpp
@@ -88,8 +88,6 @@ void Lighting::setupScene()
m_lightSource = m_scene.addPixmap(pixmap);
m_lightSource->setZValue(2);
- m_shadowEffect = new ShadowEffect(m_lightSource, this);
-
for (int i = -2; i < 3; ++i)
for (int j = -2; j < 3; ++j) {
QAbstractGraphicsShapeItem *item;
@@ -100,7 +98,7 @@ void Lighting::setupScene()
item->setPen(QPen(Qt::black));
item->setBrush(QBrush(Qt::white));
- item->setEffect(m_shadowEffect);
+ item->setGraphicsEffect(new ShadowEffect(item, m_lightSource));
item->setZValue(1);
item->setPos(i * 80, j * 80);
m_scene.addItem(item);
diff --git a/examples/graphicsview/lighting/lighting.h b/examples/graphicsview/lighting/lighting.h
index 66237f6..70a4d48 100644
--- a/examples/graphicsview/lighting/lighting.h
+++ b/examples/graphicsview/lighting/lighting.h
@@ -64,7 +64,6 @@ private:
qreal angle;
QGraphicsScene m_scene;
QGraphicsItem *m_lightSource;
- ShadowEffect *m_shadowEffect;
QList<QGraphicsItem*> m_items;
};
diff --git a/examples/graphicsview/lighting/shadoweffect.cpp b/examples/graphicsview/lighting/shadoweffect.cpp
index 726cbd0..e2dd864 100644
--- a/examples/graphicsview/lighting/shadoweffect.cpp
+++ b/examples/graphicsview/lighting/shadoweffect.cpp
@@ -43,14 +43,14 @@
#include <math.h>
-ShadowEffect::ShadowEffect(QGraphicsItem *source, QObject *parent)
- : QGraphicsShadowEffect(parent)
- , m_lightSource(source)
+ShadowEffect::ShadowEffect(QGraphicsItem *item, QGraphicsItem *source)
+ : QGraphicsShadowEffect()
+ , item(item), m_lightSource(source)
{
setBlurRadius(8);
}
-void ShadowEffect::adjustForItem(const QGraphicsItem *item)
+void ShadowEffect::adjustForItem()
{
QPointF delta = item->pos() - m_lightSource->pos();
setShadowOffset(delta.toPoint() / 30);
@@ -61,15 +61,14 @@ void ShadowEffect::adjustForItem(const QGraphicsItem *item)
setOpacity(qBound(0.4, 1 - dd / 200.0, 0.7));
}
-QRectF ShadowEffect::boundingRectFor(const QGraphicsItem *item)
+QRectF ShadowEffect::boundingRect() const
{
- adjustForItem(item);
- return QGraphicsShadowEffect::boundingRectFor(item);
+ const_cast<ShadowEffect *>(this)->adjustForItem();
+ return QGraphicsShadowEffect::boundingRect();
}
-void ShadowEffect::drawItem(QGraphicsItem *item, QPainter *painter,
- const QStyleOptionGraphicsItem *option, QWidget *widget)
+void ShadowEffect::draw(QPainter *painter)
{
- adjustForItem(item);
- QGraphicsShadowEffect::drawItem(item, painter, option, widget);
+ adjustForItem();
+ QGraphicsShadowEffect::draw(painter);
}
diff --git a/examples/graphicsview/lighting/shadoweffect.h b/examples/graphicsview/lighting/shadoweffect.h
index 02d0bf1..d4aa440 100644
--- a/examples/graphicsview/lighting/shadoweffect.h
+++ b/examples/graphicsview/lighting/shadoweffect.h
@@ -48,18 +48,17 @@
class ShadowEffect: public QGraphicsShadowEffect
{
public:
- ShadowEffect(QGraphicsItem *source, QObject *parent = 0);
+ ShadowEffect(QGraphicsItem *item, QGraphicsItem *source);
- QRectF boundingRectFor(const QGraphicsItem *item);
+ QRectF boundingRect() const;
- void drawItem(QGraphicsItem *item, QPainter *painter,
- const QStyleOptionGraphicsItem *option = 0,
- QWidget *widget = 0);
+ void draw(QPainter *painter);
private:
- void adjustForItem(const QGraphicsItem *item);
+ void adjustForItem();
private:
+ QGraphicsItem *item;
QGraphicsItem *m_lightSource;
};
diff --git a/src/gui/graphicsview/graphicsview.pri b/src/gui/graphicsview/graphicsview.pri
index c3cb574..55bb9e0 100644
--- a/src/gui/graphicsview/graphicsview.pri
+++ b/src/gui/graphicsview/graphicsview.pri
@@ -21,7 +21,8 @@ HEADERS += graphicsview/qgraphicsgridlayout.h \
graphicsview/qgraphicswidget.h \
graphicsview/qgraphicswidget_p.h \
graphicsview/qgridlayoutengine_p.h \
- graphicsview/qgraphicseffect.h
+ graphicsview/qgraphicseffect.h \
+ graphicsview/qgraphicseffect_p.h \
SOURCES += graphicsview/qgraphicsgridlayout.cpp \
graphicsview/qgraphicsitem.cpp \
diff --git a/src/gui/graphicsview/qgraphicseffect.cpp b/src/gui/graphicsview/qgraphicseffect.cpp
index 6b1f12a..8d2c416 100644
--- a/src/gui/graphicsview/qgraphicseffect.cpp
+++ b/src/gui/graphicsview/qgraphicseffect.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "qgraphicseffect.h"
+#include "qgraphicseffect_p.h"
#ifndef QT_NO_GRAPHICSVIEW
@@ -48,9 +48,6 @@
#include <QtGui/qgraphicsscene.h>
#include <QtGui/qpainter.h>
-#include <private/qobject_p.h>
-#include <private/qpixmapfilter_p.h>
-
/*
List of known drawbacks which are being discussed:
@@ -105,128 +102,92 @@
*/
+QGraphicsEffect::QGraphicsEffect()
+ : QObject(*new QGraphicsEffectPrivate, 0)
+{}
+
/*!
\internal
*/
-class QGraphicsEffectPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsEffect)
-public:
- QGraphicsEffectPrivate() {}
-};
-
-QGraphicsEffect::QGraphicsEffect(QObject *parent)
- : QObject(*new QGraphicsEffectPrivate, parent)
-{
-}
+QGraphicsEffect::QGraphicsEffect(QGraphicsEffectPrivate &dd)
+ : QObject(dd, 0)
+{}
QGraphicsEffect::~QGraphicsEffect()
{
+ Q_D(QGraphicsEffect);
+ d->setGraphicsEffectSource(0);
}
-QRectF QGraphicsEffect::boundingRectFor(const QGraphicsItem *item)
+QRectF QGraphicsEffect::boundingRect() const
{
- // default is to give the item's bounding rect
- // do NOT call item->effectiveBoundRect() because
- // that function will call this one (infinite loop)
- return item->boundingRect();
+ return sourceBoundingRect();
}
-/*! \internal
-*/
-QGraphicsEffect::QGraphicsEffect(QGraphicsEffectPrivate &dd, QObject *parent)
- : QObject(dd, parent)
+QRectF QGraphicsEffect::sourceBoundingRect() const
{
+ Q_D(const QGraphicsEffect);
+ if (d->source)
+ return d->source->boundingRect();
+ return QRectF();
}
-// this helper function is only for subclasses of QGraphicsEffect
-// the implementation is trivial, but this allows us to keep
-// QGraphicsScene::drawItem() as a protected function
-// (since QGraphicsEffect is a friend of QGraphicsScene)
-QPixmap* QGraphicsEffect::drawItemOnPixmap(QPainter *painter, QGraphicsItem *item,
- const QStyleOptionGraphicsItem *option, QWidget *widget, int flags)
+void QGraphicsEffect::drawSource(QPainter *painter)
{
- if (!item->scene())
- return 0;
- return item->scene()->drawItemOnPixmap(painter, item, option, widget, flags);
+ Q_D(QGraphicsEffect);
+ if (d->source)
+ d->source->draw(painter);
}
-/*!
- \internal
-*/
-class QGraphicsGrayscaleEffectPrivate : public QGraphicsEffectPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsGrayscaleEffect)
-public:
- QGraphicsGrayscaleEffectPrivate() {
- filter = new QPixmapColorizeFilter;
- filter->setColor(Qt::black);
- }
-
- ~QGraphicsGrayscaleEffectPrivate() {
- delete filter;
- }
-
- QPixmapColorizeFilter *filter;
-};
-
-QGraphicsGrayscaleEffect::QGraphicsGrayscaleEffect(QObject *parent)
- : QGraphicsEffect(*new QGraphicsGrayscaleEffectPrivate, parent)
+bool QGraphicsEffect::drawSourceIntoPixmap(QPixmap *pixmap, const QTransform &itemToPixmapTransform)
{
+ Q_D(QGraphicsEffect);
+ if (d->source)
+ return d->source->drawIntoPixmap(pixmap, itemToPixmapTransform);
+ return false;
}
+QGraphicsGrayscaleEffect::QGraphicsGrayscaleEffect()
+ : QGraphicsEffect(*new QGraphicsGrayscaleEffectPrivate)
+{}
+
QGraphicsGrayscaleEffect::~QGraphicsGrayscaleEffect()
-{
-}
+{}
-void QGraphicsGrayscaleEffect::drawItem(QGraphicsItem *item, QPainter *painter,
- const QStyleOptionGraphicsItem *option, QWidget *widget)
+void QGraphicsGrayscaleEffect::draw(QPainter *painter)
{
Q_D(QGraphicsGrayscaleEffect);
+ if (!d->source)
+ return;
// Find the item's bounds in device coordinates.
- QRectF deviceBounds = painter->worldTransform().mapRect(item->boundingRect());
+ QTransform itemToPixmapTransform(painter->worldTransform());
+ QRectF deviceBounds = itemToPixmapTransform.mapRect(d->source->boundingRect());
QRect deviceRect = deviceBounds.toRect().adjusted(-1, -1, 1, 1);
if (deviceRect.isEmpty())
return;
- QPixmap *pixmap = QGraphicsEffect::drawItemOnPixmap(painter, item, option, widget, 0);
- if (!pixmap)
+ if (deviceRect.x() != 0 || deviceRect.y() != 0)
+ itemToPixmapTransform *= QTransform::fromTranslate(-deviceRect.x(), -deviceRect.y());
+
+ QPixmap pixmap(deviceRect.size());
+ if (!d->source->drawIntoPixmap(&pixmap, itemToPixmapTransform))
return;
// Draw the pixmap with the filter using an untransformed painter.
QTransform restoreTransform = painter->worldTransform();
painter->setWorldTransform(QTransform());
- d->filter->draw(painter, deviceRect.topLeft(), *pixmap, pixmap->rect());
+ d->filter->draw(painter, deviceRect.topLeft(), pixmap, pixmap.rect());
painter->setWorldTransform(restoreTransform);
-}
-
-/*!
- \internal
-*/
-class QGraphicsColorizeEffectPrivate : public QGraphicsEffectPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsColorizeEffect)
-public:
- QGraphicsColorizeEffectPrivate() {
- filter = new QPixmapColorizeFilter;
- }
-
- ~QGraphicsColorizeEffectPrivate() {
- delete filter;
- }
-
- QPixmapColorizeFilter *filter;
-};
-QGraphicsColorizeEffect::QGraphicsColorizeEffect(QObject *parent)
- : QGraphicsEffect(*new QGraphicsColorizeEffectPrivate, parent)
-{
}
+QGraphicsColorizeEffect::QGraphicsColorizeEffect()
+ : QGraphicsEffect(*new QGraphicsColorizeEffectPrivate)
+{}
+
QGraphicsColorizeEffect::~QGraphicsColorizeEffect()
-{
-}
+{}
QColor QGraphicsColorizeEffect::color() const
{
@@ -240,43 +201,35 @@ void QGraphicsColorizeEffect::setColor(const QColor &c)
d->filter->setColor(c);
}
-void QGraphicsColorizeEffect::drawItem(QGraphicsItem *item, QPainter *painter,
- const QStyleOptionGraphicsItem *option, QWidget *widget)
+void QGraphicsColorizeEffect::draw(QPainter *painter)
{
Q_D(QGraphicsColorizeEffect);
+ if (!d->source)
+ return;
// Find the item's bounds in device coordinates.
- QRectF deviceBounds = painter->worldTransform().mapRect(item->boundingRect());
+ QTransform itemToPixmapTransform(painter->worldTransform());
+ QRectF deviceBounds = itemToPixmapTransform.mapRect(d->source->boundingRect());
QRect deviceRect = deviceBounds.toRect().adjusted(-1, -1, 1, 1);
if (deviceRect.isEmpty())
return;
- QPixmap *pixmap = QGraphicsEffect::drawItemOnPixmap(painter, item, option, widget, 0);
- if (!pixmap)
+ if (deviceRect.x() != 0 || deviceRect.y() != 0)
+ itemToPixmapTransform *= QTransform::fromTranslate(-deviceRect.x(), -deviceRect.y());
+
+ QPixmap pixmap(deviceRect.size());
+ if (!d->source->drawIntoPixmap(&pixmap, itemToPixmapTransform))
return;
// Draw the pixmap with the filter using an untransformed painter.
QTransform restoreTransform = painter->worldTransform();
painter->setWorldTransform(QTransform());
- d->filter->draw(painter, deviceRect.topLeft(), *pixmap, pixmap->rect());
+ d->filter->draw(painter, deviceRect.topLeft(), pixmap, pixmap.rect());
painter->setWorldTransform(restoreTransform);
}
-/*!
- \internal
-*/
-class QGraphicsPixelizeEffectPrivate : public QGraphicsEffectPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsPixelizeEffect)
-public:
- QGraphicsPixelizeEffectPrivate()
- : pixelSize(3) { }
-
- int pixelSize;
-};
-
-QGraphicsPixelizeEffect::QGraphicsPixelizeEffect(QObject *parent)
- : QGraphicsEffect(*new QGraphicsPixelizeEffectPrivate, parent)
+QGraphicsPixelizeEffect::QGraphicsPixelizeEffect()
+ : QGraphicsEffect(*new QGraphicsPixelizeEffectPrivate)
{
}
@@ -296,23 +249,28 @@ void QGraphicsPixelizeEffect::setPixelSize(int size)
d->pixelSize = size;
}
-void QGraphicsPixelizeEffect::drawItem(QGraphicsItem *item, QPainter *painter,
- const QStyleOptionGraphicsItem *option, QWidget *widget)
+void QGraphicsPixelizeEffect::draw(QPainter *painter)
{
Q_D(QGraphicsPixelizeEffect);
+ if (!d->source)
+ return;
// Find the item's bounds in device coordinates.
- QRectF deviceBounds = painter->worldTransform().mapRect(item->boundingRect());
+ QTransform itemToPixmapTransform(painter->worldTransform());
+ QRectF deviceBounds = itemToPixmapTransform.mapRect(d->source->boundingRect());
QRect deviceRect = deviceBounds.toRect().adjusted(-1, -1, 1, 1);
if (deviceRect.isEmpty())
return;
- QPixmap *pixmap = QGraphicsEffect::drawItemOnPixmap(painter, item, option, widget, 0);
- if (!pixmap)
+ if (deviceRect.x() != 0 || deviceRect.y() != 0)
+ itemToPixmapTransform *= QTransform::fromTranslate(-deviceRect.x(), -deviceRect.y());
+
+ QPixmap pixmap(deviceRect.size());
+ if (!d->source->drawIntoPixmap(&pixmap))
return;
// pixelize routine
- QImage img = pixmap->toImage().convertToFormat(QImage::Format_ARGB32);
+ QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
if (d->pixelSize > 0) {
int width = img.width();
int height = img.height();
@@ -338,27 +296,8 @@ void QGraphicsPixelizeEffect::drawItem(QGraphicsItem *item, QPainter *painter,
painter->setWorldTransform(restoreTransform);
}
-/*!
- \internal
-*/
-class QGraphicsBlurEffectPrivate : public QGraphicsEffectPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsBlurEffect)
-public:
- QGraphicsBlurEffectPrivate()
- {
- filter = new QPixmapBlurFilter;
- }
- ~QGraphicsBlurEffectPrivate()
- {
- delete filter;
- }
-
- QPixmapBlurFilter *filter;
-};
-
-QGraphicsBlurEffect::QGraphicsBlurEffect(QObject *parent)
- : QGraphicsEffect(*new QGraphicsBlurEffectPrivate, parent)
+QGraphicsBlurEffect::QGraphicsBlurEffect()
+ : QGraphicsEffect(*new QGraphicsBlurEffectPrivate)
{
}
@@ -443,51 +382,47 @@ void QGraphicsBlurEffect::setBlurRadius(int radius)
d->filter->setBlurRadius(radius);
}
-QRectF QGraphicsBlurEffect::boundingRectFor(const QGraphicsItem *item)
+QRectF QGraphicsBlurEffect::boundingRect() const
{
Q_D(const QGraphicsBlurEffect);
- return d->filter->boundingRectFor(item->boundingRect());
+ if (d->source)
+ return d->filter->boundingRectFor(d->source->boundingRect());
+ return QRectF();
}
-void QGraphicsBlurEffect::drawItem(QGraphicsItem *item, QPainter *painter,
- const QStyleOptionGraphicsItem *option, QWidget *widget)
+void QGraphicsBlurEffect::draw(QPainter *painter)
{
Q_D(QGraphicsBlurEffect);
+ if (!d->source)
+ return;
// Find the item's bounds in device coordinates.
- QRectF deviceBounds = painter->worldTransform().mapRect(item->boundingRect());
+ QTransform itemToPixmapTransform(painter->worldTransform());
+ QRectF deviceBounds = itemToPixmapTransform.mapRect(d->source->boundingRect());
QRect deviceRect = deviceBounds.toRect().adjusted(-1, -1, 1, 1);
if (deviceRect.isEmpty())
return;
- QPixmap *pixmap = QGraphicsEffect::drawItemOnPixmap(painter, item, option, widget, 0);
- if (!pixmap)
+ // ### Potentially big rect; must be clipped to the viewport rect.
+ const qreal delta = d->blurRadius * 3;
+ const QRect effectRect = deviceBounds.adjusted(-delta, -delta, delta, delta)
+ .toRect().adjusted(-1, -1, 1, 1);
+ if (effectRect.x() != 0 || effectRect.y() != 0)
+ itemToPixmapTransform *= QTransform::fromTranslate(-effectRect.x(), -effectRect.y());
+
+ QPixmap pixmap(effectRect.size());
+ if (!d->source->drawIntoPixmap(&pixmap, itemToPixmapTransform))
return;
// Draw the pixmap with the filter using an untransformed painter.
QTransform restoreTransform = painter->worldTransform();
painter->setWorldTransform(QTransform());
- d->filter->draw(painter, deviceRect.topLeft(), *pixmap, pixmap->rect());
+ d->filter->draw(painter, deviceRect.topLeft(), pixmap, pixmap.rect());
painter->setWorldTransform(restoreTransform);
}
-/*!
- \internal
-*/
-class QGraphicsBloomEffectPrivate : public QGraphicsEffectPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsBlurEffect)
-public:
- QGraphicsBloomEffectPrivate()
- : blurRadius(6)
- , opacity(0.7) { }
-
- int blurRadius;
- qreal opacity;
-};
-
-QGraphicsBloomEffect::QGraphicsBloomEffect(QObject *parent)
- : QGraphicsEffect(*new QGraphicsBloomEffectPrivate, parent)
+QGraphicsBloomEffect::QGraphicsBloomEffect()
+ : QGraphicsEffect(*new QGraphicsBloomEffectPrivate)
{
}
@@ -519,13 +454,13 @@ void QGraphicsBloomEffect::setOpacity(qreal alpha)
d->opacity = alpha;
}
-QRectF QGraphicsBloomEffect::boundingRectFor(const QGraphicsItem *item)
+QRectF QGraphicsBloomEffect::boundingRect() const
{
- Q_D(QGraphicsBloomEffect);
+ Q_D(const QGraphicsBloomEffect);
+ if (!d->source)
+ return QRectF();
qreal delta = d->blurRadius * 3;
- QRectF blurRect = item->boundingRect();
- blurRect.adjust(-delta, -delta, delta, delta);
- return blurRect;
+ return d->source->boundingRect().adjusted(-delta, -delta, delta, delta);
}
// Change brightness (positive integer) of each pixel
@@ -559,24 +494,29 @@ static QImage composited(const QImage& img1, const QImage& img2, qreal opacity,
return result;
}
-void QGraphicsBloomEffect::drawItem(QGraphicsItem *item, QPainter *painter,
- const QStyleOptionGraphicsItem *option, QWidget *widget)
+void QGraphicsBloomEffect::draw(QPainter *painter)
{
Q_D(QGraphicsBloomEffect);
+ if (!d->source)
+ return;
// Find the item's bounds in device coordinates.
- QRectF deviceBounds = painter->worldTransform().mapRect(item->boundingRect());
+ QTransform itemToPixmapTransform(painter->worldTransform());
+ QRectF deviceBounds = itemToPixmapTransform.mapRect(d->source->boundingRect());
QRect deviceRect = deviceBounds.toRect().adjusted(-1, -1, 1, 1);
if (deviceRect.isEmpty())
return;
- QPixmap *pixmap = QGraphicsEffect::drawItemOnPixmap(painter, item, option, widget, 0);
- if (!pixmap)
+ if (deviceRect.x() != 0 || deviceRect.y() != 0)
+ itemToPixmapTransform *= QTransform::fromTranslate(-deviceRect.x(), -deviceRect.y());
+
+ QPixmap pixmap(deviceRect.size());
+ if (!d->source->drawIntoPixmap(&pixmap, itemToPixmapTransform))
return;
// bloom routine
int radius = d->blurRadius;
- QImage img = pixmap->toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
QImage overlay = blurred(img, img.rect(), radius);
overlay = brightened(overlay, 70);
img = composited(img, overlay, d->opacity, QPainter::CompositionMode_Overlay);
@@ -588,27 +528,8 @@ void QGraphicsBloomEffect::drawItem(QGraphicsItem *item, QPainter *painter,
painter->setWorldTransform(restoreTransform);
}
-/*!
- \internal
-*/
-class QGraphicsFrameEffectPrivate : public QGraphicsEffectPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsFrameEffect)
-public:
- QGraphicsFrameEffectPrivate()
- : color(Qt::blue)
- , width(5)
- , alpha(0.6)
- {
- }
-
- QColor color;
- qreal width;
- qreal alpha;
-};
-
-QGraphicsFrameEffect::QGraphicsFrameEffect(QObject *parent)
- : QGraphicsEffect(*new QGraphicsFrameEffectPrivate, parent)
+QGraphicsFrameEffect::QGraphicsFrameEffect()
+ : QGraphicsEffect(*new QGraphicsFrameEffectPrivate)
{
}
@@ -652,31 +573,35 @@ void QGraphicsFrameEffect::setFrameOpacity(qreal opacity)
d->alpha = opacity;
}
-QRectF QGraphicsFrameEffect::boundingRectFor(const QGraphicsItem *item)
+QRectF QGraphicsFrameEffect::boundingRect() const
{
- Q_D(QGraphicsFrameEffect);
- QRectF frameRect = item->boundingRect();
- frameRect.adjust(-d->width, -d->width, d->width, d->width);
- return frameRect;
+ Q_D(const QGraphicsFrameEffect);
+ if (!d->source)
+ return QRectF();
+ return d->source->boundingRect().adjusted(-d->width, -d->width, d->width, d->width);
}
-void QGraphicsFrameEffect::drawItem(QGraphicsItem *item, QPainter *painter,
- const QStyleOptionGraphicsItem *option, QWidget *widget)
+void QGraphicsFrameEffect::draw(QPainter *painter)
{
Q_D(QGraphicsFrameEffect);
+ if (!d->source)
+ return;
// Find the item's bounds in device coordinates.
- QRectF deviceBounds = painter->worldTransform().mapRect(item->boundingRect());
- QRect deviceRect = deviceBounds.toRect().adjusted(-1, -1, 1, 1);
- if (deviceRect.isEmpty())
+ QTransform itemToPixmapTransform(painter->worldTransform());
+ QRectF deviceBounds = itemToPixmapTransform.mapRect(d->source->boundingRect());
+ if (deviceBounds.isEmpty())
return;
- QPixmap *pixmap = QGraphicsEffect::drawItemOnPixmap(painter, item, option, widget, 0);
- if (!pixmap)
- return;
+ QRect frameRect = deviceBounds.adjusted(-d->width, -d->width, d->width, d->width)
+ .toRect().adjusted(-1, -1, 1, 1);
- QRectF frameRect = deviceBounds;
- frameRect.adjust(-d->width, -d->width, d->width, d->width);
+ if (frameRect.x() != 0 || frameRect.y() != 0)
+ itemToPixmapTransform *= QTransform::fromTranslate(-frameRect.x(), -frameRect.y());
+
+ QPixmap pixmap(frameRect.size());
+ if (!d->source->drawIntoPixmap(&pixmap, itemToPixmapTransform))
+ return;
painter->save();
painter->setWorldTransform(QTransform());
@@ -688,33 +613,13 @@ void QGraphicsFrameEffect::drawItem(QGraphicsItem *item, QPainter *painter,
painter->drawRoundedRect(frameRect, 20, 20, Qt::RelativeSize);
painter->restore();
- painter->drawPixmap(frameRect.topLeft(), *pixmap);
+ painter->drawPixmap(frameRect.topLeft(), pixmap);
painter->restore();
}
-
-/*!
- \internal
-*/
-class QGraphicsShadowEffectPrivate : public QGraphicsEffectPrivate
-{
- Q_DECLARE_PUBLIC(QGraphicsShadowEffect)
-public:
- QGraphicsShadowEffectPrivate()
- : offset(4,4)
- , radius(8)
- , alpha(0.7)
- {
- }
-
- QPointF offset;
- int radius;
- qreal alpha;
-};
-
-QGraphicsShadowEffect::QGraphicsShadowEffect(QObject *parent)
- : QGraphicsEffect(*new QGraphicsShadowEffectPrivate, parent)
+QGraphicsShadowEffect::QGraphicsShadowEffect()
+ : QGraphicsEffect(*new QGraphicsShadowEffectPrivate)
{
}
@@ -758,25 +663,30 @@ void QGraphicsShadowEffect::setOpacity(qreal opacity)
d->alpha = opacity;
}
-QRectF QGraphicsShadowEffect::boundingRectFor(const QGraphicsItem *item)
+QRectF QGraphicsShadowEffect::boundingRect() const
{
- Q_D(QGraphicsShadowEffect);
- QRectF shadowRect = item->boundingRect();
+ Q_D(const QGraphicsShadowEffect);
+ if (!d->source)
+ return QRectF();
+ const QRectF srcBrect = d->source->boundingRect();
+ QRectF shadowRect = srcBrect;
shadowRect.adjust(d->offset.x(), d->offset.y(), d->offset.x(), d->offset.y());
QRectF blurRect = shadowRect;
qreal delta = d->radius * 3;
blurRect.adjust(-delta, -delta, delta, delta);
- QRectF totalRect = blurRect.united(item->boundingRect());
+ QRectF totalRect = blurRect.united(srcBrect);
return totalRect;
}
-void QGraphicsShadowEffect::drawItem(QGraphicsItem *item, QPainter *painter,
- const QStyleOptionGraphicsItem *option, QWidget *widget)
+void QGraphicsShadowEffect::draw(QPainter *painter)
{
Q_D(QGraphicsShadowEffect);
+ if (!d->source)
+ return;
// Find the item's bounds in device coordinates.
- QRectF deviceBounds = painter->worldTransform().mapRect(item->boundingRect());
+ QTransform itemToPixmapTransform(painter->worldTransform());
+ QRectF deviceBounds = itemToPixmapTransform.mapRect(d->source->boundingRect());
QRect deviceRect = deviceBounds.toRect().adjusted(-1, -1, 1, 1);
if (deviceRect.isEmpty())
return;
@@ -786,13 +696,16 @@ void QGraphicsShadowEffect::drawItem(QGraphicsItem *item, QPainter *painter,
QRectF blurRect = shadowRect;
qreal delta = d->radius * 3;
blurRect.adjust(-delta, -delta, delta, delta);
- QRectF totalRect = blurRect.united(deviceRect);
+ QRect totalRect = blurRect.united(deviceRect).toRect().adjusted(-1, -1, 1, 1);
- QPixmap *pixmap = QGraphicsEffect::drawItemOnPixmap(painter, item, option, widget, 0);
- if (!pixmap)
+ if (totalRect.x() != 0 || totalRect.y() != 0)
+ itemToPixmapTransform *= QTransform::fromTranslate(-totalRect.x(), -totalRect.y());
+
+ QPixmap pixmap(totalRect.size());
+ if (!d->source->drawIntoPixmap(&pixmap, itemToPixmapTransform))
return;
- QImage img = pixmap->toImage();
+ QImage img = pixmap.toImage();
QImage shadowImage(img.size(), QImage::Format_ARGB32);
shadowImage.fill(qRgba(0, 0, 0, d->alpha * 255));
shadowImage.setAlphaChannel(img.alphaChannel());
@@ -814,10 +727,9 @@ void QGraphicsShadowEffect::drawItem(QGraphicsItem *item, QPainter *painter,
qreal itemx = qMin(blurRect.x(), deviceBounds.x());
qreal itemy = qMin(blurRect.y(), deviceBounds.y());
- painter->drawPixmap(itemx, itemy, *pixmap);
+ painter->drawPixmap(itemx, itemy, pixmap);
painter->setWorldTransform(restoreTransform);
}
-
#endif
diff --git a/src/gui/graphicsview/qgraphicseffect.h b/src/gui/graphicsview/qgraphicseffect.h
index 29d97a6..74a8430 100644
--- a/src/gui/graphicsview/qgraphicseffect.h
+++ b/src/gui/graphicsview/qgraphicseffect.h
@@ -46,6 +46,7 @@
#include <QtCore/qglobal.h>
#include <QtCore/qpoint.h>
#include <QtCore/qvariant.h>
+#include <QtGui/qtransform.h>
#include <QtGui/qcolor.h>
QT_FORWARD_DECLARE_CLASS(QGraphicsItem);
@@ -67,24 +68,22 @@ class QGraphicsEffectPrivate;
class Q_GUI_EXPORT QGraphicsEffect : public QObject
{
Q_OBJECT
-
public:
-
- QGraphicsEffect(QObject *parent = 0);
+ QGraphicsEffect();
virtual ~QGraphicsEffect();
- virtual QRectF boundingRectFor(const QGraphicsItem *item);
-
- virtual void drawItem(QGraphicsItem *item, QPainter *painter,
- const QStyleOptionGraphicsItem *option = 0,
- QWidget *widget = 0) = 0;
+ virtual QRectF boundingRect() const;
protected:
- QGraphicsEffect(QGraphicsEffectPrivate &d, QObject* parent);
- QPixmap* drawItemOnPixmap(QPainter *painter, QGraphicsItem *item,
- const QStyleOptionGraphicsItem *option, QWidget *widget, int flags);
+ QGraphicsEffect(QGraphicsEffectPrivate &d);
+ virtual void draw(QPainter *painter) = 0;
+ void drawSource(QPainter *painter);
+ bool drawSourceIntoPixmap(QPixmap *pixmap, const QTransform &xform = QTransform());
+ QRectF sourceBoundingRect() const;
private:
+ friend class QGraphicsScenePrivate;
+ friend class QGraphicsItem;
Q_DECLARE_PRIVATE(QGraphicsEffect)
Q_DISABLE_COPY(QGraphicsEffect)
};
@@ -93,15 +92,12 @@ class QGraphicsGrayscaleEffectPrivate;
class Q_GUI_EXPORT QGraphicsGrayscaleEffect: public QGraphicsEffect
{
Q_OBJECT
-
public:
-
- QGraphicsGrayscaleEffect(QObject *parent = 0);
+ QGraphicsGrayscaleEffect();
~QGraphicsGrayscaleEffect();
- void drawItem(QGraphicsItem *item, QPainter *painter,
- const QStyleOptionGraphicsItem *option = 0,
- QWidget *widget = 0);
+protected:
+ void draw(QPainter *painter);
private:
Q_DECLARE_PRIVATE(QGraphicsGrayscaleEffect)
@@ -111,18 +107,15 @@ private:
class QGraphicsColorizeEffectPrivate;
class Q_GUI_EXPORT QGraphicsColorizeEffect: public QGraphicsEffect {
Q_OBJECT
-
public:
-
- QGraphicsColorizeEffect(QObject *parent = 0);
+ QGraphicsColorizeEffect();
~QGraphicsColorizeEffect();
QColor color() const;
void setColor(const QColor &c);
- void drawItem(QGraphicsItem *item, QPainter *painter,
- const QStyleOptionGraphicsItem *option = 0,
- QWidget *widget = 0);
+protected:
+ void draw(QPainter *painter);
private:
Q_DECLARE_PRIVATE(QGraphicsColorizeEffect)
@@ -132,18 +125,15 @@ private:
class QGraphicsPixelizeEffectPrivate;
class Q_GUI_EXPORT QGraphicsPixelizeEffect: public QGraphicsEffect {
Q_OBJECT
-
public:
-
- QGraphicsPixelizeEffect(QObject *parent = 0);
+ QGraphicsPixelizeEffect();
~QGraphicsPixelizeEffect();
int pixelSize() const;
void setPixelSize(int pixelSize);
- void drawItem(QGraphicsItem *item, QPainter *painter,
- const QStyleOptionGraphicsItem *option = 0,
- QWidget *widget = 0);
+protected:
+ void draw(QPainter *painter);
private:
Q_DECLARE_PRIVATE(QGraphicsPixelizeEffect)
@@ -153,20 +143,17 @@ private:
class QGraphicsBlurEffectPrivate;
class Q_GUI_EXPORT QGraphicsBlurEffect: public QGraphicsEffect {
Q_OBJECT
-
public:
-
- QGraphicsBlurEffect(QObject *parent = 0);
+ QGraphicsBlurEffect();
~QGraphicsBlurEffect();
int blurRadius() const;
void setBlurRadius(int blurRadius);
- QRectF boundingRectFor(const QGraphicsItem *item);
+ QRectF boundingRect() const;
- void drawItem(QGraphicsItem *item, QPainter *painter,
- const QStyleOptionGraphicsItem *option = 0,
- QWidget *widget = 0);
+protected:
+ void draw(QPainter *painter);
private:
Q_DECLARE_PRIVATE(QGraphicsBlurEffect)
@@ -176,10 +163,8 @@ private:
class QGraphicsBloomEffectPrivate;
class Q_GUI_EXPORT QGraphicsBloomEffect: public QGraphicsEffect {
Q_OBJECT
-
public:
-
- QGraphicsBloomEffect(QObject *parent = 0);
+ QGraphicsBloomEffect();
~QGraphicsBloomEffect();
int blurRadius() const;
@@ -188,11 +173,10 @@ public:
qreal opacity() const;
void setOpacity(qreal opacity);
- QRectF boundingRectFor(const QGraphicsItem *item);
+ QRectF boundingRect() const;
- void drawItem(QGraphicsItem *item, QPainter *painter,
- const QStyleOptionGraphicsItem *option = 0,
- QWidget *widget = 0);
+protected:
+ void draw(QPainter *painter);
private:
Q_DECLARE_PRIVATE(QGraphicsBloomEffect)
@@ -202,10 +186,8 @@ private:
class QGraphicsFrameEffectPrivate;
class Q_GUI_EXPORT QGraphicsFrameEffect: public QGraphicsEffect {
Q_OBJECT
-
public:
-
- QGraphicsFrameEffect(QObject *parent = 0);
+ QGraphicsFrameEffect();
~QGraphicsFrameEffect();
QColor frameColor() const;
@@ -217,11 +199,11 @@ public:
qreal frameOpacity() const;
void setFrameOpacity(qreal opacity);
- QRectF boundingRectFor(const QGraphicsItem *item);
+ QRectF boundingRect() const;
+
+protected:
+ void draw(QPainter *painter);
- void drawItem(QGraphicsItem *item, QPainter *painter,
- const QStyleOptionGraphicsItem *option = 0,
- QWidget *widget = 0);
private:
Q_DECLARE_PRIVATE(QGraphicsFrameEffect)
Q_DISABLE_COPY(QGraphicsFrameEffect)
@@ -230,10 +212,8 @@ private:
class QGraphicsShadowEffectPrivate;
class Q_GUI_EXPORT QGraphicsShadowEffect: public QGraphicsEffect {
Q_OBJECT
-
public:
-
- QGraphicsShadowEffect(QObject *parent = 0);
+ QGraphicsShadowEffect();
~QGraphicsShadowEffect();
QPointF shadowOffset() const;
@@ -247,13 +227,10 @@ public:
qreal opacity() const;
void setOpacity(qreal opacity);
- QRectF boundingRectFor(const QGraphicsItem *item);
-
- void drawItem(QGraphicsItem *item, QPainter *painter,
- const QStyleOptionGraphicsItem *option = 0,
- QWidget *widget = 0);
+ QRectF boundingRect() const;
protected:
+ void draw(QPainter *painter);
private:
Q_DECLARE_PRIVATE(QGraphicsShadowEffect)
diff --git a/src/gui/graphicsview/qgraphicseffect_p.h b/src/gui/graphicsview/qgraphicseffect_p.h
new file mode 100644
index 0000000..9204789
--- /dev/null
+++ b/src/gui/graphicsview/qgraphicseffect_p.h
@@ -0,0 +1,171 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.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 the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSEFFECT_P_H
+#define QGRAPHICSEFFECT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qgraphicseffect.h"
+#include <private/qobject_p.h>
+#include <private/qpixmapfilter_p.h>
+
+#if !defined(QT_NO_GRAPHICSVIEW) || (QT_EDITION & QT_MODULE_GRAPHICSVIEW) != QT_MODULE_GRAPHICSVIEW
+
+QT_BEGIN_NAMESPACE
+
+class QGraphicsEffectSource
+{
+public:
+ QGraphicsEffectSource() {}
+ virtual ~QGraphicsEffectSource() {}
+ virtual void detach() = 0;
+ virtual QRectF boundingRect() = 0;
+ virtual void draw(QPainter *p) = 0;
+ virtual bool drawIntoPixmap(QPixmap *, const QTransform & = QTransform()) = 0;
+};
+
+class QGraphicsEffectPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsEffect)
+public:
+ QGraphicsEffectPrivate() : source(0) {}
+ QGraphicsEffectSource *source;
+ inline void setGraphicsEffectSource(QGraphicsEffectSource *newSource)
+ {
+ if (source) {
+ source->detach();
+ delete source;
+ }
+ source = newSource;
+ }
+};
+
+class QGraphicsGrayscaleEffectPrivate : public QGraphicsEffectPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsGrayscaleEffect)
+public:
+ QGraphicsGrayscaleEffectPrivate()
+ {
+ filter = new QPixmapColorizeFilter;
+ filter->setColor(Qt::black);
+ }
+ ~QGraphicsGrayscaleEffectPrivate() { delete filter; }
+
+ QPixmapColorizeFilter *filter;
+};
+
+class QGraphicsColorizeEffectPrivate : public QGraphicsEffectPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsColorizeEffect)
+public:
+ QGraphicsColorizeEffectPrivate() { filter = new QPixmapColorizeFilter; }
+ ~QGraphicsColorizeEffectPrivate() { delete filter; }
+
+ QPixmapColorizeFilter *filter;
+};
+
+class QGraphicsPixelizeEffectPrivate : public QGraphicsEffectPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsPixelizeEffect)
+public:
+ QGraphicsPixelizeEffectPrivate() : pixelSize(3) {}
+
+ int pixelSize;
+};
+
+class QGraphicsBlurEffectPrivate : public QGraphicsEffectPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsBlurEffect)
+public:
+ QGraphicsBlurEffectPrivate() : filter(new QPixmapBlurFilter), blurRadius(4) {}
+ ~QGraphicsBlurEffectPrivate() { delete filter; }
+
+ QPixmapBlurFilter *filter;
+ int blurRadius;
+};
+
+class QGraphicsBloomEffectPrivate : public QGraphicsEffectPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsBlurEffect)
+public:
+ QGraphicsBloomEffectPrivate() : blurRadius(6), opacity(0.7) {}
+
+ int blurRadius;
+ qreal opacity;
+};
+
+class QGraphicsFrameEffectPrivate : public QGraphicsEffectPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsFrameEffect)
+public:
+ QGraphicsFrameEffectPrivate() : color(Qt::blue), width(5), alpha(0.6) {}
+
+ QColor color;
+ qreal width;
+ qreal alpha;
+};
+
+class QGraphicsShadowEffectPrivate : public QGraphicsEffectPrivate
+{
+ Q_DECLARE_PUBLIC(QGraphicsShadowEffect)
+public:
+ QGraphicsShadowEffectPrivate() : offset(4,4), radius(8), alpha(0.7) {}
+
+ QPointF offset;
+ int radius;
+ qreal alpha;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_GRAPHICSVIEW
+
+#endif // QGRAPHICSEFFECT_P_H
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index c395e21..7533fa4 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -552,7 +552,6 @@
#ifndef QT_NO_GRAPHICSVIEW
-#include "qgraphicseffect.h"
#include "qgraphicsscene.h"
#include "qgraphicsscene_p.h"
#include "qgraphicssceneevent.h"
@@ -1180,6 +1179,7 @@ QGraphicsItem::~QGraphicsItem()
else
d_ptr->setParentItemHelper(0);
+ delete d_ptr->graphicsEffect;
delete d_ptr->transformData;
delete d_ptr;
@@ -2190,39 +2190,53 @@ void QGraphicsItem::setOpacity(qreal opacity)
}
/*!
+ Returns a pointer to this item's effect if it has one; otherwise 0.
+
\since 4.6
- Returns this item's \e effect if it has one; otherwise,
- returns 0.
*/
-QGraphicsEffect *QGraphicsItem::effect() const
+QGraphicsEffect *QGraphicsItem::graphicsEffect() const
{
- QGraphicsEffect *fx = 0;
- if (d_ptr->hasEffect)
- fx = d_ptr->extra(QGraphicsItemPrivate::ExtraEffect).value<QGraphicsEffect*>();
-
- return fx;
+ return d_ptr->graphicsEffect;
}
/*!
+ Sets \a effect as the item's effect. If there already is an effect installed
+ on this item, QGraphicsItem won't let you install another. You must first
+ delete the existing effect (returned by graphicsEffect()) before you can call
+ setGraphicsEffect() with the new effect.
+
+ If \a effect is the installed on a different item, setGraphicsEffect() will remove
+ the effect from the item and install it on this item.
+
+ \note This function will apply the effect on itself and all its children.
+
\since 4.6
- Sets \e effect as the item's effect. It will replace the previous effect
- the item might have.
*/
-void QGraphicsItem::setEffect(QGraphicsEffect *effect)
+void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect)
{
- if (effect) {
- d_ptr->hasEffect = true;
- d_ptr->setExtra(QGraphicsItemPrivate::ExtraEffect, QVariant::fromValue(effect));
+ if (d_ptr->graphicsEffect == effect)
+ return;
+
+ if (d_ptr->graphicsEffect && effect) {
+ qWarning("QGraphicsItem::setGraphicsEffect: Attempting to set QGraphicsEffect "
+ "%p on %p, which already has an effect installed", effect, this);
+ return;
+ }
+
+ if (!effect) {
+ // Unset current effect.
+ QGraphicsEffectPrivate *oldEffectPrivate = d_ptr->graphicsEffect->d_func();
+ d_ptr->graphicsEffect = 0;
+ if (oldEffectPrivate)
+ oldEffectPrivate->setGraphicsEffectSource(0); // deletes the current source.
} else {
- d_ptr->hasEffect = false;
- d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraEffect);
- void *ptr = d_ptr->extra(QGraphicsItemPrivate::ExtraEffectPixmap).value<void*>();
- QPixmap *pixmap = reinterpret_cast<QPixmap*>(ptr);
- delete pixmap;
- d_ptr->unsetExtra(QGraphicsItemPrivate::ExtraEffectPixmap);
+ // Set new effect.
+ effect->d_func()->setGraphicsEffectSource(new QGraphicsItemEffectSource(this));
+ d_ptr->graphicsEffect = effect;
}
- update();
+ if (d_ptr->scene)
+ d_ptr->scene->d_func()->markDirty(this);
}
/*!
@@ -2236,10 +2250,8 @@ void QGraphicsItem::setEffect(QGraphicsEffect *effect)
*/
QRectF QGraphicsItem::effectiveBoundingRect() const
{
- QGraphicsEffect *fx = effect();
- if (fx)
- return fx->boundingRectFor(this);
-
+ if (d_ptr->graphicsEffect)
+ return d_ptr->graphicsEffect->boundingRect();
return boundingRect();
}
@@ -2273,42 +2285,6 @@ QRectF QGraphicsItem::sceneEffectiveBoundingRect() const
}
/*!
- \internal
-
- Used by QGraphicsScene.
-*/
-QPixmap *QGraphicsItem::effectPixmap()
-{
- if (!d_ptr->hasEffect)
- return 0;
-
- // the exact size of the pixmap is not a big deal
- // as long as it contains the effective bounding rect
- // TODO: use smart resizing etc
- // TODO: store per device and do everything in device coordinate?
- // TODO: use layer
- QRect rect = effectiveBoundingRect().toAlignedRect();
-
- void *ptr = d_ptr->extra(QGraphicsItemPrivate::ExtraEffectPixmap).value<void*>();
- QPixmap *pixmap = reinterpret_cast<QPixmap*>(ptr);
- bool avail = true;
- if (!pixmap)
- avail = false;
- if (avail && pixmap->size() != rect.size())
- avail = false;
-
- if (!avail) {
- delete pixmap;
- pixmap = new QPixmap(rect.size());
- pixmap->fill(Qt::transparent);
- ptr = reinterpret_cast<void*>(pixmap);
- d_ptr->setExtra(QGraphicsItemPrivate::ExtraEffectPixmap, QVariant::fromValue(ptr));
- }
-
- return pixmap;
-}
-
-/*!
Returns true if this item can accept drag and drop events; otherwise,
returns false. By default, items do not accept drag and drop events; items
are transparent to drag and drop.
diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h
index 4cb94bf..1bcf0e0 100644
--- a/src/gui/graphicsview/qgraphicsitem.h
+++ b/src/gui/graphicsview/qgraphicsitem.h
@@ -208,8 +208,8 @@ public:
void setOpacity(qreal opacity);
// Effect
- QGraphicsEffect *effect() const;
- void setEffect(QGraphicsEffect *effect);
+ QGraphicsEffect *graphicsEffect() const;
+ void setGraphicsEffect(QGraphicsEffect *effect);
QRectF effectiveBoundingRect() const;
QRectF sceneEffectiveBoundingRect() const;
@@ -443,8 +443,6 @@ protected:
void removeFromIndex();
void prepareGeometryChange();
- QPixmap *effectPixmap();
-
private:
Q_DISABLE_COPY(QGraphicsItem)
Q_DECLARE_PRIVATE(QGraphicsItem)
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index 3f02560..1fedca8 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -57,6 +57,7 @@
#include "qset.h"
#include "qpixmapcache.h"
#include "qgraphicsview_p.h"
+#include "qgraphicseffect_p.h"
#include <QtCore/qpoint.h>
@@ -103,8 +104,6 @@ public:
ExtraCacheData,
ExtraMaxDeviceCoordCacheSize,
ExtraBoundingRegionGranularity,
- ExtraEffect,
- ExtraEffectPixmap,
ExtraGestures
};
@@ -122,6 +121,7 @@ public:
scene(0),
parent(0),
transformData(0),
+ graphicsEffect(0),
index(-1),
siblingIndex(-1),
depth(0),
@@ -152,7 +152,6 @@ public:
allChildrenDirty(0),
fullUpdatePending(0),
flags(0),
- hasEffect(0),
dirtyChildrenBoundingRect(1),
paintedViewBoundingRectsNeedRepaint(0),
dirtySceneTransform(1),
@@ -410,6 +409,7 @@ public:
QList<QGraphicsItem *> children;
struct TransformData;
TransformData *transformData;
+ QGraphicsEffect *graphicsEffect;
QTransform sceneTransform;
int index;
int siblingIndex;
@@ -445,7 +445,6 @@ public:
// New 32 bits
quint32 fullUpdatePending : 1;
quint32 flags : 12;
- quint32 hasEffect : 1;
quint32 dirtyChildrenBoundingRect : 1;
quint32 paintedViewBoundingRectsNeedRepaint : 1;
quint32 dirtySceneTransform : 1;
@@ -513,6 +512,44 @@ struct QGraphicsItemPrivate::TransformData {
}
};
+class QGraphicsItemEffectSource : public QGraphicsEffectSource
+{
+public:
+ QGraphicsItemEffectSource(QGraphicsItem *i)
+ : QGraphicsEffectSource(), item(i), option(0), widget(0)
+ {}
+
+ inline void detach()
+ { item->setGraphicsEffect(0); }
+
+ inline QRectF boundingRect()
+ { return item->boundingRect(); }
+
+ inline void draw(QPainter *painter)
+ { item->paint(painter, option, widget); }
+
+ inline bool drawIntoPixmap(QPixmap *pixmap, const QTransform &itemToPixmapTransform)
+ {
+ pixmap->fill(Qt::transparent);
+ QPainter pixmapPainter(pixmap);
+ if (!itemToPixmapTransform.isIdentity())
+ pixmapPainter.setWorldTransform(itemToPixmapTransform);
+ item->paint(&pixmapPainter, option, widget);
+ return true;
+ }
+
+ inline void setPaintInfo(const QStyleOptionGraphicsItem *o, QWidget *w)
+ { option = o; widget = w; }
+
+ void resetPaintInfo()
+ { option = 0; widget = 0; }
+
+private:
+ QGraphicsItem *item;
+ const QStyleOptionGraphicsItem *option;
+ QWidget *widget;
+};
+
/*!
\internal
*/
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index b2b9ebd..41bcb76 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -3971,8 +3971,8 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
#endif
// Render using effect, works now only for no cache mode
- if (noCache && itemd->hasEffect && item->effect()) {
- item->effect()->drawItem(item, painter, option, widget);
+ if (noCache && itemd->graphicsEffect) {
+ itemd->graphicsEffect->draw(painter);
return;
}
@@ -4271,62 +4271,6 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte
}
}
-// FIXME: merge this with drawItems (needs refactoring)
-QPixmap* QGraphicsScene::drawItemOnPixmap(QPainter *painter,
- QGraphicsItem *item,
- const QStyleOptionGraphicsItem *option,
- QWidget *widget,
- int flags)
-{
- // TODO: use for choosing item or device coordinate
- // FIXME: how about source, dest, and exposed rects?
- Q_UNUSED(flags);
-
- // Item's (local) bounding rect, including the effect
- QRectF brect = item->effectiveBoundingRect();
- QRectF adjustedBrect(brect);
- _q_adjustRect(&adjustedBrect);
- if (adjustedBrect.isEmpty())
- return 0;
-
- // Find the item's bounds in device coordinates.
- QRectF deviceBounds = painter->worldTransform().mapRect(brect);
- QRect deviceRect = deviceBounds.toRect().adjusted(-1, -1, 1, 1);
- if (deviceRect.isEmpty())
- return 0;
-
- // If widget, check if it intersects or not
- QRect viewRect = widget ? widget->rect() : QRect();
- if (widget && !viewRect.intersects(deviceRect))
- return 0;
-
- // Create offscreen pixmap
- // TODO: use the pixmap from the layer
- QPixmap *targetPixmap = item->effectPixmap();
- if (!targetPixmap)
- targetPixmap = new QPixmap(deviceRect.size());
-
- // FIXME: this is brute force
- QRegion pixmapExposed;
- pixmapExposed += targetPixmap->rect();
-
- // Construct an item-to-pixmap transform.
- QPointF p = deviceRect.topLeft();
- QTransform itemToPixmap = painter->worldTransform();
- if (!p.isNull())
- itemToPixmap *= QTransform::fromTranslate(-p.x(), -p.y());
-
- // Calculate the style option's exposedRect.
- QStyleOptionGraphicsItem fxOption = *option;
- fxOption.exposedRect = brect.adjusted(-1, -1, 1, 1);
-
- // Render
- _q_paintIntoCache(targetPixmap, item, pixmapExposed, itemToPixmap, painter->renderHints(),
- &fxOption, false);
-
- return targetPixmap;
-}
-
void QGraphicsScenePrivate::drawItems(QPainter *painter, const QTransform *const viewTransform,
QRegion *exposedRegion, QWidget *widget)
{
@@ -4455,11 +4399,21 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
painter->setClipPath(item->shape(), Qt::IntersectClip);
painter->setOpacity(opacity);
- if (!item->d_ptr->cacheMode && !item->d_ptr->isWidget && !item->d_ptr->hasEffect)
+ QGraphicsItemEffectSource *source = item->d_ptr->graphicsEffect
+ ? static_cast<QGraphicsItemEffectSource *>
+ (item->d_ptr->graphicsEffect->d_func()->source)
+ : 0;
+ if (source)
+ source->setPaintInfo(&styleOptionTmp, widget);
+
+ if (!item->d_ptr->cacheMode && !item->d_ptr->isWidget && !source)
item->paint(painter, &styleOptionTmp, widget);
else
drawItemHelper(item, painter, &styleOptionTmp, widget, painterStateProtection);
+ if (source)
+ source->resetPaintInfo();
+
if (savePainter)
painter->restore();
}
diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h
index 6292afa..89436aa 100644
--- a/src/gui/graphicsview/qgraphicsscene.h
+++ b/src/gui/graphicsview/qgraphicsscene.h
@@ -282,11 +282,6 @@ protected:
const QStyleOptionGraphicsItem options[],
QWidget *widget = 0);
- QPixmap* drawItemOnPixmap(QPainter *painter, QGraphicsItem *item,
- const QStyleOptionGraphicsItem *option, QWidget *widget, int flags);
-
-
-
protected Q_SLOTS:
bool focusNextPrevChild(bool next);