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 }