git repos / SagoImageBrowser

blame: src/thumbnaildelegate.cpp

normal view · raw

14cf904f Poul Sander 2026-06-22 18:18 1
/*
14cf904f Poul Sander 2026-06-22 18:18 2
MIT License
14cf904f Poul Sander 2026-06-22 18:18 3
14cf904f Poul Sander 2026-06-22 18:18 4
Copyright (c) 2026 Poul Sander
14cf904f Poul Sander 2026-06-22 18:18 5
14cf904f Poul Sander 2026-06-22 18:18 6
Permission is hereby granted, free of charge, to any person obtaining a copy
14cf904f Poul Sander 2026-06-22 18:18 7
of this software and associated documentation files (the "Software"), to deal
14cf904f Poul Sander 2026-06-22 18:18 8
in the Software without restriction, including without limitation the rights
14cf904f Poul Sander 2026-06-22 18:18 9
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14cf904f Poul Sander 2026-06-22 18:18 10
copies of the Software, and to permit persons to whom the Software is
14cf904f Poul Sander 2026-06-22 18:18 11
furnished to do so, subject to the following conditions:
14cf904f Poul Sander 2026-06-22 18:18 12
14cf904f Poul Sander 2026-06-22 18:18 13
The above copyright notice and this permission notice shall be included in all
14cf904f Poul Sander 2026-06-22 18:18 14
copies or substantial portions of the Software.
14cf904f Poul Sander 2026-06-22 18:18 15
14cf904f Poul Sander 2026-06-22 18:18 16
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14cf904f Poul Sander 2026-06-22 18:18 17
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14cf904f Poul Sander 2026-06-22 18:18 18
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14cf904f Poul Sander 2026-06-22 18:18 19
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14cf904f Poul Sander 2026-06-22 18:18 20
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
14cf904f Poul Sander 2026-06-22 18:18 21
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
14cf904f Poul Sander 2026-06-22 18:18 22
SOFTWARE.
14cf904f Poul Sander 2026-06-22 18:18 23
14cf904f Poul Sander 2026-06-22 18:18 24
*/
14cf904f Poul Sander 2026-06-22 18:18 25
1dcea855 Poul Sander 2026-05-26 21:48 26
#include "thumbnaildelegate.h"
1dcea855 Poul Sander 2026-05-26 21:48 27
1dcea855 Poul Sander 2026-05-26 21:48 28
#include <QPainter>
1dcea855 Poul Sander 2026-05-26 21:48 29
#include <QApplication>
1dcea855 Poul Sander 2026-05-26 21:48 30
#include <QStyle>
1dcea855 Poul Sander 2026-05-26 21:48 31
#include <QTextOption>
1dcea855 Poul Sander 2026-05-26 21:48 32
#include <QFontMetrics>
1dcea855 Poul Sander 2026-05-26 21:48 33
1dcea855 Poul Sander 2026-05-26 21:48 34
ThumbnailDelegate::ThumbnailDelegate(QObject *parent)
1dcea855 Poul Sander 2026-05-26 21:48 35
    : QStyledItemDelegate(parent)
1dcea855 Poul Sander 2026-05-26 21:48 36
{
1dcea855 Poul Sander 2026-05-26 21:48 37
}
1dcea855 Poul Sander 2026-05-26 21:48 38
1dcea855 Poul Sander 2026-05-26 21:48 39
void ThumbnailDelegate::paint(QPainter *painter,
1dcea855 Poul Sander 2026-05-26 21:48 40
                              const QStyleOptionViewItem &option,
1dcea855 Poul Sander 2026-05-26 21:48 41
                              const QModelIndex &index) const
1dcea855 Poul Sander 2026-05-26 21:48 42
{
1dcea855 Poul Sander 2026-05-26 21:48 43
    painter->save();
1dcea855 Poul Sander 2026-05-26 21:48 44
1dcea855 Poul Sander 2026-05-26 21:48 45
    // Folder items use the default delegate rendering unchanged
1dcea855 Poul Sander 2026-05-26 21:48 46
    if (index.data(Qt::UserRole).toBool()) {
1dcea855 Poul Sander 2026-05-26 21:48 47
        painter->restore();
1dcea855 Poul Sander 2026-05-26 21:48 48
        QStyledItemDelegate::paint(painter, option, index);
1dcea855 Poul Sander 2026-05-26 21:48 49
        return;
1dcea855 Poul Sander 2026-05-26 21:48 50
    }
1dcea855 Poul Sander 2026-05-26 21:48 51
1dcea855 Poul Sander 2026-05-26 21:48 52
    // Draw selection / hover background
1dcea855 Poul Sander 2026-05-26 21:48 53
    QStyle *style = option.widget ? option.widget->style() : QApplication::style();
1dcea855 Poul Sander 2026-05-26 21:48 54
    QStyleOptionViewItem bgOption = option;
1dcea855 Poul Sander 2026-05-26 21:48 55
    bgOption.showDecorationSelected = true;
1dcea855 Poul Sander 2026-05-26 21:48 56
    style->drawPrimitive(QStyle::PE_PanelItemViewItem, &bgOption, painter, option.widget);
1dcea855 Poul Sander 2026-05-26 21:48 57
1dcea855 Poul Sander 2026-05-26 21:48 58
    const QRect cellRect = option.rect;
1dcea855 Poul Sander 2026-05-26 21:48 59
1dcea855 Poul Sander 2026-05-26 21:48 60
    // Fixed icon zone: top IconZoneHeight pixels of the cell
1dcea855 Poul Sander 2026-05-26 21:48 61
    const QRect iconZone(cellRect.left(), cellRect.top(),
1dcea855 Poul Sander 2026-05-26 21:48 62
                         cellRect.width(), IconZoneHeight);
1dcea855 Poul Sander 2026-05-26 21:48 63
1dcea855 Poul Sander 2026-05-26 21:48 64
    // Fixed text zone: everything below the icon zone
1dcea855 Poul Sander 2026-05-26 21:48 65
    const QRect textZone(cellRect.left(), cellRect.top() + IconZoneHeight,
1dcea855 Poul Sander 2026-05-26 21:48 66
                         cellRect.width(), cellRect.height() - IconZoneHeight);
1dcea855 Poul Sander 2026-05-26 21:48 67
1dcea855 Poul Sander 2026-05-26 21:48 68
    // --- Draw icon centered within the icon zone ---
1dcea855 Poul Sander 2026-05-26 21:48 69
    const QVariant decorData = index.data(Qt::DecorationRole);
1dcea855 Poul Sander 2026-05-26 21:48 70
    QPixmap pixmap;
1dcea855 Poul Sander 2026-05-26 21:48 71
    if (decorData.userType() == QMetaType::QPixmap) {
1dcea855 Poul Sander 2026-05-26 21:48 72
        pixmap = qvariant_cast<QPixmap>(decorData);
1dcea855 Poul Sander 2026-05-26 21:48 73
    } else if (decorData.userType() == QMetaType::QIcon) {
1dcea855 Poul Sander 2026-05-26 21:48 74
        pixmap = qvariant_cast<QIcon>(decorData).pixmap(option.decorationSize);
1dcea855 Poul Sander 2026-05-26 21:48 75
    }
1dcea855 Poul Sander 2026-05-26 21:48 76
    if (!pixmap.isNull()) {
1dcea855 Poul Sander 2026-05-26 21:48 77
        // Center the pixmap in the icon zone
1dcea855 Poul Sander 2026-05-26 21:48 78
        const int x = iconZone.left() + (iconZone.width()  - pixmap.width())  / 2;
1dcea855 Poul Sander 2026-05-26 21:48 79
        const int y = iconZone.top()  + (iconZone.height() - pixmap.height()) / 2;
1dcea855 Poul Sander 2026-05-26 21:48 80
        painter->drawPixmap(x, y, pixmap);
1dcea855 Poul Sander 2026-05-26 21:48 81
    }
1dcea855 Poul Sander 2026-05-26 21:48 82
1dcea855 Poul Sander 2026-05-26 21:48 83
    // --- Draw text top-aligned within the text zone ---
1dcea855 Poul Sander 2026-05-26 21:48 84
    const QString text = index.data(Qt::DisplayRole).toString();
1dcea855 Poul Sander 2026-05-26 21:48 85
    if (!text.isEmpty()) {
1dcea855 Poul Sander 2026-05-26 21:48 86
        QColor textColor = option.palette.color(
1dcea855 Poul Sander 2026-05-26 21:48 87
            (option.state & QStyle::State_Selected) ? QPalette::HighlightedText
1dcea855 Poul Sander 2026-05-26 21:48 88
                                                    : QPalette::Text);
1dcea855 Poul Sander 2026-05-26 21:48 89
        painter->setPen(textColor);
1dcea855 Poul Sander 2026-05-26 21:48 90
        painter->setFont(option.font);
1dcea855 Poul Sander 2026-05-26 21:48 91
1dcea855 Poul Sander 2026-05-26 21:48 92
        QTextOption textOpt;
1dcea855 Poul Sander 2026-05-26 21:48 93
        textOpt.setAlignment(Qt::AlignTop | Qt::AlignHCenter);
1dcea855 Poul Sander 2026-05-26 21:48 94
        textOpt.setWrapMode(QTextOption::WordWrap);
1dcea855 Poul Sander 2026-05-26 21:48 95
1dcea855 Poul Sander 2026-05-26 21:48 96
        // Elide text that would overflow the text zone
1dcea855 Poul Sander 2026-05-26 21:48 97
        const QFontMetrics fm(option.font);
1dcea855 Poul Sander 2026-05-26 21:48 98
        const QString elidedText = fm.elidedText(
1dcea855 Poul Sander 2026-05-26 21:48 99
            text, option.textElideMode, textZone.width() * 2);
1dcea855 Poul Sander 2026-05-26 21:48 100
1dcea855 Poul Sander 2026-05-26 21:48 101
        painter->drawText(QRectF(textZone), elidedText, textOpt);
1dcea855 Poul Sander 2026-05-26 21:48 102
    }
1dcea855 Poul Sander 2026-05-26 21:48 103
1dcea855 Poul Sander 2026-05-26 21:48 104
    painter->restore();
1dcea855 Poul Sander 2026-05-26 21:48 105
}
1dcea855 Poul Sander 2026-05-26 21:48 106
1dcea855 Poul Sander 2026-05-26 21:48 107
QSize ThumbnailDelegate::sizeHint(const QStyleOptionViewItem &option,
1dcea855 Poul Sander 2026-05-26 21:48 108
                                  const QModelIndex &index) const
1dcea855 Poul Sander 2026-05-26 21:48 109
{
1dcea855 Poul Sander 2026-05-26 21:48 110
    Q_UNUSED(option)
1dcea855 Poul Sander 2026-05-26 21:48 111
    Q_UNUSED(index)
1dcea855 Poul Sander 2026-05-26 21:48 112
    // Return the grid size set on the view (148×168)
1dcea855 Poul Sander 2026-05-26 21:48 113
    return option.rect.size().isValid() ? option.rect.size()
1dcea855 Poul Sander 2026-05-26 21:48 114
                                        : QStyledItemDelegate::sizeHint(option, index);
1dcea855 Poul Sander 2026-05-26 21:48 115
}
1970-01-01 00:00 116