From fe9affeea1fc9f75cdbd8399736c8fcbbdc90c87 Mon Sep 17 00:00:00 2001 From: Craig Watson <craig@watsons.ch> Date: Fri, 26 Feb 2016 15:00:31 +0100 Subject: [PATCH] Overhaul of UBGraphicsMediaItem class - Removed inheritance of UBGraphicsProxyWidget; cleaned up related code - Added two children classes: UBGraphicsVideoItem and UBGraphicsAudioItem. UBGraphicsMediaItem is now an abstract class. - Better encapsulation; the Scene and other external classes no longer access the mediaObject directly There is now less distinction between audio and video items to outside code: apart from the UBSvgSubsetAdaptor, there is no need to know whether a media item holds a video or audio file. Creation is handled through the static function `UBGraphicsMediaItem::createMediaItem(URL, parent)` --- src/adaptors/UBSvgSubsetAdaptor.cpp | 48 +-- src/adaptors/UBSvgSubsetAdaptor.h | 6 +- src/board/UBBoardController.h | 2 - src/core/UBPersistenceManager.cpp | 2 +- src/domain/UBGraphicsItemDelegate.cpp | 4 +- src/domain/UBGraphicsMediaItem.cpp | 376 ++++++++++++++------- src/domain/UBGraphicsMediaItem.h | 114 ++++--- src/domain/UBGraphicsMediaItemDelegate.cpp | 102 ++---- src/domain/UBGraphicsMediaItemDelegate.h | 13 +- src/domain/UBGraphicsScene.cpp | 20 +- src/domain/UBGraphicsScene.h | 2 - 11 files changed, 393 insertions(+), 296 deletions(-) diff --git a/src/adaptors/UBSvgSubsetAdaptor.cpp b/src/adaptors/UBSvgSubsetAdaptor.cpp index 064ca529..c28da1c6 100644 --- a/src/adaptors/UBSvgSubsetAdaptor.cpp +++ b/src/adaptors/UBSvgSubsetAdaptor.cpp @@ -661,9 +661,8 @@ UBGraphicsScene* UBSvgSubsetAdaptor::UBSvgSubsetReader::loadScene() audioItem->show(); - //force start to load the video and display the first frame - audioItem->mediaObject()->play(); - audioItem->mediaObject()->pause(); + audioItem->play(); + audioItem->pause(); } } else if (mXmlReader.name() == "video") @@ -676,16 +675,12 @@ UBGraphicsScene* UBSvgSubsetAdaptor::UBSvgSubsetReader::loadScene() videoItem->setFlag(QGraphicsItem::ItemIsSelectable, true); mScene->addItem(videoItem); - mScene->addItem(videoItem->videoItem()); - - // Update the child QGraphicsVideoItem's transformation matrix - videoItem->setMatrix(videoItem->matrix()); videoItem->show(); //force start to load the video and display the first frame - videoItem->mediaObject()->play(); - videoItem->mediaObject()->pause(); + videoItem->play(); + videoItem->pause(); } } else if (mXmlReader.name() == "text")//This is for backward compatibility with proto text field prior to version 4.3 @@ -1210,14 +1205,17 @@ bool UBSvgSubsetAdaptor::UBSvgSubsetWriter::persistScene(int pageIndex) continue; } - UBGraphicsMediaItem *mediaItem = qgraphicsitem_cast<UBGraphicsMediaItem*> (item); + UBGraphicsVideoItem * videoItem = qgraphicsitem_cast<UBGraphicsVideoItem*> (item); - if (mediaItem && mediaItem->isVisible()) - { - if (UBGraphicsMediaItem::mediaType_Video == mediaItem->getMediaType()) - videoItemToLinkedVideo(mediaItem); - else - audioItemToLinkedAudio(mediaItem); + if (videoItem && videoItem->isVisible()) { + videoItemToLinkedVideo(videoItem); + continue; + } + + UBGraphicsAudioItem * audioItem = qgraphicsitem_cast<UBGraphicsAudioItem*> (item); + + if (audioItem && audioItem->isVisible()) { + audioItemToLinkedAudio(audioItem); continue; } @@ -2019,15 +2017,16 @@ UBGraphicsPDFItem* UBSvgSubsetAdaptor::UBSvgSubsetReader::pdfItemFromPDF() return pdfItem; } -void UBSvgSubsetAdaptor::UBSvgSubsetWriter::audioItemToLinkedAudio(UBGraphicsMediaItem* audioItem) +void UBSvgSubsetAdaptor::UBSvgSubsetWriter::audioItemToLinkedAudio(UBGraphicsAudioItem *audioItem) { mXmlWriter.writeStartElement("audio"); graphicsItemToSvg(audioItem); - if (audioItem->mediaObject()->state() == QMediaPlayer::PausedState && (audioItem->mediaObject()->duration() - audioItem->mediaObject()->position()) > 0) + if (audioItem->playerState() == QMediaPlayer::PausedState && + (audioItem->mediaDuration() - audioItem->mediaPosition()) > 0) { - qint64 pos = audioItem->mediaObject()->position(); + qint64 pos = audioItem->mediaPosition(); mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "position", QString("%1").arg(pos)); } @@ -2038,7 +2037,7 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::audioItemToLinkedAudio(UBGraphicsMed } -void UBSvgSubsetAdaptor::UBSvgSubsetWriter::videoItemToLinkedVideo(UBGraphicsMediaItem* videoItem) +void UBSvgSubsetAdaptor::UBSvgSubsetWriter::videoItemToLinkedVideo(UBGraphicsVideoItem* videoItem) { /* w3c sample * @@ -2051,9 +2050,10 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::videoItemToLinkedVideo(UBGraphicsMed graphicsItemToSvg(videoItem); - if (videoItem->mediaObject()->state() == QMediaPlayer::PausedState && (videoItem->mediaObject()->duration() - videoItem->mediaObject()->position()) > 0) + if (videoItem->playerState() == QMediaPlayer::PausedState && + (videoItem->mediaDuration() - videoItem->mediaPosition()) > 0) { - qint64 pos = videoItem->mediaObject()->position(); + qint64 pos = videoItem->mediaPosition(); mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "position", QString("%1").arg(pos)); } @@ -2083,7 +2083,7 @@ UBGraphicsMediaItem* UBSvgSubsetAdaptor::UBSvgSubsetReader::audioItemFromSvg() href = mDocumentPath + "/" + href.right(href.length() - indexOfAudioDirectory); } - UBGraphicsMediaItem* audioItem = new UBGraphicsMediaItem(QUrl::fromLocalFile(href)); + UBGraphicsMediaItem* audioItem = UBGraphicsMediaItem::createMediaItem(QUrl::fromLocalFile(href)); if(audioItem) audioItem->connect(UBApplication::boardController, SIGNAL(activeSceneChanged()), audioItem, SLOT(activeSceneChanged())); @@ -2118,7 +2118,7 @@ UBGraphicsMediaItem* UBSvgSubsetAdaptor::UBSvgSubsetReader::videoItemFromSvg() href = mDocumentPath + "/" + href.right(href.length() - indexOfAudioDirectory); } - UBGraphicsMediaItem* videoItem = new UBGraphicsMediaItem(QUrl::fromLocalFile(href)); + UBGraphicsMediaItem* videoItem = UBGraphicsMediaItem::createMediaItem(QUrl::fromLocalFile(href)); if(videoItem){ videoItem->connect(UBApplication::boardController, SIGNAL(activeSceneChanged()), videoItem, SLOT(activeSceneChanged())); } diff --git a/src/adaptors/UBSvgSubsetAdaptor.h b/src/adaptors/UBSvgSubsetAdaptor.h index 7bc1c88b..91f61e94 100644 --- a/src/adaptors/UBSvgSubsetAdaptor.h +++ b/src/adaptors/UBSvgSubsetAdaptor.h @@ -40,6 +40,8 @@ class UBGraphicsPixmapItem; class UBGraphicsPDFItem; class UBGraphicsWidgetItem; class UBGraphicsMediaItem; +class UBGraphicsVideoItem; +class UBGraphicsAudioItem; class UBGraphicsAppleWidgetItem; class UBGraphicsW3CWidgetItem; class UBGraphicsTextItem; @@ -232,8 +234,8 @@ class UBSvgSubsetAdaptor void pixmapItemToLinkedImage(UBGraphicsPixmapItem *pixmapItem); void svgItemToLinkedSvg(UBGraphicsSvgItem *svgItem); void pdfItemToLinkedPDF(UBGraphicsPDFItem *pdfItem); - void videoItemToLinkedVideo(UBGraphicsMediaItem *videoItem); - void audioItemToLinkedAudio(UBGraphicsMediaItem *audioItem); + void videoItemToLinkedVideo(UBGraphicsVideoItem *videoItem); + void audioItemToLinkedAudio(UBGraphicsAudioItem *audioItem); void graphicsItemToSvg(QGraphicsItem *item); void graphicsAppleWidgetToSvg(UBGraphicsAppleWidgetItem *item); void graphicsW3CWidgetToSvg(UBGraphicsW3CWidgetItem *item); diff --git a/src/board/UBBoardController.h b/src/board/UBBoardController.h index 4d796656..bc1481d5 100644 --- a/src/board/UBBoardController.h +++ b/src/board/UBBoardController.h @@ -51,8 +51,6 @@ class UBVersion; class UBSoftwareUpdate; class UBSoftwareUpdateDialog; class UBGraphicsMediaItem; -class UBGraphicsVideoItem; -class UBGraphicsAudioItem; class UBGraphicsWidgetItem; class UBBoardPaletteManager; class UBItem; diff --git a/src/core/UBPersistenceManager.cpp b/src/core/UBPersistenceManager.cpp index 60c271ef..7114bfae 100644 --- a/src/core/UBPersistenceManager.cpp +++ b/src/core/UBPersistenceManager.cpp @@ -566,7 +566,7 @@ void UBPersistenceManager::duplicateDocumentScene(UBDocumentProxy* proxy, int in QString fileName = QFileInfo(source).completeBaseName(); destination = destination.replace(fileName,newUuid.toString()); QFile::copy(source,destination); - mediaItem->mediaFileUrl(QUrl::fromLocalFile(destination)); + mediaItem->setMediaFileUrl(QUrl::fromLocalFile(destination)); continue; } diff --git a/src/domain/UBGraphicsItemDelegate.cpp b/src/domain/UBGraphicsItemDelegate.cpp index a8271e34..779ca9e9 100644 --- a/src/domain/UBGraphicsItemDelegate.cpp +++ b/src/domain/UBGraphicsItemDelegate.cpp @@ -1439,10 +1439,10 @@ void DelegateMediaControl::seekToMousePos(QPointF mousePos) mouseX = mSeecArea.width() - mSeecArea.height()/2; if (mTotalTimeInMs > 0 && length > 0 && mDelegate - && mDelegate->mediaObject() && mDelegate->mediaObject()->isSeekable()) + && mDelegate->isMediaSeekable()) { qint64 tickPos = (mTotalTimeInMs/length)* (mouseX - minX); - mDelegate->mediaObject()->setPosition(tickPos); + mDelegate->setMediaPos(tickPos); //OSX is a bit lazy updateTicker(tickPos); diff --git a/src/domain/UBGraphicsMediaItem.cpp b/src/domain/UBGraphicsMediaItem.cpp index beaa39c9..8c61a874 100644 --- a/src/domain/UBGraphicsMediaItem.cpp +++ b/src/domain/UBGraphicsMediaItem.cpp @@ -39,100 +39,107 @@ bool UBGraphicsMediaItem::sIsMutedByDefault = false; +/** + * @brief Create and return a UBGraphicsMediaItem instance. The type (audio or video) is determined from the URL. + * @param pMediaFileUrl The URL of the audio or video file + * @param parent (Optional) the parent item + * @return A pointer to the newly created instance. + */ +UBGraphicsMediaItem* UBGraphicsMediaItem::createMediaItem(const QUrl &pMediaFileUrl, QGraphicsItem* parent) +{ + UBGraphicsMediaItem * mediaItem; + + QString mediaPath = pMediaFileUrl.toString(); + if ("" == mediaPath) + mediaPath = pMediaFileUrl.toLocalFile(); + + if (mediaPath.toLower().contains("videos")) + mediaItem = new UBGraphicsVideoItem(pMediaFileUrl, parent); + else if (mediaPath.toLower().contains("audios")) + mediaItem = new UBGraphicsAudioItem(pMediaFileUrl, parent); + + return mediaItem; +} + UBGraphicsMediaItem::UBGraphicsMediaItem(const QUrl& pMediaFileUrl, QGraphicsItem *parent) - : UBGraphicsProxyWidget(parent) - , mDummyVideoWidget(NULL) - , mVideoItem(NULL) - , mAudioWidget(NULL) + : QGraphicsRectItem(parent) , mMuted(sIsMutedByDefault) , mMutedByUserAction(sIsMutedByDefault) , mMediaFileUrl(pMediaFileUrl) , mLinkedImage(NULL) , mInitialPos(0) { - update(); - mMediaObject = new QMediaPlayer(this); + mMediaObject->setMedia(pMediaFileUrl); - QString mediaPath = pMediaFileUrl.toString(); - if ("" == mediaPath) - mediaPath = pMediaFileUrl.toLocalFile(); + setDelegate(new UBGraphicsMediaItemDelegate(this)); + Delegate()->createControls(); - if (mediaPath.toLower().contains("videos")) - { - mMediaType = mediaType_Video; + setData(UBGraphicsItemData::itemLayerType, QVariant(itemLayerType::ObjectItem)); + setFlag(ItemIsMovable, true); + setFlag(ItemSendsGeometryChanges, true); - mMediaObject->setNotifyInterval(50); + setAcceptHoverEvents(true); - /* A dummy widget is used to keep the old functionality (when a Phonon video widget - * was used) with the current implementation, such as maintaining a clickable area - * above the video to move it around, etc. - * The whole class could be cleaned up, and the inheritance of QGraphicsProxyWidget - * abandoned, to make for a cleaner solution; for now, this works ok. - */ - mDummyVideoWidget = new QWidget(); - mDummyVideoWidget->resize(320,240); - mDummyVideoWidget->setMinimumSize(320, 240); - mDummyVideoWidget->setWindowOpacity(0.0); - - mVideoItem = new QGraphicsVideoItem(this); + connect(mMediaObject, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), + Delegate(), SLOT(mediaStatusChanged(QMediaPlayer::MediaStatus))); - // Necessary to allow the video to be displayed on secondary screen - mVideoItem->setData(UBGraphicsItemData::ItemLayerType, UBItemLayerType::Object); - mVideoItem->setFlag(ItemStacksBehindParent, true); + connect(mMediaObject, SIGNAL(stateChanged(QMediaPlayer::State)), + Delegate(), SLOT(mediaStateChanged(QMediaPlayer::State))); - mMediaObject->setVideoOutput(mVideoItem); + /* + connect(mMediaObject, static_cast<void(QMediaPlayer::*)(QMediaPlayer::Error)>(&QMediaPlayer::error), + Delegate(), &UBGraphicsMediaItemDelegate::mediaError); + */ - mVideoItem->setSize(QSize(320,240)); + connect(mMediaObject, SIGNAL(positionChanged(qint64)), + Delegate(), SLOT(updateTicker(qint64))); - haveLinkedImage = true; - } - else if (mediaPath.toLower().contains("audios")) - { - mMediaType = mediaType_Audio; + connect(mMediaObject, SIGNAL(durationChanged(qint64)), + Delegate(), SLOT(totalTimeChanged(qint64))); - mMediaObject->setNotifyInterval(1000); - mAudioWidget = new QWidget(); - mAudioWidget->resize(320,26); - mAudioWidget->setMinimumSize(150,26); + connect(Delegate(), SIGNAL(showOnDisplayChanged(bool)), + this, SLOT(showOnDisplayChanged(bool))); - haveLinkedImage = false; - } + connect(mMediaObject, SIGNAL(videoAvailableChanged(bool)), + this, SLOT(hasMediaChanged(bool))); +} - mMediaObject->setMedia(pMediaFileUrl); +UBGraphicsAudioItem::UBGraphicsAudioItem(const QUrl &pMediaFileUrl, QGraphicsItem *parent) + :UBGraphicsMediaItem(pMediaFileUrl, parent) +{ + this->setSize(320, 26); + this->setMinimumSize(QSize(150, 26)); + Delegate()->frame()->setOperationMode(UBGraphicsDelegateFrame::ResizingHorizontally); - // we should create delegate after media objects because delegate uses his properties at creation. - setDelegate(new UBGraphicsMediaItemDelegate(this, mMediaObject)); + mMediaObject->setNotifyInterval(1000); + haveLinkedImage = false; +} - // delegate should be created earler because we setWidget calls resize event for graphics proxy widgt. - // resize uses delegate. - if (mediaType_Video == mMediaType) - setWidget(mDummyVideoWidget); - else - setWidget(mAudioWidget); +UBGraphicsVideoItem::UBGraphicsVideoItem(const QUrl &pMediaFileUrl, QGraphicsItem *parent) + :UBGraphicsMediaItem(pMediaFileUrl, parent) +{ + mVideoItem = new QGraphicsVideoItem(this); - // media widget should be created and placed on proxy widget here. - // TODO claudio remove this because in contrast with the fact the frame should be created on demand. - // but without forcing the control creation we do not have the frame and all the calculation - // for the different element of the interface will fail - Delegate()->createControls(); - if (mediaType_Audio == mMediaType) - Delegate()->frame()->setOperationMode(UBGraphicsDelegateFrame::ResizingHorizontally); - else { - Delegate()->frame()->setOperationMode(UBGraphicsDelegateFrame::Resizing); - // Resize the widget as soon as the video's native size is known (it isn't at this stage) - connect(mVideoItem, SIGNAL(nativeSizeChanged(QSizeF)), this, SLOT(resize(QSizeF))); - } + mVideoItem->setData(UBGraphicsItemData::ItemLayerType, UBItemLayerType::Object); + mVideoItem->setFlag(ItemStacksBehindParent, true); - setData(UBGraphicsItemData::itemLayerType, QVariant(itemLayerType::ObjectItem)); //Necessary to set if we want z value to be assigned correctly + mMediaObject->setVideoOutput(mVideoItem); + mMediaObject->setNotifyInterval(50); + + setMinimumSize(QSize(320, 240)); + setSize(320, 240); - connect(Delegate(), SIGNAL(showOnDisplayChanged(bool)), this, SLOT(showOnDisplayChanged(bool))); - connect(mMediaObject, SIGNAL(videoAvailableChanged(bool)), this, SLOT(hasMediaChanged(bool))); -} + connect(mVideoItem, SIGNAL(nativeSizeChanged(QSizeF)), + this, SLOT(videoSizeChanged(QSizeF))); + + haveLinkedImage = true; + update(); +} UBGraphicsMediaItem::~UBGraphicsMediaItem() { @@ -140,19 +147,6 @@ UBGraphicsMediaItem::~UBGraphicsMediaItem() mMediaObject->stop(); } - -void UBGraphicsMediaItem::setSelected(bool selected) -{ - if(selected){ - Delegate()->createControls(); - if (mediaType_Audio == mMediaType) - Delegate()->frame()->setOperationMode(UBGraphicsDelegateFrame::ResizingHorizontally); - else - Delegate()->frame()->setOperationMode(UBGraphicsDelegateFrame::Resizing); - } - UBGraphicsProxyWidget::setSelected(selected); -} - QVariant UBGraphicsMediaItem::itemChange(GraphicsItemChange change, const QVariant &value) { if ((change == QGraphicsItem::ItemEnabledChange) @@ -180,9 +174,91 @@ QVariant UBGraphicsMediaItem::itemChange(GraphicsItemChange change, const QVaria } } - return UBGraphicsProxyWidget::itemChange(change, value); + if (Delegate()) { + QVariant newValue = Delegate()->itemChange(change, value); + return QGraphicsRectItem::itemChange(change, newValue); + } + + else + return QGraphicsRectItem::itemChange(change, value); } +void UBGraphicsMediaItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + painter->save(); + painter->setCompositionMode(QPainter::CompositionMode_SourceOver); + Delegate()->postpaint(painter, option, widget); + painter->restore(); +} + + +QMediaPlayer::State UBGraphicsMediaItem::playerState() const +{ + return mMediaObject->state(); +} + +qint64 UBGraphicsMediaItem::mediaDuration() const +{ + return mMediaObject->duration(); +} + +qint64 UBGraphicsMediaItem::mediaPosition() const +{ + return mMediaObject->position(); +} + +bool UBGraphicsMediaItem::isMediaSeekable() const +{ + return mMediaObject->isSeekable(); +} + +/** + * @brief Set the item's minimum size. If the current size is smaller, it will be resized. + * @param size The new minimum size + */ +void UBGraphicsMediaItem::setMinimumSize(const QSize& size) +{ + mMinimumSize = size; + + QSizeF newSize = rect().size(); + int width = newSize.width(); + int height = newSize.height(); + + if (rect().width() < mMinimumSize.width()) + width = mMinimumSize.width(); + + if (rect().height() < mMinimumSize.height()) + height = mMinimumSize.height(); + + this->setSize(width, height); +} + +void UBGraphicsMediaItem::setMediaFileUrl(QUrl url) +{ + mMediaFileUrl = url; +} + +void UBGraphicsMediaItem::setInitialPos(qint64 p) +{ + mInitialPos = p; +} + +void UBGraphicsMediaItem::setMediaPos(qint64 p) +{ + mMediaObject->setPosition(p); +} + +void UBGraphicsMediaItem::setSelected(bool selected) +{ + if(selected){ + Delegate()->createControls(); + if (this->getMediaType() == mediaType_Audio) + Delegate()->frame()->setOperationMode(UBGraphicsDelegateFrame::ResizingHorizontally); + else + Delegate()->frame()->setOperationMode(UBGraphicsDelegateFrame::Resizing); + } + QGraphicsRectItem::setSelected(selected); +} void UBGraphicsMediaItem::setSourceUrl(const QUrl &pSourceUrl) { @@ -243,28 +319,65 @@ void UBGraphicsMediaItem::activeSceneChanged() void UBGraphicsMediaItem::showOnDisplayChanged(bool shown) { - if (!shown) - { + if (!shown) { mMuted = true; mMediaObject->setMuted(mMuted); } - else if (!mMutedByUserAction) - { + else if (!mMutedByUserAction) { mMuted = false; mMediaObject->setMuted(mMuted); } } +void UBGraphicsMediaItem::play() +{ + mMediaObject->play(); +} -UBItem* UBGraphicsMediaItem::deepCopy() const +void UBGraphicsMediaItem::pause() { - QUrl url = this->mediaFileUrl(); - UBGraphicsMediaItem *copy = new UBGraphicsMediaItem(url, parentItem()); + mMediaObject->pause(); +} - copy->setUuid(this->uuid()); // this is OK for now as long as Widgets are imutable +void UBGraphicsMediaItem::stop() +{ + mMediaObject->stop(); +} - copyItemParameters(copy); +void UBGraphicsMediaItem::togglePlayPause() +{ + + if (mMediaObject->state() == QMediaPlayer::StoppedState) + mMediaObject->play(); + + else if (mMediaObject->state() == QMediaPlayer::PlayingState) { + + if ((mMediaObject->duration() - mMediaObject->position()) <= 0) { + mMediaObject->stop(); + mMediaObject->play(); + } + + else { + mMediaObject->pause(); + if(scene()) + scene()->setModified(true); + } + } + + else if (mMediaObject->state() == QMediaPlayer::PausedState) { + if ((mMediaObject->duration() - mMediaObject->position()) <= 0) + mMediaObject->stop(); + + mMediaObject->play(); + } + + else if ( mMediaObject->mediaStatus() == QMediaPlayer::LoadingMedia) { + mMediaObject->setMedia(mediaFileUrl()); + mMediaObject->play(); + } + + if (mMediaObject->error()) + qDebug() << "Error appeared." << mMediaObject->errorString(); - return copy; } void UBGraphicsMediaItem::copyItemParameters(UBItem *copy) const @@ -279,7 +392,7 @@ void UBGraphicsMediaItem::copyItemParameters(UBItem *copy) const cp->setData(UBGraphicsItemData::ItemLayerType, this->data(UBGraphicsItemData::ItemLayerType)); cp->setData(UBGraphicsItemData::ItemLocked, this->data(UBGraphicsItemData::ItemLocked)); cp->setSourceUrl(this->sourceUrl()); - cp->resize(this->size()); + cp->setSize(rect().width(), rect().height()); cp->setZValue(this->zValue()); @@ -322,59 +435,76 @@ void UBGraphicsMediaItem::mousePressEvent(QGraphicsSceneMouseEvent *event) event->accept(); setSelected(true); } + QGraphicsRectItem::mousePressEvent(event); +} +QRectF UBGraphicsMediaItem::boundingRect() const +{ + return rect(); } -void UBGraphicsMediaItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +void UBGraphicsMediaItem::setSize(int width, int height) { - if(mShouldMove && (event->buttons() & Qt::LeftButton)) - { - QPointF offset = event->scenePos() - mMousePressPos; + QRectF r = rect(); + r.setWidth(width); + r.setHeight(height); + setRect(r); - if (offset.toPoint().manhattanLength() > QApplication::startDragDistance()) - { - QPointF mouseMovePos = mapFromScene(mMouseMovePos); - QPointF eventPos = mapFromScene( event->scenePos()); + if (Delegate()) + Delegate()->positionHandles(); + if (scene()) + scene()->setModified(true); +} - QPointF translation = eventPos - mouseMovePos; - setPos(translation.x(), translation.y()); - } +UBItem* UBGraphicsAudioItem::deepCopy() const +{ + QUrl url = this->mediaFileUrl(); + UBGraphicsMediaItem *copy = new UBGraphicsAudioItem(url, parentItem()); - mMouseMovePos = event->scenePos(); - } + copy->setUuid(this->uuid()); // this is OK for now as long as Widgets are imutable + + copyItemParameters(copy); + + return copy; +} + +UBItem* UBGraphicsVideoItem::deepCopy() const +{ + QUrl url = this->mediaFileUrl(); + UBGraphicsMediaItem *copy = new UBGraphicsVideoItem(url, parentItem()); - event->accept(); + copy->setUuid(this->uuid()); + copyItemParameters(copy); + return copy; } -void UBGraphicsMediaItem::resize(const QSizeF & pSize) +void UBGraphicsVideoItem::setSize(int width, int height) { // Resize the video, then the rest of the Item - if (mVideoItem) { - qreal sizeX = 0; - qreal sizeY = 0; + int sizeX = 0; + int sizeY = 0; - QSizeF minimumItemSize(mDummyVideoWidget->minimumSize()); - if (minimumItemSize.width() > pSize.width()) - sizeX = minimumItemSize.width(); - else - sizeX = pSize.width(); + if (mMinimumSize.width() > width) + sizeX = mMinimumSize.width(); + else + sizeX = width; - if (minimumItemSize.height() > pSize.height()) - sizeY = minimumItemSize.height(); - else - sizeY = pSize.height(); + if (mMinimumSize.height() > height) + sizeY = mMinimumSize.height(); + else + sizeY = height; + + mVideoItem->setSize(QSize(sizeX, sizeY)); - mVideoItem->setSize(QSizeF (sizeX, sizeY)); - } - UBGraphicsProxyWidget::resize(pSize); + UBGraphicsMediaItem::setSize(sizeX, sizeY); } -void UBGraphicsMediaItem::resize(qreal w, qreal h) +void UBGraphicsVideoItem::videoSizeChanged(QSizeF newSize) { - UBGraphicsMediaItem::resize(QSizeF(w, h)); + this->setSize(newSize.width(), newSize.height()); } diff --git a/src/domain/UBGraphicsMediaItem.h b/src/domain/UBGraphicsMediaItem.h index 8014f85c..a7c4540c 100644 --- a/src/domain/UBGraphicsMediaItem.h +++ b/src/domain/UBGraphicsMediaItem.h @@ -45,7 +45,7 @@ class QGraphicsVideoItem; -class UBGraphicsMediaItem : public UBGraphicsProxyWidget +class UBGraphicsMediaItem : public QObject, public UBItem, public UBGraphicsItem, public QGraphicsRectItem, public UBResizableGraphicsItem { Q_OBJECT @@ -55,9 +55,6 @@ public: mediaType_Audio } mediaType; - UBGraphicsMediaItem(const QUrl& pMediaFileUrl, QGraphicsItem *parent = 0); - ~UBGraphicsMediaItem(); - enum { Type = UBGraphicsItemType::MediaItemType }; virtual int type() const @@ -65,48 +62,46 @@ public: return Type; } - virtual QUrl mediaFileUrl() const - { - return mMediaFileUrl; - } + static UBGraphicsMediaItem* createMediaItem(const QUrl& pMediaFileUrl, QGraphicsItem* parent = 0); - virtual void mediaFileUrl(QUrl url){mMediaFileUrl=url;} + UBGraphicsMediaItem(const QUrl& pMediaFileUrl, QGraphicsItem* parent = 0); + ~UBGraphicsMediaItem(); - QMediaPlayer* mediaObject() const - { - return mMediaObject; - } - void setInitialPos(qint64 p) { - mInitialPos = p; - } - qint64 initialPos() { - return mInitialPos; - } + // Getters - bool isMuted() const - { - return mMuted; - } + virtual mediaType getMediaType() const = 0; - QGraphicsVideoItem * videoItem() const - { - return mVideoItem; - } + virtual UBGraphicsScene* scene(); + bool hasLinkedImage() const { return haveLinkedImage; } + virtual QUrl mediaFileUrl() const { return mMediaFileUrl; } + bool isMuted() const { return mMuted; } + qint64 initialPos() const { return mInitialPos; } - bool hasLinkedImage(){return haveLinkedImage;} + bool isMediaSeekable() const; + qint64 mediaDuration() const; + qint64 mediaPosition() const; - mediaType getMediaType() { return mMediaType; } + QMediaPlayer::State playerState() const; - virtual UBGraphicsScene* scene(); + QRectF boundingRect() const; - virtual UBItem* deepCopy() const; + QSizeF size() const { return rect().size(); } + + // Setters + virtual void setMediaFileUrl(QUrl url); + void setInitialPos(qint64 p); + void setMediaPos(qint64 p); + virtual void setSourceUrl(const QUrl &pSourceUrl); + void setSelected(bool selected); + void setMinimumSize(const QSize& size); virtual void copyItemParameters(UBItem *copy) const; - virtual void setSourceUrl(const QUrl &pSourceUrl); + virtual void setSize(int width, int height); + void resize(qreal w, qreal h) { setSize(w, h); } - void setSelected(bool selected); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); public slots: @@ -116,23 +111,22 @@ public slots: void activeSceneChanged(); void hasMediaChanged(bool hasMedia); void showOnDisplayChanged(bool shown); - virtual void resize(qreal w, qreal h); - virtual void resize(const QSizeF & pSize); + + virtual void play(); + virtual void pause(); + virtual void stop(); + virtual void togglePlayPause(); protected: virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); - virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + virtual void clearSource(); QMediaPlayer *mMediaObject; - QWidget *mDummyVideoWidget; - QGraphicsVideoItem *mVideoItem; - QWidget *mAudioWidget; - -private: + QSize mMinimumSize; bool mMuted; bool mMutedByUserAction; @@ -141,8 +135,6 @@ private: QUrl mMediaFileUrl; QString mMediaSource; - mediaType mMediaType; - bool mShouldMove; QPointF mMousePressPos; QPointF mMouseMovePos; @@ -152,4 +144,40 @@ private: qint64 mInitialPos; }; + +class UBGraphicsAudioItem: public UBGraphicsMediaItem +{ + Q_OBJECT + +public: + + UBGraphicsAudioItem(const QUrl& pMediaFileUrl, QGraphicsItem *parent = 0); + mediaType getMediaType() const { return mediaType_Audio; } + + virtual UBItem* deepCopy() const; +}; + +class UBGraphicsVideoItem: public UBGraphicsMediaItem +{ + Q_OBJECT + +public: + + UBGraphicsVideoItem(const QUrl& pMediaFileUrl, QGraphicsItem *parent = 0); + + mediaType getMediaType() const { return mediaType_Video; } + + void setSize(int width, int height); + + virtual UBItem* deepCopy() const; + +public slots: + void videoSizeChanged(QSizeF newSize); + +protected: + + QGraphicsVideoItem *mVideoItem; +}; + + #endif // UBGRAPHICSMEDIAITEM_H diff --git a/src/domain/UBGraphicsMediaItemDelegate.cpp b/src/domain/UBGraphicsMediaItemDelegate.cpp index 8ad719ef..374c1336 100644 --- a/src/domain/UBGraphicsMediaItemDelegate.cpp +++ b/src/domain/UBGraphicsMediaItemDelegate.cpp @@ -43,42 +43,17 @@ #include "core/memcheck.h" -UBGraphicsMediaItemDelegate::UBGraphicsMediaItemDelegate(UBGraphicsMediaItem* pDelegated, QMediaPlayer* pMedia, QObject * parent) +UBGraphicsMediaItemDelegate::UBGraphicsMediaItemDelegate(UBGraphicsMediaItem* pDelegated, QObject * parent) : UBGraphicsItemDelegate(pDelegated, parent, GF_COMMON | GF_RESPECT_RATIO | GF_TOOLBAR_USED) , mPlayPauseButton(NULL) - , mMedia(pMedia) , mToolBarShowTimer(NULL) , m_iToolBarShowingInterval(5000) { QPalette palette; palette.setBrush ( QPalette::Light, Qt::darkGray ); - mMedia->setNotifyInterval(50); - - connect(mMedia, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), - this, SLOT(mediaStatusChanged(QMediaPlayer::MediaStatus))); - - connect(mMedia, SIGNAL(stateChanged(QMediaPlayer::State)), - this, SLOT(mediaStateChanged(QMediaPlayer::State))); - - connect(mMedia, static_cast<void(QMediaPlayer::*)(QMediaPlayer::Error)>(&QMediaPlayer::error), - this, &UBGraphicsMediaItemDelegate::mediaError); - - connect(mMedia, SIGNAL(positionChanged(qint64)), - this, SLOT(updateTicker(qint64))); - - connect(mMedia, SIGNAL(durationChanged(qint64)), - this, SLOT(totalTimeChanged(qint64))); - - if (delegated()->hasLinkedImage()) - { - mToolBarShowTimer = new QTimer(); - connect(mToolBarShowTimer, SIGNAL(timeout()), this, SLOT(hideToolBar())); - mToolBarShowTimer->setInterval(m_iToolBarShowingInterval); - } - if (delegated()->isMuted()) delegated()->setMute(true); @@ -110,7 +85,7 @@ void UBGraphicsMediaItemDelegate::buildButtons() mStopButton = new DelegateButton(":/images/stop.svg", mDelegated, mToolBarItem, Qt::TitleBarArea); connect(mStopButton, SIGNAL(clicked(bool)), - mMedia, SLOT(stop())); + delegated(), SLOT(stop())); mMediaControl = new DelegateMediaControl(delegated(), mToolBarItem); mMediaControl->setFlag(QGraphicsItem::ItemIsSelectable, true); @@ -132,8 +107,16 @@ void UBGraphicsMediaItemDelegate::buildButtons() mToolBarItem->setVisibleOnBoard(true); mToolBarItem->setShifting(false); - if (mToolBarShowTimer) - { + if (!mToolBarShowTimer) { + + if (delegated()->hasLinkedImage()) { + mToolBarShowTimer = new QTimer(); + connect(mToolBarShowTimer, SIGNAL(timeout()), this, SLOT(hideToolBar())); + mToolBarShowTimer->setInterval(m_iToolBarShowingInterval); + } + } + + else { connect(mPlayPauseButton, SIGNAL(clicked(bool)), mToolBarShowTimer, SLOT(start())); @@ -195,13 +178,15 @@ void UBGraphicsMediaItemDelegate::positionHandles() void UBGraphicsMediaItemDelegate::remove(bool canUndo) { - if (delegated() && delegated()->mediaObject()) - delegated()->mediaObject()->stop(); + if (delegated()) + delegated()->stop(); + /* if (delegated()->videoItem()) { UBGraphicsScene* scene = dynamic_cast<UBGraphicsScene*>(mDelegated->scene()); scene->removeItem(delegated()->videoItem()); } + */ UBGraphicsItemDelegate::remove(canUndo); } @@ -223,43 +208,8 @@ UBGraphicsMediaItem* UBGraphicsMediaItemDelegate::delegated() void UBGraphicsMediaItemDelegate::togglePlayPause() { - if (delegated() && delegated()->mediaObject()) { - - QMediaPlayer * media = delegated()->mediaObject(); - - if (media->state() == QMediaPlayer::StoppedState) - media->play(); - - else if (media->state() == QMediaPlayer::PlayingState) { - - if ((media->duration() - media->position()) <= 0) { - media->stop(); - media->play(); - } - - else { - media->pause(); - if(delegated()->scene()) - delegated()->scene()->setModified(true); - } - } - - else if (media->state() == QMediaPlayer::PausedState) { - if ((media->duration() - media->position()) <= 0) - media->stop(); - - media->play(); - } - - else if ( media->mediaStatus() == QMediaPlayer::LoadingMedia) { - delegated()->mediaObject()->setMedia(delegated()->mediaFileUrl()); - media->play(); - } - - if (media->error()) - qDebug() << "Error appeared." << media->errorString(); - - } + if (delegated()) + delegated()->togglePlayPause(); } void UBGraphicsMediaItemDelegate::mediaStatusChanged(QMediaPlayer::MediaStatus status) @@ -268,7 +218,7 @@ void UBGraphicsMediaItemDelegate::mediaStatusChanged(QMediaPlayer::MediaStatus s // StalledMedia, BufferingMedia, BufferedMedia, EndOfMedia, InvalidMedia if (status == QMediaPlayer::LoadedMedia) - mMediaControl->totalTimeChanged(delegated()->mediaObject()->duration()); + mMediaControl->totalTimeChanged(delegated()->mediaDuration()); // in most cases, the only necessary action is to update the play/pause state updatePlayPauseState(); @@ -288,15 +238,13 @@ void UBGraphicsMediaItemDelegate::mediaError(QMediaPlayer::Error error) // ServiceMissingError Q_UNUSED(error); - qDebug() << "Error appeared." << mMedia->errorString(); + qDebug() << "Error appeared.";// << mMedia->errorString(); } void UBGraphicsMediaItemDelegate::updatePlayPauseState() { - QMediaPlayer * media = delegated()->mediaObject(); - - if (media->state() == QMediaPlayer::PlayingState) + if (delegated()->playerState() == QMediaPlayer::PlayingState) mPlayPauseButton->setFileName(":/images/pause.svg"); else mPlayPauseButton->setFileName(":/images/play.svg"); @@ -305,8 +253,10 @@ void UBGraphicsMediaItemDelegate::updatePlayPauseState() void UBGraphicsMediaItemDelegate::updateTicker(qint64 time) { - QMediaPlayer* media = delegated()->mediaObject(); - mMediaControl->totalTimeChanged(media->duration()); + // TODO: duration() getter for UBGMediaItem + // make sure that all delegate()->mediaObject() calls are removed. 'tis dirty. + + mMediaControl->totalTimeChanged(delegated()->mediaDuration()); mMediaControl->updateTicker(time); } @@ -320,7 +270,7 @@ void UBGraphicsMediaItemDelegate::showHide(bool show) { QVariant showFlag = QVariant(show ? UBItemLayerType::Object : UBItemLayerType::Control); showHideRecurs(showFlag, mDelegated); - showHideRecurs(showFlag, delegated()->videoItem()); + // TODO: call showHideRecurs on the videoItem too (from UBGMI?) mDelegated->update(); emit showOnDisplayChanged(show); diff --git a/src/domain/UBGraphicsMediaItemDelegate.h b/src/domain/UBGraphicsMediaItemDelegate.h index 3031a738..f36c7343 100644 --- a/src/domain/UBGraphicsMediaItemDelegate.h +++ b/src/domain/UBGraphicsMediaItemDelegate.h @@ -43,7 +43,7 @@ class UBGraphicsMediaItemDelegate : public UBGraphicsItemDelegate Q_OBJECT public: - UBGraphicsMediaItemDelegate(UBGraphicsMediaItem* pDelegated, QMediaPlayer* pMedia, QObject * parent = 0); + UBGraphicsMediaItemDelegate(UBGraphicsMediaItem* pDelegated, QObject * parent = 0); virtual ~UBGraphicsMediaItemDelegate(); virtual void positionHandles(); @@ -56,6 +56,10 @@ class UBGraphicsMediaItemDelegate : public UBGraphicsItemDelegate void updateTicker(qint64 time); virtual void showHide(bool show); + void mediaStatusChanged(QMediaPlayer::MediaStatus status); + void mediaStateChanged(QMediaPlayer::State state); + void mediaError(QMediaPlayer::Error error); + protected slots: virtual void remove(bool canUndo = true); @@ -68,11 +72,6 @@ class UBGraphicsMediaItemDelegate : public UBGraphicsItemDelegate void hideToolBar(); - void mediaStatusChanged(QMediaPlayer::MediaStatus status); - - void mediaStateChanged(QMediaPlayer::State state); - - void mediaError(QMediaPlayer::Error error); protected: virtual void buildButtons(); @@ -84,8 +83,6 @@ class UBGraphicsMediaItemDelegate : public UBGraphicsItemDelegate DelegateButton* mMuteButton; DelegateMediaControl* mMediaControl; - QMediaPlayer* mMedia; // mMedia belongs to the associated UBGraphicsMediaItem (mDelegated) - QTimer* mToolBarShowTimer; int m_iToolBarShowingInterval; }; diff --git a/src/domain/UBGraphicsScene.cpp b/src/domain/UBGraphicsScene.cpp index ddb0a37a..5d86a2d0 100644 --- a/src/domain/UBGraphicsScene.cpp +++ b/src/domain/UBGraphicsScene.cpp @@ -1349,10 +1349,10 @@ UBGraphicsMediaItem* UBGraphicsScene::addMedia(const QUrl& pMediaFileUrl, bool s if (!QFile::exists(pMediaFileUrl.toString())) return NULL; - UBGraphicsMediaItem* mediaItem = new UBGraphicsMediaItem(pMediaFileUrl); - if(mediaItem){ + UBGraphicsMediaItem * mediaItem = UBGraphicsMediaItem::createMediaItem(pMediaFileUrl); + + if(mediaItem) connect(UBApplication::boardController, SIGNAL(activeSceneChanged()), mediaItem, SLOT(activeSceneChanged())); - } mediaItem->setPos(pPos); @@ -1361,11 +1361,6 @@ UBGraphicsMediaItem* UBGraphicsScene::addMedia(const QUrl& pMediaFileUrl, bool s addItem(mediaItem); - if (mediaItem->videoItem()) { - addItem(mediaItem->videoItem()); - mediaItem->videoItem()->show(); - } - mediaItem->show(); if (mUndoRedoStackEnabled) { //should be deleted after scene own undo stack implemented @@ -1373,12 +1368,11 @@ UBGraphicsMediaItem* UBGraphicsScene::addMedia(const QUrl& pMediaFileUrl, bool s UBApplication::undoStack->push(uc); } - mediaItem->mediaObject()->play(); + mediaItem->play(); - if (!shouldPlayAsap) - { - mediaItem->mediaObject()->pause(); - mediaItem->mediaObject()->setPosition(0); + if (!shouldPlayAsap) { + mediaItem->pause(); + mediaItem->setMediaPos(0); } setDocumentUpdated(); diff --git a/src/domain/UBGraphicsScene.h b/src/domain/UBGraphicsScene.h index 1734df7e..1d2ae889 100644 --- a/src/domain/UBGraphicsScene.h +++ b/src/domain/UBGraphicsScene.h @@ -40,8 +40,6 @@ class UBGraphicsProxyWidget; class UBGraphicsSvgItem; class UBGraphicsPolygonItem; class UBGraphicsMediaItem; -class UBGraphicsVideoItem; -class UBGraphicsAudioItem; class UBGraphicsWidgetItem; class UBGraphicsW3CWidgetItem; class UBGraphicsAppleWidgetItem; -- 2.18.1