diff --git a/src/panels/information/informationpanelcontent.h b/src/panels/information/informationpanelcontent.h --- a/src/panels/information/informationpanelcontent.h +++ b/src/panels/information/informationpanelcontent.h @@ -154,6 +154,7 @@ QDialogButtonBox* m_configureButtons; PlacesItemModel* m_placesItemModel; + bool m_usePhonon; }; #endif // INFORMATIONPANELCONTENT_H diff --git a/src/panels/information/informationpanelcontent.cpp b/src/panels/information/informationpanelcontent.cpp --- a/src/panels/information/informationpanelcontent.cpp +++ b/src/panels/information/informationpanelcontent.cpp @@ -46,11 +46,18 @@ #include #include #include +#include +#include +#include +#include #include "dolphin_informationpanelsettings.h" #include "phononwidget.h" #include "pixmapviewer.h" +const int PLAY_ARROW_SIZE = 24; +const int PLAY_ARROW_BORDER_SIZE = 2; + InformationPanelContent::InformationPanelContent(QWidget* parent) : QWidget(parent), m_item(), @@ -61,7 +68,8 @@ m_nameLabel(nullptr), m_metaDataWidget(nullptr), m_metaDataArea(nullptr), - m_placesItemModel(nullptr) + m_placesItemModel(nullptr), + m_usePhonon(false) { parent->installEventFilter(this); @@ -161,9 +169,9 @@ if (item != m_item) { m_item = item; - refreshPreview(); refreshMetaData(); } + refreshPreview(); } void InformationPanelContent::refreshPreview() @@ -174,6 +182,8 @@ m_previewJob->kill(); } + m_preview->setCursor(Qt::ArrowCursor); + m_usePhonon = false; setNameLabelText(m_item.text()); if (InformationPanelSettings::previewsShown()) { @@ -216,25 +226,33 @@ const QString mimeType = m_item.mimetype(); const bool isVideo = mimeType.startsWith(QLatin1String("video/")); - const bool usePhonon = mimeType.startsWith(QLatin1String("audio/")) || isVideo; - - if (usePhonon) { - - if (InformationPanelSettings::previewsAutoPlay() && isVideo) { - // hides the preview now to avoid flickering when the autoplay video starts - m_preview->hide(); - } else { - // the video won't play before the preview is displayed - m_preview->show(); + m_usePhonon = mimeType.startsWith(QLatin1String("audio/")) || isVideo; + + if (m_usePhonon) { + if ((m_phononWidget->state() != Phonon::State::PlayingState && + m_phononWidget->state() != Phonon::State::PausedState) || + m_item.targetUrl() != m_phononWidget->url()) { + // change the cursor + m_preview->setCursor(Qt::PointingHandCursor); + m_preview->installEventFilter(m_phononWidget); + + if (InformationPanelSettings::previewsAutoPlay() && isVideo) { + // hides the preview now to avoid flickering when the autoplay video starts + m_preview->hide(); + } else { + // the video won't play before the preview is displayed + m_preview->show(); + } + + m_phononWidget->show(); + m_phononWidget->setUrl(m_item.targetUrl(), isVideo ? PhononWidget::MediaKind::Video : PhononWidget::MediaKind::Audio); + m_phononWidget->setVideoSize(m_preview->size()); } - - m_phononWidget->show(); - m_phononWidget->setUrl(m_item.targetUrl(), isVideo ? PhononWidget::MediaKind::Video : PhononWidget::MediaKind::Audio); - m_phononWidget->setVideoSize(m_preview->size()); } else { // When we don't need it, hide the phonon widget first to avoid flickering m_phononWidget->hide(); m_preview->show(); + m_preview->removeEventFilter(m_phononWidget); } } } else { @@ -323,6 +341,42 @@ QPixmap p = pixmap; KIconLoader::global()->drawOverlays(item.overlays(), p, KIconLoader::Desktop); + + if (m_usePhonon) { + // adds a play arrow + + // compute relative pixel positions + const int zero_x = static_cast(p.width() / 2 - PLAY_ARROW_SIZE / 2 / devicePixelRatio()); + const int zero_y = static_cast(p.height() / 2 - PLAY_ARROW_SIZE / 2 / devicePixelRatio()); + + QPolygon arrow; + arrow << QPoint(zero_x, zero_y); + arrow << QPoint(zero_x, zero_y + PLAY_ARROW_SIZE); + arrow << QPoint(zero_x + PLAY_ARROW_SIZE, zero_y + PLAY_ARROW_SIZE / 2); + + QPainterPath path; + path.addPolygon(arrow); + + QLinearGradient gradient(QPointF(zero_x, zero_y), + QPointF(zero_x + PLAY_ARROW_SIZE,zero_y + PLAY_ARROW_SIZE)); + + QColor whiteColor = Qt::white; + QColor blackColor = Qt::black; + gradient.setColorAt(0, whiteColor); + gradient.setColorAt(1, blackColor); + + QBrush brush(gradient); + + QPainter painter(&p); + + QPen pen(blackColor, PLAY_ARROW_BORDER_SIZE, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); + painter.setPen(pen); + + painter.setRenderHint(QPainter::Antialiasing); + painter.drawPolygon(arrow); + painter.fillPath(path, brush); + } + m_preview->setPixmap(p); } diff --git a/src/panels/information/phononwidget.h b/src/panels/information/phononwidget.h --- a/src/panels/information/phononwidget.h +++ b/src/panels/information/phononwidget.h @@ -58,6 +58,7 @@ QSize videoSize() const; void setAutoPlay(bool autoPlay); + bool eventFilter(QObject *object, QEvent *event) override; signals: /** @@ -72,6 +73,7 @@ public slots: void play(); + Phonon::State state(); protected: void showEvent(QShowEvent *event) override; diff --git a/src/panels/information/phononwidget.cpp b/src/panels/information/phononwidget.cpp --- a/src/panels/information/phononwidget.cpp +++ b/src/panels/information/phononwidget.cpp @@ -95,6 +95,24 @@ return m_url; } +bool PhononWidget::eventFilter(QObject *object, QEvent *event) +{ + Q_UNUSED(object); + if (event->type() == QEvent::MouseButtonPress) { + const QMouseEvent *mouseEvent = static_cast(event); + if (mouseEvent->button() == Qt::LeftButton) { + // toggle playback + if (m_media && m_media->state() == Phonon::State::PlayingState) { + m_media->pause(); + } else { + play(); + } + return true; + } + } + return false; +} + void PhononWidget::setVideoSize(const QSize& size) { if (m_videoSize != size) { @@ -172,8 +190,8 @@ switch (newstate) { case Phonon::PlayingState: case Phonon::BufferingState: - m_stopButton->show(); m_playButton->hide(); + m_stopButton->show(); break; default: m_stopButton->hide(); @@ -196,6 +214,7 @@ if (!m_videoPlayer) { m_videoPlayer = new EmbeddedVideoPlayer(this); + m_videoPlayer->setCursor(Qt::PointingHandCursor); m_videoPlayer->installEventFilter(this); m_topLayout->insertWidget(0, m_videoPlayer); Phonon::createPath(m_media, m_videoPlayer); @@ -227,6 +246,11 @@ } } +Phonon::State PhononWidget::state() +{ + return m_media == nullptr ? Phonon::State::StoppedState : m_media->state(); +} + void PhononWidget::stop() { if (m_media) {