From be08d3ff0d366280edd6cc1aad0b89da9797b4d3 Mon Sep 17 00:00:00 2001 From: Craig Watson Date: Tue, 8 Mar 2016 17:04:33 +0100 Subject: [PATCH] Videos: show black rectangle also on OS X and Windows (Solution from previous commit worked only on Linux) --- src/domain/UBGraphicsMediaItem.cpp | 44 ++++++++++++++++++++++++++---- src/domain/UBGraphicsMediaItem.h | 3 ++ 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/domain/UBGraphicsMediaItem.cpp b/src/domain/UBGraphicsMediaItem.cpp index 9109ad67..c26278cb 100644 --- a/src/domain/UBGraphicsMediaItem.cpp +++ b/src/domain/UBGraphicsMediaItem.cpp @@ -117,6 +117,7 @@ UBGraphicsVideoItem::UBGraphicsVideoItem(const QUrl &pMediaFileUrl, QGraphicsIte :UBGraphicsMediaItem(pMediaFileUrl, parent) { haveLinkedImage = true; + setPlaceholderVisible(true); Delegate()->createControls(); mVideoItem = new QGraphicsVideoItem(this); @@ -136,6 +137,9 @@ UBGraphicsVideoItem::UBGraphicsVideoItem(const QUrl &pMediaFileUrl, QGraphicsIte connect(mMediaObject, SIGNAL(videoAvailableChanged(bool)), this, SLOT(hasVideoChanged(bool))); + connect(mMediaObject, SIGNAL(stateChanged(QMediaPlayer::State)), + this, SLOT(mediaStateChanged(QMediaPlayer::State))); + setAcceptHoverEvents(true); update(); @@ -530,12 +534,42 @@ void UBGraphicsVideoItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) void UBGraphicsVideoItem::hasVideoChanged(bool hasVideo) { - if (hasVideo) { - setBrush(QColor(Qt::transparent)); - setPen(QColor(Qt::transparent)); - } - else { + // On Linux, this is called (with hasVideo == true) when the video is first played + // and when it finishes (hasVideo == false). But on Windows and OS X, it isn't called when + // the video finishes, so those platforms require another solution to showing/hiding the + // placeholder black rectangle. + + setPlaceholderVisible(!hasVideo); +} + +void UBGraphicsVideoItem::mediaStateChanged(QMediaPlayer::State state) +{ + +#if defined(Q_OS_OSX) || defined(Q_OS_WIN) + setPlaceholderVisible((state == QMediaPlayer::StoppedState)); +#else + Q_UNUSED(state); +#endif + +} + +/** + * @brief Set the brush and fill to display a black rectangle + * @param visible If true, a black rectangle is displayed in place of the video + * + * Depending on platforms, when a video is finished or stopped, the video might be + * removed altogether. To avoid just having the controls bar visible at that point, + * we can display a "fake" black video frame in its place using this method. + */ +void UBGraphicsVideoItem::setPlaceholderVisible(bool visible) +{ + if (visible) { setBrush(QColor(Qt::black)); setPen(QColor(Qt::white)); } + else { + setBrush(QColor(Qt::transparent)); + setPen(QColor(Qt::transparent)); + } + } diff --git a/src/domain/UBGraphicsMediaItem.h b/src/domain/UBGraphicsMediaItem.h index 3046e074..388221ec 100644 --- a/src/domain/UBGraphicsMediaItem.h +++ b/src/domain/UBGraphicsMediaItem.h @@ -180,6 +180,7 @@ public: public slots: void videoSizeChanged(QSizeF newSize); void hasVideoChanged(bool hasVideo); + void mediaStateChanged(QMediaPlayer::State state); protected: @@ -188,6 +189,8 @@ protected: virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event); virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event); virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); + + void setPlaceholderVisible(bool visible); };