Krita Source Code Documentation
Loading...
Searching...
No Matches
KisResourceThumbnailPainter.cpp
Go to the documentation of this file.
1/* This file is part of the KDE project
2 * SPDX-FileCopyrightText: 2008 Jan Hambrecht <jaham@gmx.net>
3 * SPDX-FileCopyrightText: 2018 Boudewijn Rempt <boud@valdyas.org>
4 *
5 * SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7
9#include "KisResourceModel.h"
10
11#include <QPainter>
12#include <QDebug>
13
15
17 : QObject(parent)
18 , m_checkerPainter(4)
19{
20}
21
22QImage KisResourceThumbnailPainter::getReadyThumbnail(const QModelIndex &index, QSize size, const QPalette& palette) const
23{
24 QImage thumbLabel = QImage(size, QImage::Format_ARGB32);
25 thumbLabel.fill(Qt::white);
26 QPainter painter(&thumbLabel);
27 paint(&painter, index, QRect(QPoint(0, 0), size), palette, false, false);
28 return thumbLabel;
29}
30void KisResourceThumbnailPainter::paint(QPainter *painter, const QModelIndex& globalIndex, QRect rect, const QPalette& palette, bool selected, bool addMargin) const
31{
32 const qreal devicePixelRatioF = painter->device()->devicePixelRatioF();
33
34 QImage thumbnail = KisResourceThumbnailCache::instance()->getImage(globalIndex);
35 thumbnail.setDevicePixelRatio(devicePixelRatioF);
36
37 const QString resourceType = globalIndex.data(Qt::UserRole + KisAbstractResourceModel::ResourceType).toString();
38 const QString name = globalIndex.data(Qt::UserRole + KisAbstractResourceModel::Tooltip).toString();
39
40 painter->save();
41
42 if(addMargin) {
43 // margin has empty space...which we want to be the color palette background
44 painter->fillRect(rect, palette.window());
45 }
46
47 if (selected) {
48 painter->fillRect(rect, palette.highlight());
49 }
50
51 QRect innerRect = addMargin ? rect.adjusted(2, 2, -2, -2) : rect;
52 QSize innerRectSizeDPI = innerRect.size() * devicePixelRatioF;
53
54 painter->setRenderHint(QPainter::SmoothPixmapTransform, true);
55
56 if (resourceType == ResourceType::Gradients) {
57 m_checkerPainter.paint(*painter, innerRect, innerRect.topLeft());
58 if (!thumbnail.isNull()) {
59 thumbnail = KisResourceThumbnailCache::instance()->getImage(globalIndex,
60 innerRectSizeDPI,
61 Qt::IgnoreAspectRatio,
62 Qt::SmoothTransformation);
63 thumbnail.setDevicePixelRatio(devicePixelRatioF);
64 painter->drawImage(innerRect.topLeft(), thumbnail);
65 }
66 } else if (resourceType == ResourceType::Patterns) {
67 painter->fillRect(innerRect, Qt::white); // no checkers, they are confusing with patterns.
68 // for large patterns, scale down to no less than 50% zoom and crop it,
69 // to see distinguishing details without being too zoomed in
70 double scale = qMin(double(thumbnail.height()) / innerRectSizeDPI.height(), double(thumbnail.width()) / innerRectSizeDPI.width());
71 if (!thumbnail.isNull() && (scale >= 1.0)) {
72 scale = qMin(scale, 2.0);
73 QRect sourceRect = QRect(0, 0, innerRectSizeDPI.width() * scale, innerRectSizeDPI.height() * scale);
74 painter->drawImage(innerRect, thumbnail, sourceRect);
75 } else {
76 // crisply transform small patterns, which get scaled up to user-space,
77 // preventing them from being too tiny to see on hi-dpi
78 painter->setRenderHint(QPainter::SmoothPixmapTransform, false);
79 QBrush patternBrush(thumbnail);
80 painter->setBrushOrigin(innerRect.topLeft());
81 painter->fillRect(innerRect, patternBrush);
82 }
83 } else if (resourceType == ResourceType::WindowLayouts) {
84 // TODO: thumbnails for window layouts?
85 painter->fillRect(innerRect, Qt::white);
86 QPen before = painter->pen();
87 painter->setPen(Qt::black);
88 painter->drawText(innerRect, Qt::TextWordWrap, name.split("_").join(" "));
89 painter->setPen(before);
90 } else {
91 painter->fillRect(innerRect, Qt::white); // no checkers, they are confusing with patterns.
92 if (!thumbnail.isNull() && !(thumbnail.height() == innerRectSizeDPI.height() &&
93 thumbnail.width() == innerRectSizeDPI.width())) {
94 bool needsUpscaling = thumbnail.height() < innerRectSizeDPI.height()
95 || thumbnail.width() < innerRectSizeDPI.width();
96
97 thumbnail = KisResourceThumbnailCache::instance()->getImage(globalIndex,
98 innerRectSizeDPI,
99 Qt::KeepAspectRatio,
100 needsUpscaling ? Qt::FastTransformation
101 : Qt::SmoothTransformation);
102 thumbnail.setDevicePixelRatio(devicePixelRatioF);
103 }
104 QPoint topleft(innerRect.topLeft());
105
106 if (thumbnail.width() < innerRectSizeDPI.width()) {
107 topleft.setX(topleft.x() + (innerRect.width() - thumbnail.width()/devicePixelRatioF) / 2);
108 }
109 if (thumbnail.height() < innerRectSizeDPI.height()) {
110 topleft.setY(topleft.y() + (innerRect.height() - thumbnail.height()/devicePixelRatioF) / 2);
111 }
112 painter->drawImage(topleft, thumbnail);
113 }
114
115 painter->restore();
116}
static KisResourceThumbnailCache * instance()
QImage getImage(const QModelIndex &index, const QSize size=QSize(-1, -1), Qt::AspectRatioMode aspectMode=Qt::IgnoreAspectRatio, Qt::TransformationMode transformMode=Qt::FastTransformation)
void paint(QPainter *painter, const QModelIndex &index, QRect rect, const QPalette &palette, bool selected, bool addMargin) const
QImage getReadyThumbnail(const QModelIndex &globalIndex, QSize rect, const QPalette &palette) const
void paint(QPainter &painter, const QRectF &rect, const QPointF &patternOrigin) const
const QString Patterns
const QString Gradients
const QString WindowLayouts
rgba palette[MAX_PALETTE]
Definition palette.c:35