#include "playlistmodel.h"
#include "fontutils.h"
#include "downloaditem.h"
-#include "utils.h"
+#include "iconutils.h"
#include "videodefinition.h"
#include "video.h"
+#include "datautils.h"
const int PlaylistItemDelegate::THUMB_HEIGHT = 90;
const int PlaylistItemDelegate::THUMB_WIDTH = 160;
const int PlaylistItemDelegate::PADDING = 10;
+namespace {
+
+void drawElidedText(QPainter *painter, const QRect &textBox, const int flags, const QString &text) {
+ QString elidedText = QFontMetrics(painter->font()).elidedText(text, Qt::ElideRight, textBox.width(), flags);
+ painter->drawText(textBox, 0, elidedText);
+}
+
+}
+
PlaylistItemDelegate::PlaylistItemDelegate(QObject* parent, bool downloadInfo)
: QStyledItemDelegate(parent),
downloadInfo(downloadInfo),
}
void PlaylistItemDelegate::createPlayIcon() {
- playIcon = QPixmap(THUMB_WIDTH, THUMB_HEIGHT);
+ qreal maxRatio = IconUtils::maxSupportedPixelRatio();
+ playIcon = QPixmap(THUMB_WIDTH * maxRatio, THUMB_HEIGHT * maxRatio);
+ playIcon.setDevicePixelRatio(maxRatio);
playIcon.fill(Qt::transparent);
- QPixmap tempPixmap(THUMB_WIDTH, THUMB_HEIGHT);
+ QPixmap tempPixmap(THUMB_WIDTH * maxRatio, THUMB_HEIGHT * maxRatio);
+ tempPixmap.setDevicePixelRatio(maxRatio);
tempPixmap.fill(Qt::transparent);
QPainter painter(&tempPixmap);
painter.setRenderHints(QPainter::Antialiasing, true);
const bool isActive = index.data( ActiveTrackRole ).toBool();
const bool isSelected = option.state & QStyle::State_Selected;
+ // 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, line);
+ paintActiveOverlay(painter, option, line);
- // get the video metadata
- const VideoPointer videoPointer = index.data( VideoRole ).value<VideoPointer>();
- const Video *video = videoPointer.data();
+ // 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);
// thumb
painter->drawPixmap(0, 0, video->thumbnail());
// play icon overlayed on the thumb
if (isActive)
- painter->drawPixmap(playIcon.rect(), playIcon);
+ painter->drawPixmap(0, 0, playIcon);
// time
- 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 (video->duration() > 0)
+ drawTime(painter, video->formattedDuration(), line);
if (line.width() > THUMB_WIDTH + 60) {
- if (isActive) painter->setFont(boldFont);
+ // if (isActive) painter->setFont(boldFont);
// text color
if (isSelected)
- painter->setPen(QPen(option.palette.brush(QPalette::HighlightedText), 0));
+ painter->setPen(QPen(option.palette.highlightedText(), 0));
else
- painter->setPen(QPen(option.palette.brush(QPalette::Text), 0));
+ painter->setPen(QPen(option.palette.text(), 0));
// title
QString videoTitle = video->title();
painter->setFont(smallerFont);
// published date
- QString publishedString = video->published().date().toString(Qt::DefaultLocaleShortDate);
+ QString publishedString = DataUtils::formatDateTime(video->published());
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();
+ }
- // 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);
+ }
+ const 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);
+ if (authorTextBox.right() > line.width()) authorTextBox.setRight(line.width());
+ drawElidedText(painter, authorTextBox, Qt::AlignLeft | Qt::AlignTop, authorString);
+ painter->restore();
- 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();
+ // 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, 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) {
- QString definitionString = VideoDefinition::getDefinitionName(video->getDefinitionCode());
- 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);
- }
-
- }
+ stringSize = QSize(QFontMetrics(painter->font()).size( Qt::TextSingleLine, viewCountString ) );
+ QRect viewCountTextBox(textLoc , stringSize);
+ if (viewCountTextBox.right() > line.width()) viewCountTextBox.setRight(line.width());
+ drawElidedText(painter, 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 {
- bool isHovered = option.state & QStyle::State_MouseOver;
+ const bool isHovered = index.data(HoveredItemRole).toBool();
if (!isActive && isHovered) {
painter->setFont(smallerFont);
painter->setPen(Qt::white);
}
-void PlaylistItemDelegate::paintActiveOverlay(QPainter *painter, const QRect &line) const {
- static QLinearGradient linearGradient;
- static bool initialized = false;
-
- if (!initialized) {
- QPalette palette;
- QColor highlightColor = palette.color(QPalette::Highlight);
- QColor backgroundColor = palette.color(QPalette::Base);
- const float animation = 0.4;
- const int gradientRange = 16;
-
- QColor color2 = QColor::fromHsv(
- highlightColor.hue(),
- (int) (backgroundColor.saturation() * (1.0f - animation) + highlightColor.saturation() * animation),
- (int) (backgroundColor.value() * (1.0f - animation) + highlightColor.value() * animation)
- );
- QColor color1 = QColor::fromHsv(
- color2.hue(),
- qMax(color2.saturation() - gradientRange, 0),
- qMin(color2.value() + gradientRange, 255)
- );
-
- linearGradient = QLinearGradient(0, 0, 0, THUMB_HEIGHT);
- linearGradient.setColorAt(0.0, color1);
- linearGradient.setColorAt(1.0, color2);
- initialized = true;
- }
-
- painter->fillRect(line, linearGradient);
+void PlaylistItemDelegate::paintActiveOverlay(QPainter *painter, const QStyleOptionViewItem& option, const QRect &line) const {
+ painter->save();
+ painter->setOpacity(.1);
+ painter->fillRect(line, option.palette.highlight());
+ painter->restore();
}
void PlaylistItemDelegate::drawTime(QPainter *painter, const QString &time, const QRect &line) const {
if (status != Finished && status != Failed && status != Idle) {
if (downloadButtonHovered) message = tr("Stop downloading");
painter->save();
- QIcon closeIcon = Utils::icon("window-close");
+ QIcon closeIcon = IconUtils::icon("window-close");
painter->drawPixmap(downloadButtonRect(line), closeIcon.pixmap(16, 16, iconMode));
painter->restore();
}
message = tr("Open parent folder");
#endif
painter->save();
- QIcon searchIcon = Utils::icon("system-search");
+ QIcon searchIcon = IconUtils::icon("system-search");
painter->drawPixmap(downloadButtonRect(line), searchIcon.pixmap(16, 16, iconMode));
painter->restore();
}
else if (status == Failed || status == Idle) {
if (downloadButtonHovered) message = tr("Restart downloading");
painter->save();
- QIcon searchIcon = Utils::icon("view-refresh");
+ QIcon searchIcon = IconUtils::icon("view-refresh");
painter->drawPixmap(downloadButtonRect(line), searchIcon.pixmap(16, 16, iconMode));
painter->restore();
}