File indexing completed on 2024-05-12 04:58:27
0001 /* ============================================================ 0002 * Falkon - Qt web browser 0003 * Copyright (C) 2010-2017 David Rosca <nowrep@gmail.com> 0004 * 0005 * This program is free software: you can redistribute it and/or modify 0006 * it under the terms of the GNU General Public License as published by 0007 * the Free Software Foundation, either version 3 of the License, or 0008 * (at your option) any later version. 0009 * 0010 * This program is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 * GNU General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU General Public License 0016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0017 * ============================================================ */ 0018 #include "listitemdelegate.h" 0019 #include "mainapplication.h" 0020 #include "proxystyle.h" 0021 0022 #include <QApplication> 0023 #include <QPainter> 0024 #include <QtGuiVersion> 0025 0026 ListItemDelegate::ListItemDelegate(int iconSize, QWidget* parent) 0027 : QStyledItemDelegate(parent) 0028 , m_iconSize(iconSize) 0029 , m_updateParentHeight(false) 0030 , m_uniformItemSizes(false) 0031 , m_itemHeight(0) 0032 , m_itemWidth(0) 0033 , m_padding(0) 0034 { 0035 } 0036 0037 void ListItemDelegate::setUpdateParentHeight(bool update) 0038 { 0039 m_updateParentHeight = update; 0040 } 0041 0042 void ListItemDelegate::setUniformItemSizes(bool uniform) 0043 { 0044 m_uniformItemSizes = uniform; 0045 } 0046 0047 int ListItemDelegate::itemHeight() const 0048 { 0049 return m_itemHeight; 0050 } 0051 0052 void ListItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index) const 0053 { 0054 QStyleOptionViewItem opt = option; 0055 initStyleOption(&opt, index); 0056 0057 const QWidget* w = opt.widget; 0058 const QStyle* style = w ? w->style() : QApplication::style(); 0059 const Qt::LayoutDirection direction = w ? w->layoutDirection() : QApplication::layoutDirection(); 0060 0061 const QPalette::ColorRole colorRole = opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text; 0062 0063 QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; 0064 if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active)) { 0065 cg = QPalette::Inactive; 0066 } 0067 0068 #ifdef Q_OS_WIN 0069 opt.palette.setColor(QPalette::All, QPalette::HighlightedText, opt.palette.color(QPalette::Active, QPalette::Text)); 0070 opt.palette.setColor(QPalette::All, QPalette::Highlight, opt.palette.base().color().darker(108)); 0071 #endif 0072 0073 QPalette textPalette = opt.palette; 0074 textPalette.setCurrentColorGroup(cg); 0075 0076 int topPosition = opt.rect.top() + m_padding; 0077 0078 // Draw background 0079 opt.showDecorationSelected = true; 0080 style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, w); 0081 0082 // Draw icon 0083 QRect iconRect(opt.rect.left() + (opt.rect.width() - m_iconSize) / 2, topPosition, m_iconSize, m_iconSize); 0084 QRect visualIconRect = style->visualRect(direction, opt.rect, iconRect); 0085 QPixmap pixmap = index.data(Qt::DecorationRole).value<QIcon>().pixmap(m_iconSize); 0086 painter->drawPixmap(visualIconRect, pixmap); 0087 topPosition += m_iconSize + m_padding; 0088 0089 // Draw title 0090 const QString title = index.data(Qt::DisplayRole).toString(); 0091 const int leftTitleEdge = opt.rect.left() + m_padding; 0092 QRect titleRect(leftTitleEdge, topPosition, opt.rect.width() - 2 * m_padding, opt.fontMetrics.height()); 0093 QRect visualTitleRect = style->visualRect(direction, opt.rect, titleRect); 0094 style->drawItemText(painter, visualTitleRect, Qt::AlignCenter, textPalette, true, title, colorRole); 0095 } 0096 0097 QSize ListItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const 0098 { 0099 if (!m_itemHeight) { 0100 QStyleOptionViewItem opt(option); 0101 initStyleOption(&opt, index); 0102 0103 const QWidget* w = opt.widget; 0104 const QStyle* style = w ? w->style() : QApplication::style(); 0105 const int padding = style->pixelMetric(QStyle::PM_FocusFrameHMargin, nullptr) + 1; 0106 0107 m_padding = padding > 5 ? padding : 5; 0108 0109 m_itemHeight = 3 * m_padding + opt.fontMetrics.height() + m_iconSize; 0110 0111 // Update height of parent widget 0112 QWidget* p = qobject_cast<QWidget*>(parent()); 0113 if (p && m_updateParentHeight) { 0114 int frameWidth = p->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, nullptr, p); 0115 p->setFixedHeight(m_itemHeight + 2 * frameWidth); 0116 } 0117 } 0118 int width = 2 * m_padding + option.fontMetrics.horizontalAdvance(index.data(Qt::DisplayRole).toString()); 0119 width = width > (m_iconSize + 2 * m_padding) ? width : m_iconSize + 2 * m_padding; 0120 0121 if (m_uniformItemSizes) { 0122 if (width > m_itemWidth) { 0123 m_itemWidth = width; 0124 } 0125 else { 0126 width = m_itemWidth; 0127 } 0128 } 0129 0130 return QSize(width, m_itemHeight); 0131 }