#include "icon_view_delegate.h" #include #include #include #include #include namespace LtsDataView { static constexpr int s_shadowRadius = 22; void IconViewDelegate::setDisplayWidgetCreator(const std::function &customDisplayWidgetCreator) { m_customDisplayWidgetCreator = customDisplayWidgetCreator; QScopedPointer dw(m_customDisplayWidgetCreator()); if (!dw) { qWarning() << "IconViewDelegate::setDisplayWidgetCreator: delegate is not a base of AbstractDisplayWidget!"; Q_ASSERT(false); return; } m_displayWidgetSize = dw->size() + QSize(s_shadowRadius * 2, s_shadowRadius * 2); } QSize IconViewDelegate::sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const { return m_displayWidgetSize; } void IconViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QScopedPointer dw(m_customDisplayWidgetCreator()); if (!dw) { qWarning() << "IconViewDelegate::paint: delegate is not a base of AbstractDisplayWidget!"; Q_ASSERT(false); return; } if (!dw->init(index)) { qWarning() << "IconViewDelegate::paint: delegate could not create ui"; return; } const auto dpr = dw->devicePixelRatioF(); QPixmap p(dw->size() * dpr); p.setDevicePixelRatio(dpr); QPainter myPainter(&p); dw->render(&myPainter); myPainter.end(); // drop shadow QGraphicsDropShadowEffect *shadowEffect = new QGraphicsDropShadowEffect(); shadowEffect->setBlurRadius(s_shadowRadius); shadowEffect->setOffset(0, 0); // center (shadow on all sides) if (option.state & QStyle::State_Selected) shadowEffect->setColor(dw->palette().light().color()); else shadowEffect->setColor(dw->palette().shadow().color()); // draw pixmap & shadow QGraphicsPixmapItem *item = new QGraphicsPixmapItem(p); item->setGraphicsEffect(shadowEffect); // TODO: avoid creating a QGraphicsScene by using QGraphicsItem::paint() QGraphicsScene scene; scene.addItem(item); scene.render(painter, option.rect, QRectF(-s_shadowRadius, -s_shadowRadius, option.rect.width(), option.rect.height())); } } // namespace LtsDataView