File indexing completed on 2024-05-12 16:01:27
0001 /* 0002 * SPDX-FileCopyrightText: 2009 Cyrille Berger <cberger@cberger.net> 0003 * SPDX-FileCopyrightText: 2011 Silvio Heinrich <plassy@web.de> 0004 * SPDX-FileCopyrightText: 2014 Mohit Goyal <mohit.bits2011@gmail.com> 0005 * 0006 * SPDX-License-Identifier: LGPL-2.1-or-later 0007 */ 0008 0009 #include "kis_categorized_item_delegate.h" 0010 #include "kis_categorized_list_model.h" 0011 0012 #include <QPainter> 0013 #include <QStyle> 0014 #include <QStyleOptionMenuItem> 0015 #include <QStyleOptionViewItem> 0016 #include <QApplication> 0017 #include <QTransform> 0018 0019 #include <KoIcon.h> 0020 0021 #include <kis_icon.h> 0022 #include "kis_debug.h" 0023 0024 KisCategorizedItemDelegate::KisCategorizedItemDelegate(QObject *parent) 0025 : QStyledItemDelegate(parent), 0026 m_minimumItemHeight(0) 0027 { 0028 } 0029 0030 void KisCategorizedItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const 0031 { 0032 painter->resetTransform(); 0033 0034 if(!index.data(__CategorizedListModelBase::IsHeaderRole).toBool()) { 0035 QStyleOptionViewItem sovi(option); 0036 0037 if (index.data(__CategorizedListModelBase::isLockableRole).toBool()) { 0038 0039 const int iconSize = qMax(16, m_minimumItemHeight - 2); 0040 bool locked = index.data(__CategorizedListModelBase::isLockedRole).toBool(); 0041 0042 0043 QIcon icon = locked ? KisIconUtils::loadIcon(koIconName("layer-locked")) : KisIconUtils::loadIcon(koIconName("layer-unlocked")); 0044 0045 // to be able to make an icon more transparent. we need to create a new image 0046 // and use the QPainter to make a more transparent version of it. 0047 QImage image(iconSize, iconSize, QImage::Format_ARGB32_Premultiplied); 0048 image.fill(Qt::transparent); // needs to happen, otherwise 'junk' pixels are used (looks bad) 0049 0050 QPainter p(&image); 0051 p.setCompositionMode(QPainter::CompositionMode_Source); 0052 0053 0054 // make unlocked icons more hidden 0055 if (locked) { 0056 p.setOpacity(1.0); 0057 } else { 0058 p.setOpacity(0.14); 0059 } 0060 0061 p.drawPixmap(0, 0, icon.pixmap(iconSize, QIcon::Normal) ); 0062 p.end(); 0063 0064 icon = QIcon( QPixmap::fromImage(image) ); // the new icon is ready 0065 0066 0067 0068 sovi.decorationPosition = QStyleOptionViewItem::Right; 0069 sovi.decorationAlignment = Qt::AlignRight; 0070 sovi.decorationSize = QSize(iconSize, iconSize); 0071 sovi.features |= QStyleOptionViewItem::HasDecoration; 0072 sovi.icon = icon; 0073 0074 } 0075 0076 QStyledItemDelegate::paint(painter, sovi, index); 0077 painter->setOpacity(1); 0078 } 0079 else { 0080 QPalette palette = QApplication::palette(); 0081 if(option.state & QStyle::State_MouseOver) 0082 painter->fillRect(option.rect, palette.midlight()); 0083 else 0084 painter->fillRect(option.rect, palette.button()); 0085 0086 painter->setBrush(palette.buttonText()); 0087 painter->drawText(option.rect, index.data().toString(), QTextOption(Qt::AlignVCenter|Qt::AlignHCenter)); 0088 0089 paintTriangle( 0090 painter, 0091 option.rect.x(), 0092 option.rect.y(), 0093 option.rect.height(), 0094 !index.data(__CategorizedListModelBase::ExpandCategoryRole).toBool() 0095 ); 0096 } 0097 painter->resetTransform(); 0098 } 0099 0100 QSize KisCategorizedItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const 0101 { 0102 //on first calling this calculates the minimal height of the items 0103 if (m_minimumItemHeight == 0) { 0104 for(int i=0; i<index.model()->rowCount(); i++) { 0105 QSize indexSize = QStyledItemDelegate::sizeHint(option, index.model()->index(i, 0)); 0106 m_minimumItemHeight = qMax(m_minimumItemHeight, indexSize.height()); 0107 0108 /** 0109 * Make all the items, including the ones having 0110 * checkboxes look the same. 0111 */ 0112 QStyle *style = QApplication::style(); 0113 QStyleOptionButton so; 0114 QSize size = style->sizeFromContents(QStyle::CT_CheckBox, &so, QSize(), 0); 0115 0116 m_minimumItemHeight = qMax(size.height(), m_minimumItemHeight); 0117 } 0118 } 0119 0120 int width = QStyledItemDelegate::sizeHint(option, index).width(); 0121 0122 if (index.data(__CategorizedListModelBase::isLockableRole).toBool()) { 0123 width += m_minimumItemHeight; 0124 } 0125 0126 return QSize(width, m_minimumItemHeight); 0127 } 0128 0129 void KisCategorizedItemDelegate::paintTriangle(QPainter* painter, qint32 x, qint32 y, qint32 size, bool rotate) const 0130 { 0131 QPolygonF triangle; 0132 triangle.push_back(QPointF(-0.2,-0.2)); 0133 triangle.push_back(QPointF( 0.2,-0.2)); 0134 triangle.push_back(QPointF( 0.0, 0.2)); 0135 0136 QTransform transform; 0137 transform.translate(x + size/2, y + size/2); 0138 transform.scale(size, size); 0139 0140 if(rotate) 0141 transform.rotate(-90); 0142 0143 QPalette palette = QApplication::palette(); 0144 painter->setBrush(palette.buttonText()); 0145 painter->drawPolygon(transform.map(triangle)); 0146 } 0147