File indexing completed on 2024-05-12 04:19:49

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 <thumbnailview/dragpixmapgenerator.h>
0023 
0024 // Local
0025 #include "gwenview_lib_debug.h"
0026 #include <paintutils.h>
0027 
0028 // KF
0029 #include <KIconLoader>
0030 
0031 // Qt
0032 #include <QApplication>
0033 #include <QPainter>
0034 #include <QPalette>
0035 #include <QPixmap>
0036 #include <QtMath>
0037 
0038 namespace Gwenview
0039 {
0040 namespace DragPixmapGenerator
0041 {
0042 const int DRAG_THUMB_SIZE = KIconLoader::SizeHuge;
0043 const int SPREAD_ANGLE = 30;
0044 
0045 DragPixmap generate(const QList<QPixmap> &pixmaps, int totalCount)
0046 {
0047     DragPixmap out;
0048 
0049     const int extraSpace = DRAG_THUMB_SIZE / 4;
0050     const int maxHeight = qSqrt(qPow(DRAG_THUMB_SIZE + extraSpace, 2) + qPow(DRAG_THUMB_SIZE / 2, 2));
0051     out.pix = QPixmap(maxHeight * 2, maxHeight);
0052     out.pix.fill(Qt::transparent);
0053 
0054     QPainter painter(&out.pix);
0055     painter.translate(out.pix.width() / 2, out.pix.height());
0056 
0057     const int count = pixmaps.count();
0058     qreal delta = 0;
0059     if (count > 1) {
0060         painter.rotate(-SPREAD_ANGLE / 2);
0061         delta = SPREAD_ANGLE / (count - 1);
0062     }
0063 
0064     painter.setRenderHint(QPainter::Antialiasing);
0065     painter.setRenderHint(QPainter::SmoothPixmapTransform);
0066     // int index = 0;
0067     int maxX = 0;
0068     for (const QPixmap &pix : pixmaps) {
0069         QPixmap pix2 = pix.scaled(DRAG_THUMB_SIZE - 2, DRAG_THUMB_SIZE - 2, Qt::KeepAspectRatio, Qt::SmoothTransformation);
0070         QRect rect(-pix2.width() / 2, -pix2.height() - extraSpace, pix2.width(), pix2.height());
0071 
0072         if (!pix2.hasAlphaChannel()) {
0073             // Draw a thin white border around fully opaque pictures to give them a photo-like appearance
0074             painter.fillRect(rect.adjusted(-1, -1, 1, 1), Qt::white);
0075         }
0076         painter.drawPixmap(rect.topLeft(), pix2);
0077 
0078         QPoint topRight = painter.transform().map(rect.topRight());
0079         maxX = qMax(topRight.x(), maxX);
0080         /*
0081         painter.drawRect(-pix2.width() / 2, -pix2.height() - extraSpace, pix2.width(), pix2.height());
0082         painter.drawText(-pix2.width() / 2, -pix2.height() - extraSpace, pix2.width(), pix2.height(), Qt::AlignTop | Qt::AlignLeft, QString::number(index));
0083         index++;
0084         */
0085         painter.rotate(delta);
0086     }
0087     out.hotSpot = QPoint(out.pix.width() / 2, -extraSpace);
0088 
0089     if (count < totalCount) {
0090         painter.resetTransform();
0091         QString text = QString::number(totalCount);
0092         QRect rect = painter.fontMetrics().boundingRect(text);
0093         if (rect.width() < rect.height()) {
0094             rect.setWidth(rect.height());
0095         }
0096 
0097         const int padding = 1;
0098         rect.moveRight(maxX - padding - 1);
0099         rect.moveBottom(out.pix.height() - padding - 1);
0100 
0101         // Background
0102         QColor bg1 = QApplication::palette().color(QPalette::Highlight);
0103         QColor bg2 = PaintUtils::adjustedHsv(bg1, 0, 0, -50);
0104         QLinearGradient gradient(0, rect.top(), 0, rect.bottom());
0105         gradient.setColorAt(0, bg1);
0106         gradient.setColorAt(1, bg2);
0107         painter.setBrush(gradient);
0108         painter.setPen(bg1);
0109         painter.translate(-.5, -.5);
0110         painter.drawRoundedRect(rect.adjusted(-padding, -padding, padding, padding), padding, padding);
0111 
0112         // Foreground
0113         painter.setPen(QApplication::palette().color(QPalette::HighlightedText));
0114         painter.drawText(rect, Qt::AlignCenter, text);
0115     }
0116 
0117     return out;
0118 }
0119 
0120 } // DragPixmapGenerator namespace
0121 
0122 } // namespace