| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the QtWidgets module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:LGPL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Lesser General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Lesser |
| ** General Public License version 3 as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
| ** packaging of this file. Please review the following information to |
| ** ensure the GNU Lesser General Public License version 3 requirements |
| ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 2.0 or (at your option) the GNU General |
| ** Public license version 3 or any later version approved by the KDE Free |
| ** Qt Foundation. The licenses are as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
| ** https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| /*! |
| \class QGraphicsEffect |
| \brief The QGraphicsEffect class is the base class for all graphics |
| effects. |
| \since 4.6 |
| \ingroup multimedia |
| \ingroup graphicsview-api |
| \inmodule QtWidgets |
| |
| Effects alter the appearance of elements by hooking into the rendering |
| pipeline and operating between the source (e.g., a QGraphicsPixmapItem) |
| and the destination device (e.g., QGraphicsView's viewport). Effects can be |
| disabled by calling setEnabled(false). If effects are disabled, the source |
| is rendered directly. |
| |
| To add a visual effect to a QGraphicsItem, for example, you can use one of |
| the standard effects, or alternately, create your own effect by creating a |
| subclass of QGraphicsEffect. The effect can then be installed on the item |
| using QGraphicsItem::setGraphicsEffect(). |
| |
| Qt provides the following standard effects: |
| |
| \list |
| \li QGraphicsBlurEffect - blurs the item by a given radius |
| \li QGraphicsDropShadowEffect - renders a dropshadow behind the item |
| \li QGraphicsColorizeEffect - renders the item in shades of any given color |
| \li QGraphicsOpacityEffect - renders the item with an opacity |
| \endlist |
| |
| \table |
| \row |
| \li{2,1} \image graphicseffect-plain.png |
| \row |
| \li \image graphicseffect-blur.png |
| \li \image graphicseffect-colorize.png |
| \row |
| \li \image graphicseffect-opacity.png |
| \li \image graphicseffect-drop-shadow.png |
| \endtable |
| |
| \image graphicseffect-widget.png |
| |
| For more information on how to use each effect, refer to the specific |
| effect's documentation. |
| |
| To create your own custom effect, create a subclass of QGraphicsEffect (or |
| any other existing effects) and reimplement the virtual function draw(). |
| This function is called whenever the effect needs to redraw. The draw() |
| function takes the painter with which to draw as an argument. For more |
| information, refer to the documenation for draw(). In the draw() function |
| you can call sourcePixmap() to get a pixmap of the graphics effect source |
| which you can then process. |
| |
| If your effect changes, use update() to request for a redraw. If your |
| custom effect changes the bounding rectangle of the source, e.g., a radial |
| glow effect may need to apply an extra margin, you can reimplement the |
| virtual boundingRectFor() function, and call updateBoundingRect() |
| to notify the framework whenever this rectangle changes. The virtual |
| sourceChanged() function is called to notify the effects that |
| the source has changed in some way - e.g., if the source is a |
| QGraphicsRectItem and its rectangle parameters have changed. |
| |
| \sa QGraphicsItem::setGraphicsEffect(), QWidget::setGraphicsEffect() |
| */ |
| |
| #include "qgraphicseffect_p.h" |
| #include "private/qgraphicsitem_p.h" |
| |
| #include <QtWidgets/qgraphicsitem.h> |
| |
| #include <QtGui/qimage.h> |
| #include <QtGui/qpainter.h> |
| #include <QtGui/qpaintengine.h> |
| #include <QtCore/qrect.h> |
| #include <QtCore/qdebug.h> |
| #include <private/qdrawhelper_p.h> |
| |
| QT_BEGIN_NAMESPACE |
| |
| QGraphicsEffectPrivate::~QGraphicsEffectPrivate() |
| { |
| } |
| |
| /*! |
| \internal |
| \class QGraphicsEffectSource |
| \brief The QGraphicsEffectSource class represents the source on which a |
| QGraphicsEffect is installed on. |
| |
| When a QGraphicsEffect is installed on a QGraphicsItem, for example, this |
| class will act as a wrapper around QGraphicsItem. Then, calling update() is |
| effectively the same as calling QGraphicsItem::update(). |
| |
| QGraphicsEffectSource also provides a pixmap() function which creates a |
| pixmap with the source painted into it. |
| |
| \sa QGraphicsItem::setGraphicsEffect(), QWidget::setGraphicsEffect() |
| */ |
| |
| /*! |
| \internal |
| */ |
| QGraphicsEffectSource::QGraphicsEffectSource(QGraphicsEffectSourcePrivate &dd, QObject *parent) |
| : QObject(dd, parent) |
| {} |
| |
| /*! |
| Destroys the effect source. |
| */ |
| QGraphicsEffectSource::~QGraphicsEffectSource() |
| {} |
| |
| /*! |
| Returns the bounding rectangle of the source mapped to the given \a system. |
| |
| \sa draw() |
| */ |
| QRectF QGraphicsEffectSource::boundingRect(Qt::CoordinateSystem system) const |
| { |
| return d_func()->boundingRect(system); |
| } |
| |
| /*! |
| Returns the bounding rectangle of the source mapped to the given \a system. |
| |
| Calling this function with Qt::DeviceCoordinates outside of |
| QGraphicsEffect::draw() will give undefined results, as there is no device |
| context available. |
| |
| \sa draw() |
| */ |
| QRectF QGraphicsEffect::sourceBoundingRect(Qt::CoordinateSystem system) const |
| { |
| Q_D(const QGraphicsEffect); |
| if (d->source) |
| return d->source->boundingRect(system); |
| return QRectF(); |
| } |
| |
| /*! |
| Returns a pointer to the item if this source is a QGraphicsItem; otherwise |
| returns \nullptr. |
| |
| \sa widget() |
| */ |
| const QGraphicsItem *QGraphicsEffectSource::graphicsItem() const |
| { |
| return d_func()->graphicsItem(); |
| } |
| |
| /*! |
| Returns a pointer to the widget if this source is a QWidget; otherwise |
| returns \nullptr. |
| |
| \sa graphicsItem() |
| */ |
| const QWidget *QGraphicsEffectSource::widget() const |
| { |
| return d_func()->widget(); |
| } |
| |
| /*! |
| Returns a pointer to the style options (used when drawing the source) if |
| available; otherwise returns \nullptr. |
| |
| \sa graphicsItem(), widget() |
| */ |
| const QStyleOption *QGraphicsEffectSource::styleOption() const |
| { |
| return d_func()->styleOption(); |
| } |
| |
| /*! |
| Draws the source using the given \a painter. |
| |
| This function should only be called from QGraphicsEffect::draw(). |
| |
| \sa QGraphicsEffect::draw() |
| */ |
| void QGraphicsEffectSource::draw(QPainter *painter) |
| { |
| Q_D(const QGraphicsEffectSource); |
| |
| QPixmap pm; |
| if (QPixmapCache::find(d->m_cacheKey, &pm)) { |
| QTransform restoreTransform; |
| if (d->m_cachedSystem == Qt::DeviceCoordinates) { |
| restoreTransform = painter->worldTransform(); |
| painter->setWorldTransform(QTransform()); |
| } |
| |
| painter->drawPixmap(d->m_cachedOffset, pm); |
| |
| if (d->m_cachedSystem == Qt::DeviceCoordinates) |
| painter->setWorldTransform(restoreTransform); |
| } else { |
| d_func()->draw(painter); |
| } |
| } |
| |
| /*! |
| Draws the source directly using the given \a painter. |
| |
| This function should only be called from QGraphicsEffect::draw(). |
| |
| For example: |
| |
| \snippet code/src_gui_effects_qgraphicseffect.cpp 0 |
| |
| \sa QGraphicsEffect::draw() |
| */ |
| void QGraphicsEffect::drawSource(QPainter *painter) |
| { |
| Q_D(const QGraphicsEffect); |
| if (d->source) |
| d->source->draw(painter); |
| } |
| |
| /*! |
| Schedules a redraw of the source. Call this function whenever the source |
| needs to be redrawn. |
| |
| \sa QGraphicsEffect::updateBoundingRect(), QWidget::update(), |
| QGraphicsItem::update(), |
| */ |
| void QGraphicsEffectSource::update() |
| { |
| d_func()->update(); |
| } |
| |
| /*! |
| Returns \c true if the source effectively is a pixmap, e.g., a |
| QGraphicsPixmapItem. |
| |
| This function is useful for optimization purposes. For instance, there's no |
| point in drawing the source in device coordinates to avoid pixmap scaling |
| if this function returns \c true - the source pixmap will be scaled anyways. |
| */ |
| bool QGraphicsEffectSource::isPixmap() const |
| { |
| return d_func()->isPixmap(); |
| } |
| |
| /*! |
| Returns \c true if the source effectively is a pixmap, e.g., a |
| QGraphicsPixmapItem. |
| |
| This function is useful for optimization purposes. For instance, there's no |
| point in drawing the source in device coordinates to avoid pixmap scaling |
| if this function returns \c true - the source pixmap will be scaled anyways. |
| */ |
| bool QGraphicsEffect::sourceIsPixmap() const |
| { |
| return source() ? source()->isPixmap() : false; |
| } |
| |
| /*! |
| Returns a pixmap with the source painted into it. |
| |
| The \a system specifies which coordinate system to be used for the source. |
| The optional \a offset parameter returns the offset where the pixmap should |
| be painted at using the current painter. |
| |
| The \a mode determines how much of the effect the pixmap will contain. |
| By default, the pixmap will contain the whole effect. |
| |
| The returned pixmap is bound to the current painter's device rectangle when |
| \a system is Qt::DeviceCoordinates. |
| |
| \sa QGraphicsEffect::draw(), boundingRect() |
| */ |
| QPixmap QGraphicsEffectSource::pixmap(Qt::CoordinateSystem system, QPoint *offset, QGraphicsEffect::PixmapPadMode mode) const |
| { |
| Q_D(const QGraphicsEffectSource); |
| |
| // Shortcut, no cache for childless pixmap items... |
| const QGraphicsItem *item = graphicsItem(); |
| if (system == Qt::LogicalCoordinates && mode == QGraphicsEffect::NoPad && item && isPixmap()) { |
| const QGraphicsPixmapItem *pixmapItem = static_cast<const QGraphicsPixmapItem *>(item); |
| if (offset) |
| *offset = pixmapItem->offset().toPoint(); |
| return pixmapItem->pixmap(); |
| } |
| |
| if (Q_UNLIKELY(system == Qt::DeviceCoordinates && item && |
| !static_cast<const QGraphicsItemEffectSourcePrivate *>(d_func())->info)) { |
| qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context"); |
| return QPixmap(); |
| } |
| |
| QPixmap pm; |
| if (item && d->m_cachedSystem == system && d->m_cachedMode == mode) |
| QPixmapCache::find(d->m_cacheKey, &pm); |
| |
| if (pm.isNull()) { |
| pm = d->pixmap(system, &d->m_cachedOffset, mode); |
| d->m_cachedSystem = system; |
| d->m_cachedMode = mode; |
| |
| d->invalidateCache(); |
| d->m_cacheKey = QPixmapCache::insert(pm); |
| } |
| |
| if (offset) |
| *offset = d->m_cachedOffset; |
| |
| return pm; |
| } |
| |
| /*! |
| Returns a pixmap with the source painted into it. |
| |
| The \a system specifies which coordinate system to be used for the source. |
| The optional \a offset parameter returns the offset where the pixmap should |
| be painted at using the current painter. For control on how the pixmap is |
| padded use the \a mode parameter. |
| |
| The returned pixmap is clipped to the current painter's device rectangle when |
| \a system is Qt::DeviceCoordinates. |
| |
| Calling this function with Qt::DeviceCoordinates outside of |
| QGraphicsEffect::draw() will give undefined results, as there is no device |
| context available. |
| |
| \sa draw(), boundingRect() |
| */ |
| QPixmap QGraphicsEffect::sourcePixmap(Qt::CoordinateSystem system, QPoint *offset, QGraphicsEffect::PixmapPadMode mode) const |
| { |
| Q_D(const QGraphicsEffect); |
| if (d->source) |
| return d->source->pixmap(system, offset, mode); |
| return QPixmap(); |
| } |
| |
| QGraphicsEffectSourcePrivate::~QGraphicsEffectSourcePrivate() |
| { |
| invalidateCache(); |
| } |
| |
| void QGraphicsEffectSourcePrivate::setCachedOffset(const QPoint &offset) |
| { |
| m_cachedOffset = offset; |
| } |
| |
| void QGraphicsEffectSourcePrivate::invalidateCache(InvalidateReason reason) const |
| { |
| if (m_cachedMode != QGraphicsEffect::PadToEffectiveBoundingRect |
| && (reason == EffectRectChanged |
| || (reason == TransformChanged && m_cachedSystem == Qt::LogicalCoordinates))) { |
| return; |
| } |
| |
| QPixmapCache::remove(m_cacheKey); |
| } |
| |
| /*! |
| Constructs a new QGraphicsEffect instance having the |
| specified \a parent. |
| */ |
| QGraphicsEffect::QGraphicsEffect(QObject *parent) |
| : QObject(*new QGraphicsEffectPrivate, parent) |
| { |
| } |
| |
| /*! |
| \internal |
| */ |
| QGraphicsEffect::QGraphicsEffect(QGraphicsEffectPrivate &dd, QObject *parent) |
| : QObject(dd, parent) |
| { |
| } |
| |
| /*! |
| Removes the effect from the source, and destroys the graphics effect. |
| */ |
| QGraphicsEffect::~QGraphicsEffect() |
| { |
| Q_D(QGraphicsEffect); |
| d->setGraphicsEffectSource(nullptr); |
| } |
| |
| /*! |
| Returns the effective bounding rectangle for this effect, i.e., the |
| bounding rectangle of the source in device coordinates, adjusted by |
| any margins applied by the effect itself. |
| |
| \sa boundingRectFor(), updateBoundingRect() |
| */ |
| QRectF QGraphicsEffect::boundingRect() const |
| { |
| Q_D(const QGraphicsEffect); |
| if (d->source) |
| return boundingRectFor(d->source->boundingRect()); |
| return QRectF(); |
| } |
| |
| /*! |
| Returns the effective bounding rectangle for this effect, given the |
| provided \a rect in the device coordinates. When writing |
| you own custom effect, you must call updateBoundingRect() whenever any |
| parameters are changed that may cause this this function to return a |
| different value. |
| |
| \sa sourceBoundingRect() |
| */ |
| QRectF QGraphicsEffect::boundingRectFor(const QRectF &rect) const |
| { |
| return rect; |
| } |
| |
| /*! |
| \property QGraphicsEffect::enabled |
| \brief whether the effect is enabled or not. |
| |
| If an effect is disabled, the source will be rendered with as normal, with |
| no interference from the effect. If the effect is enabled, the source will |
| be rendered with the effect applied. |
| |
| This property is enabled by default. |
| |
| Using this property, you can disable certain effects on slow platforms, in |
| order to ensure that the user interface is responsive. |
| */ |
| bool QGraphicsEffect::isEnabled() const |
| { |
| Q_D(const QGraphicsEffect); |
| return d->isEnabled; |
| } |
| |
| void QGraphicsEffect::setEnabled(bool enable) |
| { |
| Q_D(QGraphicsEffect); |
| if (d->isEnabled == enable) |
| return; |
| |
| d->isEnabled = enable; |
| if (d->source) { |
| d->source->d_func()->effectBoundingRectChanged(); |
| d->source->d_func()->invalidateCache(); |
| } |
| emit enabledChanged(enable); |
| } |
| |
| /*! |
| \fn void QGraphicsEffect::enabledChanged(bool enabled) |
| |
| This signal is emitted whenever the effect is enabled or disabled. |
| The \a enabled parameter holds the effects's new enabled state. |
| |
| \sa isEnabled() |
| */ |
| |
| /*! |
| Schedules a redraw of the effect. Call this function whenever the effect |
| needs to be redrawn. This function does not trigger a redraw of the source. |
| |
| \sa updateBoundingRect() |
| */ |
| void QGraphicsEffect::update() |
| { |
| Q_D(QGraphicsEffect); |
| if (d->source) |
| d->source->update(); |
| } |
| |
| /*! |
| \internal |
| |
| Returns a pointer to the source, which provides extra context information |
| that can be useful for the effect. |
| |
| \sa draw() |
| */ |
| QGraphicsEffectSource *QGraphicsEffect::source() const |
| { |
| Q_D(const QGraphicsEffect); |
| return d->source; |
| } |
| |
| /*! |
| This function notifies the effect framework when the effect's bounding |
| rectangle has changed. As a custom effect author, you must call this |
| function whenever you change any parameters that will cause the virtual |
| boundingRectFor() function to return a different value. |
| |
| This function will call update() if this is necessary. |
| |
| \sa boundingRectFor(), boundingRect(), sourceBoundingRect() |
| */ |
| void QGraphicsEffect::updateBoundingRect() |
| { |
| Q_D(QGraphicsEffect); |
| if (d->source) { |
| d->source->d_func()->effectBoundingRectChanged(); |
| d->source->d_func()->invalidateCache(QGraphicsEffectSourcePrivate::EffectRectChanged); |
| } |
| } |
| |
| /*! |
| \fn virtual void QGraphicsEffect::draw(QPainter *painter) = 0 |
| |
| This pure virtual function draws the effect and is called whenever the |
| source needs to be drawn. |
| |
| Reimplement this function in a QGraphicsEffect subclass to provide the |
| effect's drawing implementation, using \a painter. |
| |
| For example: |
| |
| \snippet code/src_gui_effects_qgraphicseffect.cpp 1 |
| |
| This function should not be called explicitly by the user, since it is |
| meant for reimplementation purposes only. |
| */ |
| |
| /*! |
| \enum QGraphicsEffect::ChangeFlag |
| |
| This enum describes what has changed in QGraphicsEffectSource. |
| |
| \value SourceAttached The effect is installed on a source. |
| \value SourceDetached The effect is uninstalled on a source. |
| \value SourceBoundingRectChanged The bounding rect of the source has |
| changed. |
| \value SourceInvalidated The visual appearance of the source has changed. |
| */ |
| |
| /*! |
| \enum QGraphicsEffect::PixmapPadMode |
| |
| This enum describes how the pixmap returned from sourcePixmap should be |
| padded. |
| |
| \value NoPad The pixmap should not receive any additional |
| padding. |
| \value PadToTransparentBorder The pixmap should be padded |
| to ensure it has a completely transparent border. |
| \value PadToEffectiveBoundingRect The pixmap should be padded to |
| match the effective bounding rectangle of the effect. |
| */ |
| |
| /*! |
| This virtual function is called by QGraphicsEffect to notify the effect |
| that the source has changed. If the effect applies any cache, then this |
| cache must be purged in order to reflect the new appearance of the source. |
| |
| The \a flags describes what has changed. |
| */ |
| void QGraphicsEffect::sourceChanged(ChangeFlags flags) |
| { |
| Q_UNUSED(flags); |
| } |
| |
| /*! |
| \class QGraphicsColorizeEffect |
| \brief The QGraphicsColorizeEffect class provides a colorize effect. |
| \since 4.6 |
| \inmodule QtWidgets |
| |
| A colorize effect renders the source with a tint of its color(). The color |
| can be modified using the setColor() function. |
| |
| By default, the color is light blue (QColor(0, 0, 192)). |
| |
| \image graphicseffect-colorize.png |
| |
| \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsOpacityEffect |
| */ |
| |
| /*! |
| Constructs a new QGraphicsColorizeEffect instance. |
| The \a parent parameter is passed to QGraphicsEffect's constructor. |
| */ |
| QGraphicsColorizeEffect::QGraphicsColorizeEffect(QObject *parent) |
| : QGraphicsEffect(*new QGraphicsColorizeEffectPrivate, parent) |
| { |
| } |
| |
| /*! |
| Destroys the effect. |
| */ |
| QGraphicsColorizeEffect::~QGraphicsColorizeEffect() |
| { |
| } |
| |
| /*! |
| \property QGraphicsColorizeEffect::color |
| \brief the color of the effect. |
| |
| By default, the color is light blue (QColor(0, 0, 192)). |
| */ |
| QColor QGraphicsColorizeEffect::color() const |
| { |
| Q_D(const QGraphicsColorizeEffect); |
| return d->filter->color(); |
| } |
| |
| void QGraphicsColorizeEffect::setColor(const QColor &color) |
| { |
| Q_D(QGraphicsColorizeEffect); |
| if (d->filter->color() == color) |
| return; |
| |
| d->filter->setColor(color); |
| update(); |
| emit colorChanged(color); |
| } |
| |
| /*! |
| \property QGraphicsColorizeEffect::strength |
| \brief the strength of the effect. |
| |
| By default, the strength is 1.0. |
| A strength 0.0 equals to no effect, while 1.0 means full colorization. |
| */ |
| qreal QGraphicsColorizeEffect::strength() const |
| { |
| Q_D(const QGraphicsColorizeEffect); |
| return d->filter->strength(); |
| } |
| |
| void QGraphicsColorizeEffect::setStrength(qreal strength) |
| { |
| Q_D(QGraphicsColorizeEffect); |
| if (qFuzzyCompare(d->filter->strength(), strength)) |
| return; |
| |
| d->filter->setStrength(strength); |
| d->opaque = !qFuzzyIsNull(strength); |
| update(); |
| emit strengthChanged(strength); |
| } |
| |
| /*! \fn void QGraphicsColorizeEffect::strengthChanged(qreal strength) |
| This signal is emitted whenever setStrength() changes the colorize |
| strength property. \a strength contains the new strength value of |
| the colorize effect. |
| */ |
| |
| /*! |
| \fn void QGraphicsColorizeEffect::colorChanged(const QColor &color) |
| |
| This signal is emitted whenever the effect's color changes. |
| The \a color parameter holds the effect's new color. |
| */ |
| |
| /*! |
| \reimp |
| */ |
| void QGraphicsColorizeEffect::draw(QPainter *painter) |
| { |
| Q_D(QGraphicsColorizeEffect); |
| |
| if (!d->opaque) { |
| drawSource(painter); |
| return; |
| } |
| |
| QPoint offset; |
| if (sourceIsPixmap()) { |
| // No point in drawing in device coordinates (pixmap will be scaled anyways). |
| const QPixmap pixmap = sourcePixmap(Qt::LogicalCoordinates, &offset, NoPad); |
| if (!pixmap.isNull()) |
| d->filter->draw(painter, offset, pixmap); |
| |
| return; |
| } |
| |
| // Draw pixmap in deviceCoordinates to avoid pixmap scaling. |
| const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset); |
| if (pixmap.isNull()) |
| return; |
| |
| QTransform restoreTransform = painter->worldTransform(); |
| painter->setWorldTransform(QTransform()); |
| d->filter->draw(painter, offset, pixmap); |
| painter->setWorldTransform(restoreTransform); |
| } |
| |
| /*! |
| \class QGraphicsBlurEffect |
| \brief The QGraphicsBlurEffect class provides a blur effect. |
| \since 4.6 |
| \inmodule QtWidgets |
| |
| A blur effect blurs the source. This effect is useful for reducing details, |
| such as when the source loses focus and you want to draw attention to other |
| elements. The level of detail can be modified using the setBlurRadius() |
| function. Use setBlurHints() to choose the blur hints. |
| |
| By default, the blur radius is 5 pixels. The blur radius is specified in |
| device coordinates. |
| |
| \image graphicseffect-blur.png |
| |
| \sa QGraphicsDropShadowEffect, QGraphicsColorizeEffect, QGraphicsOpacityEffect |
| */ |
| |
| /*! |
| \enum QGraphicsBlurEffect::BlurHint |
| \since 4.6 |
| |
| This enum describes the possible hints that can be used to control how |
| blur effects are applied. The hints might not have an effect in all the |
| paint engines. |
| |
| \value PerformanceHint Indicates that rendering performance is the most important factor, |
| at the potential cost of lower quality. |
| |
| \value QualityHint Indicates that rendering quality is the most important factor, |
| at the potential cost of lower performance. |
| |
| \value AnimationHint Indicates that the blur radius is going to be animated, hinting |
| that the implementation can keep a cache of blurred verisons of the source. |
| Do not use this hint if the source is going to be dynamically changing. |
| |
| \sa blurHints(), setBlurHints() |
| */ |
| |
| |
| /*! |
| Constructs a new QGraphicsBlurEffect instance. |
| The \a parent parameter is passed to QGraphicsEffect's constructor. |
| */ |
| QGraphicsBlurEffect::QGraphicsBlurEffect(QObject *parent) |
| : QGraphicsEffect(*new QGraphicsBlurEffectPrivate, parent) |
| { |
| Q_D(QGraphicsBlurEffect); |
| d->filter->setBlurHints(QGraphicsBlurEffect::PerformanceHint); |
| } |
| |
| /*! |
| Destroys the effect. |
| */ |
| QGraphicsBlurEffect::~QGraphicsBlurEffect() |
| { |
| } |
| |
| /*! |
| \property QGraphicsBlurEffect::blurRadius |
| \brief the blur radius of the effect. |
| |
| Using a smaller radius results in a sharper appearance, whereas a bigger |
| radius results in a more blurred appearance. |
| |
| By default, the blur radius is 5 pixels. |
| |
| The radius is given in device coordinates, meaning it is |
| unaffected by scale. |
| */ |
| qreal QGraphicsBlurEffect::blurRadius() const |
| { |
| Q_D(const QGraphicsBlurEffect); |
| return d->filter->radius(); |
| } |
| |
| void QGraphicsBlurEffect::setBlurRadius(qreal radius) |
| { |
| Q_D(QGraphicsBlurEffect); |
| if (qFuzzyCompare(d->filter->radius(), radius)) |
| return; |
| |
| d->filter->setRadius(radius); |
| updateBoundingRect(); |
| emit blurRadiusChanged(radius); |
| } |
| |
| /*! |
| \fn void QGraphicsBlurEffect::blurRadiusChanged(qreal radius) |
| |
| This signal is emitted whenever the effect's blur radius changes. |
| The \a radius parameter holds the effect's new blur radius. |
| */ |
| |
| /*! |
| \property QGraphicsBlurEffect::blurHints |
| \brief the blur hint of the effect. |
| |
| Use the PerformanceHint hint to say that you want a faster blur, |
| the QualityHint hint to say that you prefer a higher quality blur, |
| or the AnimationHint when you want to animate the blur radius. |
| |
| By default, the blur hint is PerformanceHint. |
| */ |
| QGraphicsBlurEffect::BlurHints QGraphicsBlurEffect::blurHints() const |
| { |
| Q_D(const QGraphicsBlurEffect); |
| return d->filter->blurHints(); |
| } |
| |
| void QGraphicsBlurEffect::setBlurHints(QGraphicsBlurEffect::BlurHints hints) |
| { |
| Q_D(QGraphicsBlurEffect); |
| if (d->filter->blurHints() == hints) |
| return; |
| |
| d->filter->setBlurHints(hints); |
| emit blurHintsChanged(hints); |
| } |
| |
| /*! |
| \fn void QGraphicsBlurEffect::blurHintsChanged(QGraphicsBlurEffect::BlurHints hints) |
| |
| This signal is emitted whenever the effect's blur hints changes. |
| The \a hints parameter holds the effect's new blur hints. |
| */ |
| |
| /*! |
| \reimp |
| */ |
| QRectF QGraphicsBlurEffect::boundingRectFor(const QRectF &rect) const |
| { |
| Q_D(const QGraphicsBlurEffect); |
| return d->filter->boundingRectFor(rect); |
| } |
| |
| /*! |
| \reimp |
| */ |
| void QGraphicsBlurEffect::draw(QPainter *painter) |
| { |
| Q_D(QGraphicsBlurEffect); |
| if (d->filter->radius() < 1) { |
| drawSource(painter); |
| return; |
| } |
| |
| PixmapPadMode mode = PadToEffectiveBoundingRect; |
| |
| QPoint offset; |
| QPixmap pixmap = sourcePixmap(Qt::LogicalCoordinates, &offset, mode); |
| if (pixmap.isNull()) |
| return; |
| |
| d->filter->draw(painter, offset, pixmap); |
| } |
| |
| /*! |
| \class QGraphicsDropShadowEffect |
| \brief The QGraphicsDropShadowEffect class provides a drop shadow effect. |
| \since 4.6 |
| \inmodule QtWidgets |
| |
| A drop shadow effect renders the source with a drop shadow. The color of |
| the drop shadow can be modified using the setColor() function. The drop |
| shadow offset can be modified using the setOffset() function and the blur |
| radius of the drop shadow can be changed with the setBlurRadius() |
| function. |
| |
| By default, the drop shadow is a semi-transparent dark gray |
| (QColor(63, 63, 63, 180)) shadow, blurred with a radius of 1 at an offset |
| of 8 pixels towards the lower right. The drop shadow offset is specified |
| in device coordinates. |
| |
| \image graphicseffect-drop-shadow.png |
| |
| \sa QGraphicsBlurEffect, QGraphicsColorizeEffect, QGraphicsOpacityEffect |
| */ |
| |
| /*! |
| Constructs a new QGraphicsDropShadowEffect instance. |
| The \a parent parameter is passed to QGraphicsEffect's constructor. |
| */ |
| QGraphicsDropShadowEffect::QGraphicsDropShadowEffect(QObject *parent) |
| : QGraphicsEffect(*new QGraphicsDropShadowEffectPrivate, parent) |
| { |
| } |
| |
| /*! |
| Destroys the effect. |
| */ |
| QGraphicsDropShadowEffect::~QGraphicsDropShadowEffect() |
| { |
| } |
| |
| /*! |
| \property QGraphicsDropShadowEffect::offset |
| \brief the shadow offset in pixels. |
| |
| By default, the offset is 8 pixels towards the lower right. |
| |
| The offset is given in device coordinates, which means it is |
| unaffected by scale. |
| |
| \sa xOffset(), yOffset(), blurRadius(), color() |
| */ |
| QPointF QGraphicsDropShadowEffect::offset() const |
| { |
| Q_D(const QGraphicsDropShadowEffect); |
| return d->filter->offset(); |
| } |
| |
| void QGraphicsDropShadowEffect::setOffset(const QPointF &offset) |
| { |
| Q_D(QGraphicsDropShadowEffect); |
| if (d->filter->offset() == offset) |
| return; |
| |
| d->filter->setOffset(offset); |
| updateBoundingRect(); |
| emit offsetChanged(offset); |
| } |
| |
| /*! |
| \property QGraphicsDropShadowEffect::xOffset |
| \brief the horizontal shadow offset in pixels. |
| |
| By default, the horizontal shadow offset is 8 pixels. |
| |
| |
| |
| \sa yOffset(), offset() |
| */ |
| |
| /*! |
| \property QGraphicsDropShadowEffect::yOffset |
| \brief the vertical shadow offset in pixels. |
| |
| By default, the vertical shadow offset is 8 pixels. |
| |
| \sa xOffset(), offset() |
| */ |
| |
| /*! |
| \fn void QGraphicsDropShadowEffect::offsetChanged(const QPointF &offset) |
| |
| This signal is emitted whenever the effect's shadow offset changes. |
| The \a offset parameter holds the effect's new shadow offset. |
| */ |
| |
| /*! |
| \property QGraphicsDropShadowEffect::blurRadius |
| \brief the blur radius in pixels of the drop shadow. |
| |
| Using a smaller radius results in a sharper shadow, whereas using a bigger |
| radius results in a more blurred shadow. |
| |
| By default, the blur radius is 1 pixel. |
| |
| \sa color(), offset() |
| */ |
| qreal QGraphicsDropShadowEffect::blurRadius() const |
| { |
| Q_D(const QGraphicsDropShadowEffect); |
| return d->filter->blurRadius(); |
| } |
| |
| void QGraphicsDropShadowEffect::setBlurRadius(qreal blurRadius) |
| { |
| Q_D(QGraphicsDropShadowEffect); |
| if (qFuzzyCompare(d->filter->blurRadius(), blurRadius)) |
| return; |
| |
| d->filter->setBlurRadius(blurRadius); |
| updateBoundingRect(); |
| emit blurRadiusChanged(blurRadius); |
| } |
| |
| /*! |
| \fn void QGraphicsDropShadowEffect::blurRadiusChanged(qreal blurRadius) |
| |
| This signal is emitted whenever the effect's blur radius changes. |
| The \a blurRadius parameter holds the effect's new blur radius. |
| */ |
| |
| /*! |
| \property QGraphicsDropShadowEffect::color |
| \brief the color of the drop shadow. |
| |
| By default, the drop color is a semi-transparent dark gray |
| (QColor(63, 63, 63, 180)). |
| |
| \sa offset(), blurRadius() |
| */ |
| QColor QGraphicsDropShadowEffect::color() const |
| { |
| Q_D(const QGraphicsDropShadowEffect); |
| return d->filter->color(); |
| } |
| |
| void QGraphicsDropShadowEffect::setColor(const QColor &color) |
| { |
| Q_D(QGraphicsDropShadowEffect); |
| if (d->filter->color() == color) |
| return; |
| |
| d->filter->setColor(color); |
| update(); |
| emit colorChanged(color); |
| } |
| |
| /*! |
| \fn void QGraphicsDropShadowEffect::colorChanged(const QColor &color) |
| |
| This signal is emitted whenever the effect's color changes. |
| The \a color parameter holds the effect's new color. |
| */ |
| |
| /*! |
| \reimp |
| */ |
| QRectF QGraphicsDropShadowEffect::boundingRectFor(const QRectF &rect) const |
| { |
| Q_D(const QGraphicsDropShadowEffect); |
| return d->filter->boundingRectFor(rect); |
| } |
| |
| /*! |
| \reimp |
| */ |
| void QGraphicsDropShadowEffect::draw(QPainter *painter) |
| { |
| Q_D(QGraphicsDropShadowEffect); |
| if (d->filter->blurRadius() <= 0 && d->filter->offset().isNull()) { |
| drawSource(painter); |
| return; |
| } |
| |
| PixmapPadMode mode = PadToEffectiveBoundingRect; |
| |
| // Draw pixmap in device coordinates to avoid pixmap scaling. |
| QPoint offset; |
| const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset, mode); |
| if (pixmap.isNull()) |
| return; |
| |
| QTransform restoreTransform = painter->worldTransform(); |
| painter->setWorldTransform(QTransform()); |
| d->filter->draw(painter, offset, pixmap); |
| painter->setWorldTransform(restoreTransform); |
| } |
| |
| /*! |
| \class QGraphicsOpacityEffect |
| \brief The QGraphicsOpacityEffect class provides an opacity effect. |
| \since 4.6 |
| \inmodule QtWidgets |
| |
| An opacity effect renders the source with an opacity. This effect is useful |
| for making the source semi-transparent, similar to a fade-in/fade-out |
| sequence. The opacity can be modified using the setOpacity() function. |
| |
| By default, the opacity is 0.7. |
| |
| \image graphicseffect-opacity.png |
| |
| \sa QGraphicsDropShadowEffect, QGraphicsBlurEffect, QGraphicsColorizeEffect |
| */ |
| |
| /*! |
| Constructs a new QGraphicsOpacityEffect instance. |
| The \a parent parameter is passed to QGraphicsEffect's constructor. |
| */ |
| QGraphicsOpacityEffect::QGraphicsOpacityEffect(QObject *parent) |
| : QGraphicsEffect(*new QGraphicsOpacityEffectPrivate, parent) |
| { |
| } |
| |
| /*! |
| Destroys the effect. |
| */ |
| QGraphicsOpacityEffect::~QGraphicsOpacityEffect() |
| { |
| } |
| |
| /*! |
| \property QGraphicsOpacityEffect::opacity |
| \brief the opacity of the effect. |
| |
| The value should be in the range of 0.0 to 1.0, where 0.0 is |
| fully transparent and 1.0 is fully opaque. |
| |
| By default, the opacity is 0.7. |
| |
| \sa setOpacityMask() |
| */ |
| qreal QGraphicsOpacityEffect::opacity() const |
| { |
| Q_D(const QGraphicsOpacityEffect); |
| return d->opacity; |
| } |
| |
| void QGraphicsOpacityEffect::setOpacity(qreal opacity) |
| { |
| Q_D(QGraphicsOpacityEffect); |
| opacity = qBound(qreal(0.0), opacity, qreal(1.0)); |
| |
| if (qFuzzyCompare(d->opacity, opacity)) |
| return; |
| |
| d->opacity = opacity; |
| if ((d->isFullyTransparent = qFuzzyIsNull(d->opacity))) |
| d->isFullyOpaque = 0; |
| else |
| d->isFullyOpaque = qFuzzyIsNull(d->opacity - 1); |
| update(); |
| emit opacityChanged(opacity); |
| } |
| |
| /*! |
| \fn void QGraphicsOpacityEffect::opacityChanged(qreal opacity) |
| |
| This signal is emitted whenever the effect's opacity changes. |
| The \a opacity parameter holds the effect's new 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 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); |
| update(); |
| |
| 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) |
| { |
| Q_D(QGraphicsOpacityEffect); |
| |
| // Transparent; nothing to draw. |
| if (d->isFullyTransparent) |
| return; |
| |
| // Opaque; draw directly without going through a pixmap. |
| if (d->isFullyOpaque && !d->hasOpacityMask) { |
| drawSource(painter); |
| return; |
| } |
| |
| QPoint offset; |
| Qt::CoordinateSystem system = sourceIsPixmap() ? Qt::LogicalCoordinates : Qt::DeviceCoordinates; |
| QPixmap pixmap = sourcePixmap(system, &offset, QGraphicsEffect::NoPad); |
| if (pixmap.isNull()) |
| return; |
| |
| painter->save(); |
| painter->setOpacity(d->opacity); |
| |
| if (d->hasOpacityMask) { |
| QPainter pixmapPainter(&pixmap); |
| pixmapPainter.setRenderHints(painter->renderHints()); |
| pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationIn); |
| if (system == Qt::DeviceCoordinates) { |
| QTransform worldTransform = painter->worldTransform(); |
| worldTransform *= QTransform::fromTranslate(-offset.x(), -offset.y()); |
| pixmapPainter.setWorldTransform(worldTransform); |
| pixmapPainter.fillRect(sourceBoundingRect(), d->opacityMask); |
| } else { |
| pixmapPainter.translate(-offset); |
| pixmapPainter.fillRect(pixmap.rect(), d->opacityMask); |
| } |
| } |
| |
| if (system == Qt::DeviceCoordinates) |
| painter->setWorldTransform(QTransform()); |
| |
| painter->drawPixmap(offset, pixmap); |
| painter->restore(); |
| } |
| |
| |
| QT_END_NAMESPACE |
| |
| #include "moc_qgraphicseffect.cpp" |
| #include "moc_qgraphicseffect_p.cpp" |