void PlaylistItemDelegate::paintTrack(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { // get the data object const TrackPointer trackPointer = index.data(Playlist::DataObjectRole).value<TrackPointer>(); Track *track = trackPointer.data(); // const PlaylistModel* playlistModel = dynamic_cast<const PlaylistModel*>(index.model()); const bool isActive = index.data(Playlist::ActiveItemRole).toBool(); // const bool isHovered = index.data(Playlist::HoveredItemRole).toBool(); const bool isSelected = option.state & QStyle::State_Selected; if (isSelected) QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter); painter->save(); painter->translate(option.rect.topLeft()); QRect line(0, 0, option.rect.width(), option.rect.height()); // text color if (isSelected) painter->setPen(QPen(option.palette.brush(QPalette::HighlightedText), 0)); else painter->setPen(QPen(option.palette.brush(QPalette::Text), 0)); if (line.height() > ITEM_HEIGHT) { // qDebug() << "header at index" << index.row(); line.setHeight(ITEM_HEIGHT); paintAlbumHeader(painter, option, line, track); // now modify our rect and painter // to make them similar to "headerless" items line.moveBottom(ITEM_HEIGHT); painter->translate(0, ITEM_HEIGHT); } if (isActive) { if (!isSelected) paintActiveOverlay(painter, option, line); QFont boldFont = painter->font(); boldFont.setBold(true); painter->setFont(boldFont); // play icon painter->drawPixmap(PADDING*2, (ITEM_HEIGHT - 16) / 2, 16, 16, getPlayIcon()); } else { paintTrackNumber(painter, option, line, track); } paintTrackTitle(painter, option, line, track); paintTrackLength(painter, option, line, track); // separator painter->setPen(option.palette.color(QPalette::Midlight)); painter->drawLine(0, line.height()-1, line.width(), line.height()-1); painter->restore(); }
void PlaylistItemDelegate::paintBody(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { const bool isSelected = option.state & QStyle::State_Selected; if (isSelected) QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter); painter->save(); painter->translate(option.rect.topLeft()); QRect line(0, 0, option.rect.width(), option.rect.height()); if (downloadInfo) line.setWidth(line.width() / 2); const bool isActive = index.data(ActiveTrackRole).toBool(); // get the video metadata const Video *video = index.data(VideoRole).value<VideoPointer>().data(); // draw the "current track" highlight underneath the text if (isActive && !isSelected) paintActiveOverlay(painter, option, line); // thumb const QPixmap &thumb = video->getThumbnail(); if (!thumb.isNull()) { painter->drawPixmap(0, 0, thumb); if (video->getDuration() > 0) drawTime(painter, video->getFormattedDuration(), line); } const bool thumbsOnly = line.width() <= thumbWidth + 60; const bool isHovered = index.data(HoveredItemRole).toBool(); // play icon overlayed on the thumb bool needPlayIcon = isActive; if (thumbsOnly) needPlayIcon = needPlayIcon && !isHovered; if (needPlayIcon) painter->drawPixmap(0, 0, playIcon); if (!thumbsOnly) { // text color if (isSelected) painter->setPen(QPen(option.palette.highlightedText(), 0)); else painter->setPen(QPen(option.palette.text(), 0)); // title QStringRef title(&video->getTitle()); QString elidedTitle = video->getTitle(); static const int titleFlags = Qt::AlignTop | Qt::TextWordWrap; QRect textBox = line.adjusted(padding + thumbWidth, padding, -padding, 0); textBox = painter->boundingRect(textBox, titleFlags, elidedTitle); while (textBox.height() > 55 && elidedTitle.length() > 10) { #if QT_VERSION < QT_VERSION_CHECK(5, 6, 0) title = title.left(title.length() - 1); #elif QT_VERSION < QT_VERSION_CHECK(5, 8, 0) title.truncate(title.length() - 1); #else title.chop(1); #endif elidedTitle = title.trimmed() + QStringLiteral("…"); textBox = painter->boundingRect(textBox, titleFlags, elidedTitle); } painter->drawText(textBox, titleFlags, elidedTitle); painter->setFont(smallerFont); painter->setOpacity(.5); QFontMetrics fontMetrics = painter->fontMetrics(); static const int flags = Qt::AlignLeft | Qt::AlignTop; // published date const QString &published = video->getFormattedPublished(); QSize textSize(fontMetrics.size(Qt::TextSingleLine, published)); QPoint textPoint(padding + thumbWidth, padding * 2 + textBox.height()); textBox = QRect(textPoint, textSize); painter->drawText(textBox, flags, published); bool elided = false; // author if (!listView || listView->isClickableAuthors()) { bool authorHovered = isHovered && index.data(AuthorHoveredRole).toBool(); painter->save(); painter->setFont(smallerBoldFont); if (!isSelected) { if (authorHovered) painter->setPen(QPen(option.palette.brush(QPalette::Highlight), 0)); } const QString &author = video->getChannelTitle(); textPoint.setX(textBox.right() + padding); textSize = QSize(painter->fontMetrics().size(Qt::TextSingleLine, author)); textBox = QRect(textPoint, textSize); authorRects.insert(index.row(), textBox); if (textBox.right() > line.width() - padding) { textBox.setRight(line.width()); elided = drawElidedText(painter, textBox, flags, author); } else { painter->drawText(textBox, flags, author); } painter->restore(); } // view count if (video->getViewCount() > 0) { const QString &viewCount = video->getFormattedViewCount(); textPoint.setX(textBox.right() + padding); textSize = QSize(fontMetrics.size(Qt::TextSingleLine, viewCount)); if (elided || textPoint.x() + textSize.width() > line.width() - padding) { textPoint.setX(thumbWidth + padding); textPoint.setY(textPoint.y() + textSize.height() + padding); } textBox = QRect(textPoint, textSize); if (textBox.bottom() <= line.height()) { painter->drawText(textBox, flags, viewCount); } } if (downloadInfo) { const QString &def = VideoDefinition::forCode(video->getDefinitionCode()).getName(); textPoint.setX(textBox.right() + padding); textSize = QSize(fontMetrics.size(Qt::TextSingleLine, def)); textBox = QRect(textPoint, textSize); painter->drawText(textBox, flags, def); } } else { // thumbs only if (isHovered) { painter->setFont(smallerFont); painter->setPen(Qt::white); QStringRef title(&video->getTitle()); QString elidedTitle = video->getTitle(); static const int titleFlags = Qt::AlignTop | Qt::TextWordWrap; QRect textBox(padding, padding, thumbWidth - padding * 2, thumbHeight - padding * 2); textBox = painter->boundingRect(textBox, titleFlags, elidedTitle); while (textBox.height() > 55 && elidedTitle.length() > 10) { #if QT_VERSION < QT_VERSION_CHECK(5, 6, 0) title = title.left(title.length() - 1); #elif QT_VERSION < QT_VERSION_CHECK(5, 8, 0) title.truncate(title.length() - 1); #else title.chop(1); #endif elidedTitle = title.trimmed() + QStringLiteral("…"); textBox = painter->boundingRect(textBox, titleFlags, elidedTitle); } painter->fillRect(QRect(0, 0, thumbWidth, textBox.height() + padding * 2), QColor(0, 0, 0, 128)); painter->drawText(textBox, titleFlags, elidedTitle); } } painter->restore(); if (downloadInfo) paintDownloadInfo(painter, option, index); }
void PlaylistItemDelegate::paintBody( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const { painter->save(); painter->translate( option.rect.topLeft() ); QRect line(0, 0, option.rect.width(), option.rect.height()); if (downloadInfo) line.setWidth(line.width() / 2); const bool isActive = index.data( ActiveTrackRole ).toBool(); const bool isSelected = option.state & QStyle::State_Selected; // draw the "current track" highlight underneath the text if (isActive && !isSelected) paintActiveOverlay(painter, line); // get the video metadata const VideoPointer videoPointer = index.data( VideoRole ).value<VideoPointer>(); const Video *video = videoPointer.data(); // thumb painter->drawPixmap(0, 0, video->thumbnail()); // play icon overlayed on the thumb if (isActive) painter->drawPixmap(playIcon.rect(), playIcon); // time if (video->duration() > 0) drawTime(painter, video->formattedDuration(), line); // separator painter->setPen(option.palette.color(QPalette::Midlight)); painter->drawLine(THUMB_WIDTH, THUMB_HEIGHT, option.rect.width(), THUMB_HEIGHT); if (!video->thumbnail().isNull()) painter->setPen(Qt::black); painter->drawLine(0, THUMB_HEIGHT, THUMB_WIDTH-1, THUMB_HEIGHT); if (line.width() > THUMB_WIDTH + 60) { // if (isActive) painter->setFont(boldFont); // text color if (isSelected) painter->setPen(QPen(option.palette.highlightedText(), 0)); else painter->setPen(QPen(option.palette.text(), 0)); // title QString videoTitle = video->title(); QString v = videoTitle; const int flags = Qt::AlignTop | Qt::TextWordWrap; QRect textBox = line.adjusted(PADDING+THUMB_WIDTH, PADDING, 0, 0); textBox = painter->boundingRect(textBox, flags, v); while (textBox.height() > 55 && v.length() > 10) { videoTitle.truncate(videoTitle.length() - 1); v = videoTitle; v = v.trimmed().append("..."); textBox = painter->boundingRect(textBox, flags, v); } painter->drawText(textBox, flags, v); painter->setFont(smallerFont); // published date QString publishedString = video->published().date().toString(Qt::DefaultLocaleShortDate); QSize stringSize(QFontMetrics(painter->font()).size( Qt::TextSingleLine, publishedString ) ); QPoint textLoc(PADDING+THUMB_WIDTH, PADDING*2 + textBox.height()); QRect publishedTextBox(textLoc , stringSize); painter->drawText(publishedTextBox, Qt::AlignLeft | Qt::AlignTop, publishedString); if (line.width() > publishedTextBox.x() + publishedTextBox.width()*2) { // author bool authorHovered = false; bool authorPressed = false; const bool isHovered = index.data(HoveredItemRole).toBool(); if (isHovered) { authorHovered = index.data(AuthorHoveredRole).toBool(); authorPressed = index.data(AuthorPressedRole).toBool(); } painter->save(); painter->setFont(smallerBoldFont); if (!isSelected) { if (authorHovered) painter->setPen(QPen(option.palette.brush(QPalette::Highlight), 0)); else painter->setOpacity(.5); } QString authorString = video->channelTitle(); textLoc.setX(textLoc.x() + stringSize.width() + PADDING); stringSize = QSize(QFontMetrics(painter->font()).size( Qt::TextSingleLine, authorString ) ); QRect authorTextBox(textLoc , stringSize); authorRects.insert(index.row(), authorTextBox); painter->drawText(authorTextBox, Qt::AlignLeft | Qt::AlignTop, authorString); painter->restore(); if (line.width() > authorTextBox.x() + 50) { // view count if (video->viewCount() >= 0) { QLocale locale; QString viewCountString = tr("%1 views").arg(locale.toString(video->viewCount())); textLoc.setX(textLoc.x() + stringSize.width() + PADDING); stringSize = QSize(QFontMetrics(painter->font()).size( Qt::TextSingleLine, viewCountString ) ); QRect viewCountTextBox(textLoc , stringSize); painter->drawText(viewCountTextBox, Qt::AlignLeft | Qt::AlignBottom, viewCountString); } if (downloadInfo) { const QString definitionString = VideoDefinition::getDefinitionFor(video->getDefinitionCode()).getName(); textLoc.setX(textLoc.x() + stringSize.width() + PADDING); stringSize = QSize(QFontMetrics(painter->font()).size( Qt::TextSingleLine, definitionString ) ); QRect viewCountTextBox(textLoc , stringSize); painter->drawText(viewCountTextBox, Qt::AlignLeft | Qt::AlignBottom, definitionString); } } } } else { const bool isHovered = index.data(HoveredItemRole).toBool(); if (!isActive && isHovered) { painter->setFont(smallerFont); painter->setPen(Qt::white); QString videoTitle = video->title(); QString v = videoTitle; const int flags = Qt::AlignTop | Qt::TextWordWrap; QRect textBox(PADDING, PADDING, THUMB_WIDTH - PADDING*2, THUMB_HEIGHT - PADDING*2); textBox = painter->boundingRect(textBox, flags, v); while (textBox.height() > THUMB_HEIGHT && v.length() > 10) { videoTitle.truncate(videoTitle.length() - 1); v = videoTitle; v = v.trimmed().append("..."); textBox = painter->boundingRect(textBox, flags, v); } painter->fillRect(QRect(0, 0, THUMB_WIDTH, textBox.height() + PADDING*2), QColor(0, 0, 0, 128)); painter->drawText(textBox, flags, v); } } painter->restore(); if (downloadInfo) paintDownloadInfo(painter, option, index); }
void PrettyItemDelegate::paintBody( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const { painter->save(); painter->translate( option.rect.topLeft() ); QRectF line(0, 0, option.rect.width(), option.rect.height()); if (downloadInfo) line.setWidth(line.width() / 2); painter->setClipRect(line); const bool isActive = index.data( ActiveTrackRole ).toBool(); const bool isSelected = option.state & QStyle::State_Selected; // draw the "current track" highlight underneath the text if (isActive && !isSelected) { paintActiveOverlay(painter, line.x(), line.y(), line.width(), line.height()); } // get the video metadata const VideoPointer videoPointer = index.data( VideoRole ).value<VideoPointer>(); const Video *video = videoPointer.data(); // thumb if (!video->thumbnail().isNull()) { painter->drawImage(QRect(0, 0, THUMB_WIDTH, THUMB_HEIGHT), video->thumbnail()); // play icon overlayed on the thumb if (isActive) paintPlayIcon(painter); // time QString timeString; int duration = video->duration(); if ( duration > 3600 ) timeString = QTime().addSecs(duration).toString("h:mm:ss"); else timeString = QTime().addSecs(duration).toString("m:ss"); drawTime(painter, timeString, line); } if (isActive) painter->setFont(boldFont); // text color if (isSelected) painter->setPen(QPen(option.palette.brush(QPalette::HighlightedText), 0)); else painter->setPen(QPen(option.palette.brush(QPalette::Text), 0)); // title QString videoTitle = video->title(); QRectF textBox = line.adjusted(PADDING+THUMB_WIDTH, PADDING, -2 * PADDING, -PADDING); textBox = painter->boundingRect( textBox, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, videoTitle); painter->drawText(textBox, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, videoTitle); painter->setFont(smallerFont); // published date QString publishedString = video->published().date().toString(Qt::DefaultLocaleShortDate); QSizeF stringSize(QFontMetrics(painter->font()).size( Qt::TextSingleLine, publishedString ) ); QPointF textLoc(PADDING+THUMB_WIDTH, PADDING*2 + textBox.height()); QRectF publishedTextBox(textLoc , stringSize); painter->drawText(publishedTextBox, Qt::AlignLeft | Qt::AlignTop, publishedString); // author bool authorHovered = false; bool authorPressed = false; const bool isHovered = index.data(HoveredItemRole).toBool(); if (isHovered) { authorHovered = index.data(AuthorHoveredRole).toBool(); authorPressed = index.data(AuthorPressedRole).toBool(); } painter->save(); painter->setFont(smallerBoldFont); if (!isSelected) { if (authorHovered) painter->setPen(QPen(option.palette.brush(QPalette::Highlight), 0)); else painter->setPen(QPen(option.palette.brush(QPalette::Mid), 0)); } QString authorString = video->author(); textLoc.setX(textLoc.x() + stringSize.width() + PADDING); stringSize = QSizeF(QFontMetrics(painter->font()).size( Qt::TextSingleLine, authorString ) ); QRectF authorTextBox(textLoc , stringSize); authorRects.insert(index.row(), authorTextBox.toRect()); painter->drawText(authorTextBox, Qt::AlignLeft | Qt::AlignTop, authorString); painter->restore(); // view count if (video->viewCount() >= 0) { painter->save(); QLocale locale; QString viewCountString = tr("%1 views").arg(locale.toString(video->viewCount())); textLoc.setX(textLoc.x() + stringSize.width() + PADDING); stringSize = QSizeF(QFontMetrics(painter->font()).size( Qt::TextSingleLine, viewCountString ) ); QRectF viewCountTextBox(textLoc , stringSize); painter->drawText(viewCountTextBox, Qt::AlignLeft | Qt::AlignBottom, viewCountString); painter->restore(); } if (downloadInfo) { painter->save(); QString definitionString = VideoDefinition::getDefinitionName(video->getDefinitionCode()); textLoc.setX(textLoc.x() + stringSize.width() + PADDING); stringSize = QSizeF(QFontMetrics(painter->font()).size( Qt::TextSingleLine, definitionString ) ); QRectF viewCountTextBox(textLoc , stringSize); painter->drawText(viewCountTextBox, Qt::AlignLeft | Qt::AlignBottom, definitionString); painter->restore(); } /* QLinearGradient myGradient; QPen myPen; QFont myFont; QPointF baseline(authorTextBox.x(), authorTextBox.y() + authorTextBox.height()); QPainterPath myPath; myPath.addText(baseline, boldFont, authorString); painter->setBrush(palette.color(QPalette::WindowText)); painter->setPen(palette.color(QPalette::Dark)); painter->setRenderHints (QPainter::Antialiasing, true); painter->drawPath(myPath); */ // separator painter->setClipping(false); painter->setPen(option.palette.color(QPalette::Midlight)); painter->drawLine(THUMB_WIDTH, THUMB_HEIGHT, option.rect.width(), THUMB_HEIGHT); if (!video->thumbnail().isNull()) painter->setPen(Qt::black); painter->drawLine(0, THUMB_HEIGHT, THUMB_WIDTH-1, THUMB_HEIGHT); painter->restore(); if (downloadInfo) paintDownloadInfo(painter, option, index); }