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 0009 #include <QPainter> 0010 #include <QDebug> 0011 #include <QStyledItemDelegate> 0012 0013 #include "KisResourceItemDelegate.h" 0014 #include "KisResourceModel.h" 0015 #include <KisResourceThumbnailCache.h> 0016 #include <KoIcon.h> 0017 0018 KisResourceItemDelegate::KisResourceItemDelegate(QObject *parent) 0019 : QAbstractItemDelegate(parent) 0020 , m_checkerPainter(4) 0021 , m_showText(false) 0022 , m_isWidget(false) 0023 { 0024 } 0025 0026 void KisResourceItemDelegate::setShowText(bool showText) 0027 { 0028 m_showText = showText; 0029 } 0030 0031 void KisResourceItemDelegate::setIsWidget(bool isWidget) 0032 { 0033 m_isWidget = isWidget; 0034 } 0035 0036 void KisResourceItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem & option, const QModelIndex &index) const 0037 { 0038 if (!index.isValid()) return; 0039 painter->save(); 0040 painter->setRenderHint(QPainter::SmoothPixmapTransform, true); 0041 if (!(option.state & QStyle::State_Enabled)) { 0042 painter->setOpacity(0.2); 0043 } 0044 0045 if (!index.isValid()) { 0046 painter->restore(); 0047 return; 0048 } 0049 0050 if (m_isWidget) { 0051 0052 bool dirty = index.data(Qt::UserRole + KisAbstractResourceModel::Dirty).toBool(); 0053 QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole)); 0054 0055 QImage preview; 0056 if (!icon.isNull()) { 0057 QSize iconSize = option.decorationSize; // or specify a desired size 0058 QPixmap pixmap = icon.pixmap(iconSize); 0059 preview = pixmap.toImage(); 0060 } 0061 0062 if (preview.isNull()) { 0063 preview = QImage(512, 512, QImage::Format_RGB32); 0064 preview.fill(Qt::red); 0065 } 0066 0067 qreal devicePixelRatioF = painter->device()->devicePixelRatioF(); 0068 QRect paintRect = option.rect.adjusted(1, 1, -1, -1); 0069 0070 if (!m_showText) { 0071 QSize pixSize(paintRect.height(), paintRect.height()); 0072 0073 QSize size = pixSize * devicePixelRatioF; 0074 Qt::AspectRatioMode aspectMode = Qt::IgnoreAspectRatio; 0075 Qt::TransformationMode transformMode = Qt::SmoothTransformation; 0076 QImage previewHighDpi = preview.scaled(size, aspectMode, transformMode); 0077 0078 previewHighDpi.setDevicePixelRatio(devicePixelRatioF); 0079 painter->drawImage(paintRect.x(), paintRect.y(), previewHighDpi); 0080 } 0081 else { 0082 QSize pixSize(paintRect.height(), paintRect.height()); 0083 0084 QSize size = pixSize * devicePixelRatioF; 0085 Qt::AspectRatioMode aspectMode = Qt::IgnoreAspectRatio; 0086 Qt::TransformationMode transformMode = Qt::SmoothTransformation; 0087 QImage previewHighDpi = preview.scaled(size, aspectMode, transformMode); 0088 0089 previewHighDpi.setDevicePixelRatio(devicePixelRatioF); 0090 painter->drawImage(paintRect.x(), paintRect.y(), previewHighDpi); 0091 0092 // Put an asterisk after the preset if it is dirty. This will help in case the pixmap icon is too small 0093 0094 QString dirtyPresetIndicator = QString(""); 0095 if (dirty) { 0096 dirtyPresetIndicator = QString("*"); 0097 } 0098 0099 // QString presetDisplayName = index.data(Qt::UserRole + KisAbstractResourceModel::Name).toString().replace("_", " "); // don't need underscores that might be part of the file name 0100 QString presetDisplayName = index.data(Qt::DisplayRole).toString(); 0101 painter->drawText(pixSize.width() + 10, option.rect.y() + option.rect.height() - 10, presetDisplayName.append(dirtyPresetIndicator)); 0102 } 0103 0104 if (dirty) { 0105 const QIcon icon = KisIconUtils::loadIcon("dirty-preset"); 0106 QPixmap pixmap = icon.pixmap(QSize(16,16)); 0107 painter->drawPixmap(paintRect.x() + 3, paintRect.y() + 3, pixmap); 0108 } 0109 0110 if (option.state & QStyle::State_Selected) { 0111 painter->setCompositionMode(QPainter::CompositionMode_HardLight); 0112 painter->setOpacity(1.0); 0113 painter->fillRect(option.rect, option.palette.highlight()); 0114 0115 // highlight is not strong enough to pick out preset. draw border around it. 0116 painter->setCompositionMode(QPainter::CompositionMode_SourceOver); 0117 painter->setPen(QPen(option.palette.highlight(), 4, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin)); 0118 QRect selectedBorder = option.rect.adjusted(2 , 2, -2, -2); // constrict the rectangle so it doesn't bleed into other presets 0119 painter->drawRect(selectedBorder); 0120 } 0121 painter->restore(); 0122 return; 0123 0124 } 0125 0126 bool dirty = index.data(Qt::UserRole + KisAbstractResourceModel::Dirty).toBool(); 0127 QImage preview = KisResourceThumbnailCache::instance()->getImage(index); 0128 0129 if (preview.isNull()) { 0130 preview = QImage(512, 512, QImage::Format_RGB32); 0131 preview.fill(Qt::red); 0132 } 0133 0134 qreal devicePixelRatioF = painter->device()->devicePixelRatioF(); 0135 QRect paintRect = option.rect.adjusted(1, 1, -1, -1); 0136 0137 if (!m_showText) { 0138 QImage previewHighDpi = 0139 KisResourceThumbnailCache::instance()->getImage(index, 0140 paintRect.size() * devicePixelRatioF, 0141 Qt::IgnoreAspectRatio, 0142 Qt::SmoothTransformation); 0143 previewHighDpi.setDevicePixelRatio(devicePixelRatioF); 0144 0145 QImage destBackground(previewHighDpi.size(), QImage::Format_RGB32); 0146 destBackground.fill(Qt::white); 0147 destBackground.setDevicePixelRatio(devicePixelRatioF); 0148 0149 painter->drawImage(paintRect.x(), paintRect.y(), destBackground); 0150 painter->drawImage(paintRect.x(), paintRect.y(), previewHighDpi); 0151 } 0152 else { 0153 QSize pixSize(paintRect.height(), paintRect.height()); 0154 QImage previewHighDpi = KisResourceThumbnailCache::instance()->getImage(index, 0155 pixSize * devicePixelRatioF, 0156 Qt::IgnoreAspectRatio, 0157 Qt::SmoothTransformation); 0158 previewHighDpi.setDevicePixelRatio(devicePixelRatioF); 0159 0160 QImage destBackground(previewHighDpi.size(), QImage::Format_RGB32); 0161 destBackground.fill(Qt::white); 0162 destBackground.setDevicePixelRatio(devicePixelRatioF); 0163 0164 painter->drawImage(paintRect.x(), paintRect.y(), destBackground); 0165 painter->drawImage(paintRect.x(), paintRect.y(), previewHighDpi); 0166 0167 // Put an asterisk after the preset if it is dirty. This will help in case the pixmap icon is too small 0168 0169 QString dirtyPresetIndicator = QString(""); 0170 if (dirty) { 0171 dirtyPresetIndicator = QString("*"); 0172 } 0173 0174 QString presetDisplayName = index.data(Qt::UserRole + KisAbstractResourceModel::Name).toString().replace("_", " "); // don't need underscores that might be part of the file name 0175 painter->drawText(pixSize.width() + 10, option.rect.y() + option.rect.height() - 10, presetDisplayName.append(dirtyPresetIndicator)); 0176 } 0177 0178 if (dirty) { 0179 const QIcon icon = KisIconUtils::loadIcon("dirty-preset"); 0180 QPixmap pixmap = icon.pixmap(QSize(16,16)); 0181 painter->drawPixmap(paintRect.x() + 3, paintRect.y() + 3, pixmap); 0182 } 0183 0184 if (option.state & QStyle::State_Selected) { 0185 painter->setCompositionMode(QPainter::CompositionMode_HardLight); 0186 painter->setOpacity(1.0); 0187 painter->fillRect(option.rect, option.palette.highlight()); 0188 0189 // highlight is not strong enough to pick out preset. draw border around it. 0190 painter->setCompositionMode(QPainter::CompositionMode_SourceOver); 0191 painter->setPen(QPen(option.palette.highlight(), 4, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin)); 0192 QRect selectedBorder = option.rect.adjusted(2 , 2, -2, -2); // constrict the rectangle so it doesn't bleed into other presets 0193 painter->drawRect(selectedBorder); 0194 } 0195 painter->restore(); 0196 0197 } 0198 0199 0200 QSize KisResourceItemDelegate::sizeHint(const QStyleOptionViewItem &optionItem, const QModelIndex &index) const 0201 { 0202 return optionItem.decorationSize; 0203 }