File indexing completed on 2024-05-19 04:27:45

0001 /* This file is part of the KDE project
0002  * SPDX-FileCopyrightText: 2008 Jan Hambrecht <jaham@gmx.net>
0003  * SPDX-FileCopyrightText: 2018 Boudewijn Rempt <boud@valdyas.org>
0004  *
0005  * SPDX-License-Identifier: LGPL-2.0-or-later
0006  */
0007 
0008 #include "KisResourceThumbnailPainter.h"
0009 #include "KisResourceModel.h"
0010 
0011 #include <QPainter>
0012 #include <QDebug>
0013 
0014 #include <KisResourceThumbnailCache.h>
0015 
0016 KisResourceThumbnailPainter::KisResourceThumbnailPainter(QObject *parent)
0017     : QObject(parent)
0018     , m_checkerPainter(4)
0019 {
0020 }
0021 
0022 QImage KisResourceThumbnailPainter::getReadyThumbnail(const QModelIndex &index, QSize size, const QPalette& palette) const
0023 {
0024     QImage thumbLabel = QImage(size, QImage::Format_ARGB32);
0025     thumbLabel.fill(Qt::white);
0026     QPainter painter(&thumbLabel);
0027     paint(&painter, index, QRect(QPoint(0, 0), size), palette, false, false);
0028     return thumbLabel;
0029 }
0030 
0031 void KisResourceThumbnailPainter::paint(QPainter *painter, const QModelIndex& index, QRect rect, const QPalette& palette, bool selected, bool addMargin) const
0032 {
0033     const qreal devicePixelRatioF = painter->device()->devicePixelRatioF();
0034 
0035     QImage thumbnail = KisResourceThumbnailCache::instance()->getImage(index);
0036     thumbnail.setDevicePixelRatio(devicePixelRatioF);
0037 
0038     const QString resourceType = index.data(Qt::UserRole + KisAbstractResourceModel::ResourceType).toString();
0039     const QString name = index.data(Qt::UserRole + KisAbstractResourceModel::Tooltip).toString();
0040 
0041     painter->save();
0042 
0043     if(addMargin) {
0044         // margin has empty space...which we want to be the color palette background
0045         painter->fillRect(rect, palette.background());
0046     }
0047 
0048     if (selected) {
0049         painter->fillRect(rect, palette.highlight());
0050     }
0051 
0052     QRect innerRect = addMargin ? rect.adjusted(2, 2, -2, -2) : rect;
0053     QSize imageSize = thumbnail.size();
0054 
0055     painter->setRenderHint(QPainter::SmoothPixmapTransform, true);
0056 
0057     if (resourceType == ResourceType::Gradients) {
0058         m_checkerPainter.paint(*painter, innerRect, innerRect.topLeft());
0059         if (!thumbnail.isNull()) {
0060             thumbnail = KisResourceThumbnailCache::instance()->getImage(index,
0061                                                                          innerRect.size() * devicePixelRatioF,
0062                                                                          Qt::IgnoreAspectRatio,
0063                                                                          Qt::SmoothTransformation);
0064             thumbnail.setDevicePixelRatio(devicePixelRatioF);
0065             painter->drawImage(innerRect.topLeft(), thumbnail);
0066         }
0067     } else if (resourceType == ResourceType::Patterns) {
0068         painter->fillRect(innerRect, Qt::white); // no checkers, they are confusing with patterns.
0069         if (!thumbnail.isNull() && (imageSize.height() > innerRect.height() || imageSize.width() > innerRect.width())) {
0070             thumbnail = KisResourceThumbnailCache::instance()->getImage(index,
0071                                                                          innerRect.size() * devicePixelRatioF,
0072                                                                          Qt::KeepAspectRatio,
0073                                                                          Qt::SmoothTransformation);
0074             thumbnail.setDevicePixelRatio(devicePixelRatioF);
0075         }
0076         QBrush patternBrush(thumbnail);
0077         patternBrush.setTransform(QTransform::fromTranslate(innerRect.x(), innerRect.y()));
0078         painter->fillRect(innerRect, patternBrush);
0079     } else if (resourceType == ResourceType::Workspaces || resourceType == ResourceType::WindowLayouts) {
0080         // TODO: thumbnails for workspaces and window layouts?
0081         painter->fillRect(innerRect, Qt::white);
0082         QPen before = painter->pen();
0083         painter->setPen(Qt::black);
0084         painter->drawText(innerRect, Qt::TextWordWrap, name.split("_").join(" "));
0085         painter->setPen(before);
0086     } else {
0087         painter->fillRect(innerRect, Qt::white); // no checkers, they are confusing with patterns.
0088         if (!thumbnail.isNull()) {
0089             if (imageSize.height() > innerRect.height()*devicePixelRatioF || imageSize.width() > innerRect.width()*devicePixelRatioF) {
0090                 thumbnail =
0091                     KisResourceThumbnailCache::instance()->getImage(index,
0092                                                                      innerRect.size() * devicePixelRatioF,
0093                                                                      Qt::KeepAspectRatio,
0094                                                                      Qt::SmoothTransformation);
0095                 thumbnail.setDevicePixelRatio(devicePixelRatioF);
0096             } else if (imageSize.height() < innerRect.height() * devicePixelRatioF
0097                        || imageSize.width() < innerRect.width() * devicePixelRatioF) {
0098                 thumbnail =
0099                     KisResourceThumbnailCache::instance()->getImage(index,
0100                                                                      innerRect.size() * devicePixelRatioF,
0101                                                                      Qt::KeepAspectRatio,
0102                                                                      Qt::FastTransformation);
0103                 thumbnail.setDevicePixelRatio(devicePixelRatioF);
0104             }
0105         }
0106         QPoint topleft(innerRect.topLeft());
0107 
0108         if (thumbnail.width() < innerRect.width()*devicePixelRatioF) {
0109             topleft.setX(topleft.x() + (innerRect.width() - thumbnail.width()/devicePixelRatioF) / 2);
0110         }
0111         if (thumbnail.height() < innerRect.height()*devicePixelRatioF) {
0112             topleft.setY(topleft.y() + (innerRect.height() - thumbnail.height()/devicePixelRatioF) / 2);
0113         }
0114         painter->drawImage(topleft, thumbnail);
0115     }
0116 
0117     painter->restore();
0118 }