From: Flavio Tordini Date: Fri, 11 Sep 2015 12:40:44 +0000 (+0200) Subject: HiDPI support X-Git-Tag: 2.5~18 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=dfb52494c10b0cb7cb56eac88bb194bb6fb96418;p=minitube HiDPI support --- diff --git a/images/app@2x.png b/images/app@2x.png new file mode 100644 index 0000000..38c2c30 Binary files /dev/null and b/images/app@2x.png differ diff --git a/images/badge3@2x.png b/images/badge3@2x.png new file mode 100644 index 0000000..f516a47 Binary files /dev/null and b/images/badge3@2x.png differ diff --git a/images/badge4@2x.png b/images/badge4@2x.png new file mode 100644 index 0000000..4511b45 Binary files /dev/null and b/images/badge4@2x.png differ diff --git a/images/badge@2x.png b/images/badge@2x.png new file mode 100644 index 0000000..2ae172e Binary files /dev/null and b/images/badge@2x.png differ diff --git a/images/channels@2x.png b/images/channels@2x.png new file mode 100644 index 0000000..abba86b Binary files /dev/null and b/images/channels@2x.png differ diff --git a/images/mark-watched@2x.png b/images/mark-watched@2x.png new file mode 100644 index 0000000..73f8fb4 Binary files /dev/null and b/images/mark-watched@2x.png differ diff --git a/images/refine-search.png b/images/refine-search.png index ea2cd3e..dd977aa 100644 Binary files a/images/refine-search.png and b/images/refine-search.png differ diff --git a/images/refine-search@2x.png b/images/refine-search@2x.png new file mode 100644 index 0000000..37340a5 Binary files /dev/null and b/images/refine-search@2x.png differ diff --git a/images/search-duration@2x.png b/images/search-duration@2x.png new file mode 100644 index 0000000..daef48d Binary files /dev/null and b/images/search-duration@2x.png differ diff --git a/images/search-quality@2x.png b/images/search-quality@2x.png new file mode 100644 index 0000000..3035153 Binary files /dev/null and b/images/search-quality@2x.png differ diff --git a/images/search-sortBy@2x.png b/images/search-sortBy@2x.png new file mode 100644 index 0000000..235200c Binary files /dev/null and b/images/search-sortBy@2x.png differ diff --git a/images/search-time@2x.png b/images/search-time@2x.png new file mode 100644 index 0000000..aeaaa21 Binary files /dev/null and b/images/search-time@2x.png differ diff --git a/images/show-updated.png b/images/show-updated.png index 732c556..9af84f2 100644 Binary files a/images/show-updated.png and b/images/show-updated.png differ diff --git a/images/show-updated@2x.png b/images/show-updated@2x.png new file mode 100644 index 0000000..7f0b807 Binary files /dev/null and b/images/show-updated@2x.png differ diff --git a/images/sort@2x.png b/images/sort@2x.png new file mode 100644 index 0000000..7475325 Binary files /dev/null and b/images/sort@2x.png differ diff --git a/images/unwatched@2x.png b/images/unwatched@2x.png new file mode 100644 index 0000000..573c25e Binary files /dev/null and b/images/unwatched@2x.png differ diff --git a/images/worldwide@2x.png b/images/worldwide@2x.png new file mode 100644 index 0000000..2393b38 Binary files /dev/null and b/images/worldwide@2x.png differ diff --git a/resources.qrc b/resources.qrc index 6353887..d41ca8a 100644 --- a/resources.qrc +++ b/resources.qrc @@ -64,5 +64,20 @@ images/badge3.png images/badge4.png sounds/snapshot.wav + images/app@2x.png + images/sort@2x.png + images/unwatched@2x.png + images/badge@2x.png + images/badge3@2x.png + images/channels@2x.png + images/mark-watched@2x.png + images/show-updated@2x.png + images/worldwide@2x.png + images/badge4@2x.png + images/refine-search@2x.png + images/search-duration@2x.png + images/search-quality@2x.png + images/search-time@2x.png + images/search-sortBy@2x.png diff --git a/src/aboutview.cpp b/src/aboutview.cpp index 8548e86..19c5ee5 100644 --- a/src/aboutview.cpp +++ b/src/aboutview.cpp @@ -31,6 +31,7 @@ $END_LICENSE */ #include "mac_startup.h" #endif #include "fontutils.h" +#include "iconutils.h" AboutView::AboutView(QWidget *parent) : View(parent) { @@ -40,7 +41,7 @@ AboutView::AboutView(QWidget *parent) : View(parent) { hLayout->setSpacing(30); QLabel *logo = new QLabel(this); - logo->setPixmap(QPixmap(":/images/app.png")); + logo->setPixmap(IconUtils::pixmap(":/images/app.png")); hLayout->addWidget(logo, 0, Qt::AlignTop); QBoxLayout *layout = new QVBoxLayout(); diff --git a/src/channelitemdelegate.cpp b/src/channelitemdelegate.cpp index 4c13dfe..16f3a53 100644 --- a/src/channelitemdelegate.cpp +++ b/src/channelitemdelegate.cpp @@ -24,6 +24,7 @@ $END_LICENSE */ #include "fontutils.h" #include "channelaggregator.h" #include "painterutils.h" +#include "iconutils.h" static const int ITEM_WIDTH = 128; static const int ITEM_HEIGHT = 128; @@ -62,7 +63,7 @@ void ChannelItemDelegate::paintAggregate(QPainter* painter, painter->translate(option.rect.topLeft()); const QRect line(0, 0, option.rect.width(), option.rect.height()); - static const QPixmap thumbnail = QPixmap(":/images/channels.png"); + static const QPixmap thumbnail = IconUtils::pixmap(":/images/channels.png"); QString name = tr("All Videos"); @@ -80,7 +81,7 @@ void ChannelItemDelegate::paintUnwatched(QPainter* painter, painter->translate(option.rect.topLeft()); const QRect line(0, 0, option.rect.width(), option.rect.height()); - static const QPixmap thumbnail = QPixmap(":/images/unwatched.png"); + static const QPixmap thumbnail = IconUtils::pixmap(":/images/unwatched.png"); QString name = tr("Unwatched Videos"); diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index 2a7ac2e..9375bb0 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -32,6 +32,7 @@ $END_LICENSE */ #endif #include "datautils.h" #include "compatibility/pathsservice.h" +#include "iconutils.h" static DownloadManager *downloadManagerInstance = 0; @@ -73,7 +74,7 @@ void DownloadManager::addItem(Video *video) { if (!Activation::instance().isActivated()) { if (video->duration() >= 60*4) { QMessageBox msgBox(MainWindow::instance()); - msgBox.setIconPixmap(QPixmap(":/images/app.png").scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation)); + msgBox.setIconPixmap(IconUtils::pixmap(":/images/app.png").scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation)); msgBox.setText(tr("This is just the demo version of %1.").arg(Constants::NAME)); msgBox.setInformativeText( tr("It can only download videos shorter than %1 minutes so you can test the download functionality.") diff --git a/src/iconutils.cpp b/src/iconutils.cpp index 6b0f61e..b975411 100644 --- a/src/iconutils.cpp +++ b/src/iconutils.cpp @@ -33,9 +33,9 @@ QIcon IconUtils::fromTheme(const QString &name) { QIcon IconUtils::fromResources(const QString &name) { QIcon icon = QIcon(QString(":/images/%1.png").arg(name)); if (!icon.isNull()) { - icon.addPixmap(QString(":/images/%1_active.png").arg(name), QIcon::Active); - icon.addPixmap(QString(":/images/%1_selected.png").arg(name), QIcon::Selected); - icon.addPixmap(QString(":/images/%1_disabled.png").arg(name), QIcon::Disabled); + icon.addPixmap(IconUtils::pixmap(QString(":/images/%1_active.png").arg(name)), QIcon::Active); + icon.addPixmap(IconUtils::pixmap(QString(":/images/%1_selected.png").arg(name)), QIcon::Selected); + icon.addPixmap(IconUtils::pixmap(QString(":/images/%1_disabled.png").arg(name)), QIcon::Disabled); } return icon; } @@ -110,3 +110,19 @@ void IconUtils::setupAction(QAction *action) { action->shortcut().toString(QKeySequence::NativeText) + ")"); } + +QPixmap IconUtils::pixmap(const QString &name) { + // Check if a "@2x" file exists + QString fileName = name; + if (qApp->devicePixelRatio() > 1.0) { + int dotIndex = fileName.lastIndexOf(QLatin1Char('.')); + if (dotIndex != -1) { + QString at2xfileName = fileName; + at2xfileName.insert(dotIndex, QStringLiteral("@2x")); + if (QFile::exists(at2xfileName)) + fileName = at2xfileName; + } + } + + return QPixmap(fileName); +} diff --git a/src/iconutils.h b/src/iconutils.h index 398fc4c..8518412 100644 --- a/src/iconutils.h +++ b/src/iconutils.h @@ -35,6 +35,10 @@ public: static QIcon tintedIcon(const QString &name, const QColor &color, const QSize &size); static void setupAction(QAction *action); + // HiDPI stuff + static QPixmap pixmap(const QString &name); + static qreal maxSupportedPixelRatio() { return 2.0; } + private: IconUtils() { } static QImage grayscaled(const QImage &image); diff --git a/src/main.cpp b/src/main.cpp index 6515067..ea695ec 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -64,7 +64,7 @@ int main(int argc, char **argv) { #ifdef Q_OS_MAC mac::MacMain(); - QFont::insertSubstitution(".Helvetica Neue DeskInterface", "Helvetica Neue"); + // QFont::insertSubstitution(".Helvetica Neue DeskInterface", "Helvetica Neue"); #endif QtSingleApplication app(argc, argv); @@ -81,9 +81,8 @@ int main(int argc, char **argv) { app.setOrganizationDomain(Constants::ORG_DOMAIN); app.setApplicationVersion(Constants::VERSION); app.setAttribute(Qt::AA_DontShowIconsInMenus); -#ifndef APP_WIN app.setWheelScrollLines(1); -#endif + app.setAttribute(Qt::AA_UseHighDpiPixmaps); #ifdef APP_EXTRA Extra::appSetup(&app); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 5a50548..aba8d47 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -992,6 +992,8 @@ void MainWindow::showWidget(QWidget* widget, bool transition) { else title += QLatin1String(" - ") + Constants::NAME; setWindowTitle(title); + statusToolBar->setUpdatesEnabled(false); + // dynamic view actions foreach (QAction* action, viewActions) showActionInStatusBar(action, false); @@ -1004,6 +1006,8 @@ void MainWindow::showWidget(QWidget* widget, bool transition) { adjustStatusBarVisibility(); messageLabel->hide(); + statusToolBar->setUpdatesEnabled(true); + /* QString desc = metadata.value("description").toString(); if (!desc.isEmpty()) showMessage(desc); @@ -1081,7 +1085,7 @@ void MainWindow::showEvent(QShowEvent *e) { bool MainWindow::confirmQuit() { if (DownloadManager::instance()->activeItems() > 0) { QMessageBox msgBox(this); - msgBox.setIconPixmap(QPixmap(":/images/app.png").scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation)); + msgBox.setIconPixmap(IconUtils::pixmap(":/images/app.png").scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation)); msgBox.setText(tr("Do you want to exit %1 with a download in progress?").arg(Constants::NAME)); msgBox.setInformativeText(tr("If you close %1 now, this download will be cancelled.").arg(Constants::NAME)); msgBox.setModal(true); @@ -1187,7 +1191,6 @@ void MainWindow::resizeEvent(QResizeEvent *e) { #ifdef APP_MAC if (initialized && mac::CanGoFullScreen(winId())) { bool isFullscreen = mac::IsFullScreen(winId()); - qDebug() << __PRETTY_FUNCTION__ << isFullscreen << fullscreenFlag; if (isFullscreen != fullscreenFlag) { if (compactViewAct->isChecked()) { compactViewAct->setChecked(false); @@ -1725,7 +1728,7 @@ void MainWindow::gotNewVersion(const QString &version) { void MainWindow::simpleUpdateDialog(const QString &version) { QMessageBox msgBox(this); msgBox.setIconPixmap( - QPixmap(":/images/app.png") + IconUtils::pixmap(":/images/app.png") .scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation)); msgBox.setText(tr("%1 version %2 is now available.").arg(Constants::NAME, version)); msgBox.setModal(true); diff --git a/src/mediaview.cpp b/src/mediaview.cpp index 7100009..0744321 100644 --- a/src/mediaview.cpp +++ b/src/mediaview.cpp @@ -400,6 +400,8 @@ void MediaView::stop() { QSlider *slider = MainWindow::instance()->getSlider(); slider->setEnabled(false); slider->setValue(0); +#else + Phonon::SeekSlider *slider = MainWindow::instance()->getSeekSlider(); #endif if (snapshotSettings) { @@ -796,7 +798,7 @@ void MediaView::demoMessage() { #endif QMessageBox msgBox(this); - msgBox.setIconPixmap(QPixmap(":/images/app.png").scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation)); + msgBox.setIconPixmap(IconUtils::pixmap(":/images/app.png").scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation)); msgBox.setText(tr("This is just the demo version of %1.").arg(Constants::NAME)); msgBox.setInformativeText(tr("It allows you to test the application and see if it works for you.")); msgBox.setModal(true); diff --git a/src/painterutils.cpp b/src/painterutils.cpp index 7e3be42..9281b0d 100644 --- a/src/painterutils.cpp +++ b/src/painterutils.cpp @@ -20,6 +20,7 @@ $END_LICENSE */ #include "painterutils.h" #include "fontutils.h" +#include "iconutils.h" PainterUtils::PainterUtils() { } @@ -63,10 +64,9 @@ void PainterUtils::topShadow(QWidget *widget) { } void PainterUtils::paintBadge(QPainter *painter, const QString &text, bool center) { - static const QPixmap badge1 = QPixmap(":/images/badge.png"); - static const QPixmap badge3 = QPixmap(":/images/badge3.png"); - static const QPixmap badge4 = QPixmap(":/images/badge4.png"); - static const int size = badge1.height(); + const QPixmap badge1 = IconUtils::pixmap(":/images/badge.png"); + const QPixmap badge3 = IconUtils::pixmap(":/images/badge3.png"); + const QPixmap badge4 = IconUtils::pixmap(":/images/badge4.png"); const int textSize = text.size(); @@ -75,10 +75,13 @@ void PainterUtils::paintBadge(QPainter *painter, const QString &text, bool cente else if (textSize == 3) badge = badge3; else badge = badge4; + const int w = badge.width() / badge.devicePixelRatio(); + const int h = badge.height() / badge.devicePixelRatio(); + int x = 0; - if (center) x -= badge.width() / 2; + if (center) x -= w / 2; - QRect rect(x, 0, badge.width(), size); + QRect rect(x, 0, w, h); painter->drawPixmap(rect, badge); QFont f = painter->font(); diff --git a/src/playlistitemdelegate.cpp b/src/playlistitemdelegate.cpp index 7639a50..e3383f6 100644 --- a/src/playlistitemdelegate.cpp +++ b/src/playlistitemdelegate.cpp @@ -55,10 +55,13 @@ PlaylistItemDelegate::~PlaylistItemDelegate() { } 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); @@ -135,7 +138,7 @@ void PlaylistItemDelegate::paintBody( QPainter* painter, // play icon overlayed on the thumb if (isActive) - painter->drawPixmap(playIcon.rect(), playIcon); + painter->drawPixmap(0, 0, playIcon); // time if (video->duration() > 0) diff --git a/src/qtsingleapplication/qtsingleapplication.pri b/src/qtsingleapplication/qtsingleapplication.pri index 6f2bced..1d85285 100755 --- a/src/qtsingleapplication/qtsingleapplication.pri +++ b/src/qtsingleapplication/qtsingleapplication.pri @@ -1,4 +1,3 @@ -include(../common.pri) INCLUDEPATH += $$PWD DEPENDPATH += $$PWD QT *= network diff --git a/src/refinesearchbutton.cpp b/src/refinesearchbutton.cpp index eeb4fe1..361fe3a 100644 --- a/src/refinesearchbutton.cpp +++ b/src/refinesearchbutton.cpp @@ -19,21 +19,17 @@ along with Minitube. If not, see . $END_LICENSE */ #include "refinesearchbutton.h" - -static const int refineButtonSize = 48; +#include "iconutils.h" RefineSearchButton::RefineSearchButton(QWidget *parent) : QPushButton(parent) { hovered = false; + const int refineButtonSize = 48; setMinimumSize(refineButtonSize, refineButtonSize); setMaximumSize(refineButtonSize, refineButtonSize); setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - setStyleSheet( - "background: red url(:/images/refine-search.png) no-repeat center;" - "border: 0;" - ); } void RefineSearchButton::paintBackground() const { @@ -41,19 +37,18 @@ void RefineSearchButton::paintBackground() const { } void RefineSearchButton::paintEvent(QPaintEvent *) { - // QPushButton::paintEvent(event); QPainter painter(this); painter.setRenderHints(QPainter::Antialiasing, true); + painter.setPen(Qt::NoPen); painter.setBrush(QColor(0,0,0, hovered ? 192 : 170)); - QPen pen(Qt::white); - pen.setWidth(2); - painter.setPen(pen); painter.drawEllipse(QPoint(width(), height()), width()-2, height()-2); - QPixmap icon = QPixmap(":/images/refine-search.png"); - painter.drawPixmap(width() - icon.width() - 6, height() - icon.height() - 6, - icon.width(), icon.height(), - icon); + QPixmap pixmap = IconUtils::pixmap(":/images/refine-search.png"); + int pw = pixmap.width() / pixmap.devicePixelRatio(); + int ph = pixmap.height() / pixmap.devicePixelRatio(); + painter.drawPixmap(width() - pw - 6, height() - ph - 6, + pw, ph, + pixmap); } void RefineSearchButton::enterEvent(QEvent *) { diff --git a/src/refinesearchwidget.cpp b/src/refinesearchwidget.cpp index ddd0999..5948f2d 100644 --- a/src/refinesearchwidget.cpp +++ b/src/refinesearchwidget.cpp @@ -23,6 +23,7 @@ $END_LICENSE */ #ifdef APP_EXTRA #include "extra.h" #endif +#include "iconutils.h" namespace The { QHash* globalActions(); @@ -155,7 +156,8 @@ void RefineSearchWidget::setupLabel(const QString &text, QBoxLayout *layout, con QLabel *icon = new QLabel(this); icon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); QString resource = paramName; - QPixmap pixmap = QPixmap(":/images/search-" + resource + ".png"); + QPixmap pixmap = IconUtils::pixmap(":/images/search-" + resource + ".png"); + /* QPixmap translucentPixmap(pixmap.size()); translucentPixmap.fill(Qt::transparent); QPainter painter; @@ -163,11 +165,11 @@ void RefineSearchWidget::setupLabel(const QString &text, QBoxLayout *layout, con painter.setOpacity(0.5); painter.drawPixmap(0, 0, pixmap); painter.end(); - icon->setPixmap(translucentPixmap); + */ + icon->setPixmap(pixmap); hLayout->addWidget(icon); QLabel *label = new QLabel(text, this); - label->setStyleSheet("color: rgba(0, 0, 0, 128);"); hLayout->addWidget(label); icon->setMaximumHeight(label->height()); diff --git a/src/searchview.cpp b/src/searchview.cpp index aa0038a..6f3280e 100644 --- a/src/searchview.cpp +++ b/src/searchview.cpp @@ -37,6 +37,7 @@ $END_LICENSE */ #endif #include "mainwindow.h" #include "painterutils.h" +#include "iconutils.h" namespace The { QHash* globalActions(); @@ -70,7 +71,7 @@ SearchView::SearchView(QWidget *parent) : View(parent) { mainLayout->addLayout(hLayout); QLabel *logo = new QLabel(this); - logo->setPixmap(QPixmap(":/images/app.png")); + logo->setPixmap(IconUtils::pixmap(":/images/app.png")); hLayout->addWidget(logo, 0, Qt::AlignTop); hLayout->addSpacing(PADDING); @@ -257,7 +258,7 @@ void SearchView::updateRecentKeywords() { itemLabel->setAttribute(Qt::WA_DeleteOnClose); itemLabel->setProperty("recentItem", true); itemLabel->setMaximumWidth(queryEdit->toWidget()->width() + watchButton->width()); - // itemLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + itemLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); // Make links navigable with the keyboard too itemLabel->setTextInteractionFlags(Qt::LinksAccessibleByKeyboard | Qt::LinksAccessibleByMouse); if (needStatusTip) diff --git a/src/segmentedcontrol.cpp b/src/segmentedcontrol.cpp index e27ff64..88172ab 100644 --- a/src/segmentedcontrol.cpp +++ b/src/segmentedcontrol.cpp @@ -173,7 +173,7 @@ QAction *SegmentedControl::hoveredAction(const QPoint& pos) const { return(d->actionList[buttonIndex]); } -int SegmentedControl::calculateButtonWidth (void) const { +int SegmentedControl::calculateButtonWidth() const { QFontMetrics fontMetrics(font()); int tmpItemWidth, itemWidth = 0; foreach (QAction *action, d->actionList) { @@ -195,7 +195,6 @@ void SegmentedControl::drawButton (QPainter *painter, void SegmentedControl::drawUnselectedButton (QPainter *painter, const QRect& rect, const QAction *action) { - painter->setPen(QPen(QColor(0, 0, 0, 128), 1)); paintButton(painter, rect, action); } @@ -216,7 +215,6 @@ void SegmentedControl::drawSelectedButton (QPainter *painter, painter->fillRect(0, 0, width, height, QBrush(gradient)); painter->restore(); - painter->setPen(QPen(QColor(0, 0, 0, 232), 1)); paintButton(painter, rect, action); } @@ -228,7 +226,7 @@ void SegmentedControl::paintButton(QPainter *painter, const QRect& rect, const Q const int width = rect.width(); painter->save(); - painter->setPen(borderColor); + painter->setPen(QPen(borderColor, 1.0 / qApp->devicePixelRatio())); #if defined(APP_MAC) | defined(APP_WIN) painter->drawRect(-1, -1, width, height); #else diff --git a/src/segmentedcontrol.h b/src/segmentedcontrol.h index bab83b1..4f3ec85 100644 --- a/src/segmentedcontrol.h +++ b/src/segmentedcontrol.h @@ -62,7 +62,7 @@ private: const QRect& rect, const QAction *action); QAction *hoveredAction(const QPoint& pos) const; - int calculateButtonWidth(void) const; + int calculateButtonWidth() const; class Private; Private *d; diff --git a/src/video.cpp b/src/video.cpp index 03edbda..2a05f07 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -94,21 +94,19 @@ void Video::loadThumbnail() { connect(reply, SIGNAL(data(QByteArray)), SLOT(setThumbnail(QByteArray))); } -void Video::setThumbnail(QByteArray bytes) { +void Video::setThumbnail(const QByteArray &bytes) { loadingThumbnail = false; + qreal ratio = qApp->devicePixelRatio(); m_thumbnail = QPixmap(); m_thumbnail.loadFromData(bytes); - if (m_thumbnail.width() > 160) - m_thumbnail = m_thumbnail.scaledToWidth(160, Qt::SmoothTransformation); + m_thumbnail.setDevicePixelRatio(ratio); + const int thumbWidth = 160 * ratio; + if (m_thumbnail.width() > thumbWidth) + m_thumbnail = m_thumbnail.scaledToWidth(thumbWidth, Qt::SmoothTransformation); + qDebug() << __PRETTY_FUNCTION__ << m_thumbnail.size(); emit gotThumbnail(); } -void Video::loadMediumThumbnail() { - if (m_mediumThumbnailUrl.isEmpty()) return; - QObject *reply = The::http()->get(m_mediumThumbnailUrl); - connect(reply, SIGNAL(data(QByteArray)), SIGNAL(gotMediumThumbnail(QByteArray))); -} - void Video::loadStreamUrl() { if (loadingStreamUrl) { qDebug() << "Already loading stream URL for" << this->title(); @@ -156,8 +154,8 @@ void Video::getVideoInfo() { // see you in gotVideoInfo... } -void Video::gotVideoInfo(QByteArray data) { - QString videoInfo = QString::fromUtf8(data); +void Video::gotVideoInfo(const QByteArray &bytes) { + QString videoInfo = QString::fromUtf8(bytes); // qDebug() << "videoInfo" << videoInfo; // get video token @@ -292,8 +290,8 @@ void Video::errorVideoInfo(QNetworkReply *reply) { emit errorStreamUrl(tr("Network error: %1 for %2").arg(reply->errorString(), reply->url().toString())); } -void Video::scrapeWebPage(QByteArray data) { - QString html = QString::fromUtf8(data); +void Video::scrapeWebPage(const QByteArray &bytes) { + QString html = QString::fromUtf8(bytes); QRegExp ageGateRE(JsFunctions::instance()->ageGateRE()); if (ageGateRE.indexIn(html) != -1) { @@ -347,7 +345,7 @@ void Video::scrapeWebPage(QByteArray data) { } } -void Video::parseJsPlayer(QByteArray bytes) { +void Video::parseJsPlayer(const QByteArray &bytes) { QString js = QString::fromUtf8(bytes); // qWarning() << "jsPlayer" << js; @@ -393,7 +391,7 @@ void Video::parseJsPlayer(QByteArray bytes) { parseFmtUrlMap(fmtUrlMap, true); } -void Video::parseDashManifest(QByteArray bytes) { +void Video::parseDashManifest(const QByteArray &bytes) { QFile file(Temporary::filename() + ".mpd"); if (!file.open(QIODevice::WriteOnly)) qWarning() << file.errorString() << file.fileName(); diff --git a/src/video.h b/src/video.h index d502cb2..f612d90 100644 --- a/src/video.h +++ b/src/video.h @@ -42,65 +42,68 @@ public: LicenseCC }; - const QString & title() const { return m_title; } - void setTitle(const QString &title) { m_title = title; } + const QString &title() const { return m_title; } + void setTitle(const QString &value) { m_title = value; } - const QString & description() const { return m_description; } - void setDescription(const QString &description) { m_description = description; } + const QString &description() const { return m_description; } + void setDescription(const QString &value) { m_description = value; } - const QString & channelTitle() const { return m_channelTitle; } + const QString &channelTitle() const { return m_channelTitle; } void setChannelTitle(const QString &value) { m_channelTitle = value; } - const QString & channelId() const { return m_channelId; } + const QString &channelId() const { return m_channelId; } void setChannelId(const QString &value ) { m_channelId = value; } - const QString & webpage(); + const QString &webpage(); void setWebpage(const QString &value); void loadThumbnail(); - const QPixmap & thumbnail() const { return m_thumbnail; } + const QPixmap &thumbnail() const { return m_thumbnail; } - const QString & thumbnailUrl() { return m_thumbnailUrl; } - void setThumbnailUrl(const QString &url) { m_thumbnailUrl = url; } + const QString &thumbnailUrl() { return m_thumbnailUrl; } + void setThumbnailUrl(const QString &value) { m_thumbnailUrl = value; } - void loadMediumThumbnail(); - const QString & mediumThumbnailUrl() { return m_mediumThumbnailUrl; } - void setMediumThumbnailUrl(const QString &url) { m_mediumThumbnailUrl = url; } + const QString &mediumThumbnailUrl() { return m_mediumThumbnailUrl; } + void setMediumThumbnailUrl(const QString &value) { m_mediumThumbnailUrl = value; } + + const QString &largeThumbnailUrl() { return m_largeThumbnailUrl; } + void setLargeThumbnailUrl(const QString &value) { m_largeThumbnailUrl = value; } int duration() const { return m_duration; } - void setDuration( int duration ) { m_duration = duration; } + void setDuration(int value) { m_duration = value; } QString formattedDuration() const; int viewCount() const { return m_viewCount; } - void setViewCount( int viewCount ) { m_viewCount = viewCount; } + void setViewCount(int viewCount) { m_viewCount = viewCount; } - const QDateTime & published() const { return m_published; } - void setPublished(const QDateTime &published ) { m_published = published; } + const QDateTime &published() const { return m_published; } + void setPublished(const QDateTime &value) { m_published = value; } int getDefinitionCode() const { return definitionCode; } void loadStreamUrl(); - const QUrl & getStreamUrl() { return m_streamUrl; } + const QUrl &getStreamUrl() { return m_streamUrl; } void setId(const QString &value) { videoId = value; } - const QString & id() const { return videoId; } + const QString &id() const { return videoId; } - void setLicense(License license) { m_license = license; } + void setLicense(License value) { m_license = value; } License license() const { return m_license; } signals: void gotThumbnail(); - void gotMediumThumbnail(QByteArray bytes); - void gotStreamUrl(QUrl streamUrl); - void errorStreamUrl(QString message); + void gotMediumThumbnail(const QByteArray &bytes); + void gotLargeThumbnail(const QByteArray &bytes); + void gotStreamUrl(const QUrl &streamUrl); + void errorStreamUrl(const QString &message); private slots: - void setThumbnail(QByteArray bytes); - void gotVideoInfo(QByteArray); - void errorVideoInfo(QNetworkReply*); - void scrapeWebPage(QByteArray); - void parseJsPlayer(QByteArray bytes); - void parseDashManifest(QByteArray bytes); + void setThumbnail(const QByteArray &bytes); + void gotVideoInfo(const QByteArray &bytes); + void errorVideoInfo(QNetworkReply *reply); + void scrapeWebPage(const QByteArray &bytes); + void parseJsPlayer(const QByteArray &bytes); + void parseDashManifest(const QByteArray &bytes); private: void getVideoInfo(); @@ -108,7 +111,7 @@ private: void captureFunction(const QString &name, const QString &js); void captureObject(const QString &name, const QString &js); QString decryptSignature(const QString &s); - void saveDefinitionForUrl(const QString& url, const VideoDefinition& definition); + void saveDefinitionForUrl(const QString &url, const VideoDefinition &definition); QString m_title; QString m_description; @@ -119,6 +122,7 @@ private: QPixmap m_thumbnail; QString m_thumbnailUrl; QString m_mediumThumbnailUrl; + QString m_largeThumbnailUrl; int m_duration; QDateTime m_published; int m_viewCount; diff --git a/src/videosourcewidget.cpp b/src/videosourcewidget.cpp index ccd2a0f..ce1a92f 100644 --- a/src/videosourcewidget.cpp +++ b/src/videosourcewidget.cpp @@ -22,16 +22,21 @@ $END_LICENSE */ #include "videosource.h" #include "video.h" #include "fontutils.h" +#include "iconutils.h" +#include "networkaccess.h" + +namespace The { +NetworkAccess* http(); +} VideoSourceWidget::VideoSourceWidget(VideoSource *videoSource, QWidget *parent) : GridWidget(parent), - videoSource(videoSource) { + videoSource(videoSource), + lastPixelRatio(0) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - connect(videoSource, SIGNAL(gotVideos(QList)), - SLOT(previewVideo(QList)), Qt::UniqueConnection); - videoSource->loadVideos(1, 1); + loadPreview(); connect(this, SIGNAL(activated()), SLOT(activate())); } @@ -40,26 +45,38 @@ void VideoSourceWidget::activate() { emit activated(videoSource); } -void VideoSourceWidget::previewVideo(QList videos) { +void VideoSourceWidget::previewVideo(const QList