File indexing completed on 2024-04-28 04:18:53

0001 // vim: set tabstop=4 shiftwidth=4 expandtab:
0002 /*
0003 Gwenview: an image viewer
0004 Copyright 2011 Aurélien Gâteau <agateau@kde.org>
0005 
0006 This program is free software; you can redistribute it and/or
0007 modify it under the terms of the GNU General Public License
0008 as published by the Free Software Foundation; either version 2
0009 of the License, or (at your option) any later version.
0010 
0011 This program is distributed in the hope that it will be useful,
0012 but WITHOUT ANY WARRANTY; without even the implied warranty of
0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014 GNU General Public License for more details.
0015 
0016 You should have received a copy of the GNU General Public License
0017 along with this program; if not, write to the Free Software
0018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA.
0019 
0020 */
0021 // Self
0022 #include "shadowfilter.h"
0023 
0024 // Local
0025 
0026 // KF
0027 
0028 // Qt
0029 #include <QColor>
0030 #include <QCoreApplication>
0031 #include <QHash>
0032 #include <QPainter>
0033 #include <QWidget>
0034 
0035 namespace Gwenview
0036 {
0037 struct ShadowFilterPrivate {
0038     QWidget *mWidget = nullptr;
0039     QHash<ShadowFilter::WidgetEdge, QColor> mShadows;
0040 
0041     void paintShadow(QPainter *painter, const QColor &color, QPoint origin, int dx, int dy)
0042     {
0043         const int gradientSize = 12;
0044 
0045         if (color == Qt::transparent) {
0046             return;
0047         }
0048         QLinearGradient gradient;
0049         gradient.setColorAt(0, color);
0050         gradient.setColorAt(1, Qt::transparent);
0051         gradient.setStart(origin);
0052         gradient.setFinalStop(origin.x() + dx * gradientSize, origin.y() + dy * gradientSize);
0053         painter->fillRect(mWidget->rect(), gradient);
0054     }
0055 
0056     void paint()
0057     {
0058         QPainter painter(mWidget);
0059         const QRect rect = mWidget->rect();
0060         QColor color;
0061 
0062         color = mShadows.value(ShadowFilter::LeftEdge, Qt::transparent);
0063         paintShadow(&painter, color, rect.topLeft(), 1, 0);
0064 
0065         color = mShadows.value(ShadowFilter::TopEdge, Qt::transparent);
0066         paintShadow(&painter, color, rect.topLeft(), 0, 1);
0067 
0068         color = mShadows.value(ShadowFilter::RightEdge, Qt::transparent);
0069         paintShadow(&painter, color, rect.topRight(), -1, 0);
0070 
0071         color = mShadows.value(ShadowFilter::BottomEdge, Qt::transparent);
0072         paintShadow(&painter, color, rect.bottomLeft(), 0, -1);
0073     }
0074 };
0075 
0076 ShadowFilter::ShadowFilter(QWidget *widget)
0077     : QObject(widget)
0078     , d(new ShadowFilterPrivate)
0079 {
0080     d->mWidget = widget;
0081     widget->installEventFilter(this);
0082 }
0083 
0084 ShadowFilter::~ShadowFilter()
0085 {
0086     delete d;
0087 }
0088 
0089 void ShadowFilter::setShadow(ShadowFilter::WidgetEdge edge, const QColor &color)
0090 {
0091     d->mShadows[edge] = color;
0092 }
0093 
0094 void ShadowFilter::reset()
0095 {
0096     d->mShadows.clear();
0097 }
0098 
0099 bool ShadowFilter::eventFilter(QObject *obj, QEvent *event)
0100 {
0101     if (event->type() == QEvent::Paint) {
0102         obj->removeEventFilter(this);
0103         QCoreApplication::sendEvent(obj, event);
0104         d->paint();
0105         obj->installEventFilter(this);
0106         return true;
0107     }
0108     return false;
0109 }
0110 
0111 } // namespace
0112 
0113 #include "moc_shadowfilter.cpp"