From d7a6993a720e685d921bbf9d715789307e79effe Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Mon, 26 Oct 2009 21:01:48 +0000 Subject: [PATCH] improve overwrite mode with transitions svn path=/trunk/kdenlive/; revision=4065 --- src/abstractclipitem.cpp | 5 +++ src/abstractclipitem.h | 1 + src/abstractgroupitem.cpp | 14 ++++---- src/clipitem.cpp | 36 ++++++++++++--------- src/customtrackview.cpp | 68 +++++++++++++++++++++++++++++++++------ src/customtrackview.h | 1 + src/transition.cpp | 5 +++ src/transition.h | 1 + 8 files changed, 101 insertions(+), 30 deletions(-) diff --git a/src/abstractclipitem.cpp b/src/abstractclipitem.cpp index 5159c04d..c3149852 100644 --- a/src/abstractclipitem.cpp +++ b/src/abstractclipitem.cpp @@ -52,6 +52,11 @@ ItemInfo AbstractClipItem::info() const return info; } +int AbstractClipItem::defaultZValue() const +{ + return 2; +} + GenTime AbstractClipItem::endPos() const { return m_info.startPos + m_info.cropDuration; diff --git a/src/abstractclipitem.h b/src/abstractclipitem.h index eb07f21e..09fd98d4 100644 --- a/src/abstractclipitem.h +++ b/src/abstractclipitem.h @@ -51,6 +51,7 @@ public: virtual GenTime startPos() const ; virtual void setTrack(int track); virtual GenTime endPos() const ; + virtual int defaultZValue() const ; virtual int track() const ; virtual GenTime cropStart() const ; virtual GenTime cropDuration() const ; diff --git a/src/abstractgroupitem.cpp b/src/abstractgroupitem.cpp index 35733c10..788e015b 100644 --- a/src/abstractgroupitem.cpp +++ b/src/abstractgroupitem.cpp @@ -198,9 +198,10 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant return QPointF(pos().x() - start.x(), pos().y()); }*/ - QPainterPath shape = clipGroupShape(newPos - pos()); QList collindingItems; + QPainterPath shape; if (projectScene()->editMode() == NORMALEDIT) { + shape = clipGroupShape(newPos - pos()); collindingItems = scene()->items(shape, Qt::IntersectsItemShape); for (int i = 0; i < children.count(); i++) { collindingItems.removeAll(children.at(i)); @@ -249,11 +250,12 @@ QVariant AbstractGroupItem::itemChange(GraphicsItemChange change, const QVariant } } - - shape = transitionGroupShape(newPos - pos()); - collindingItems = scene()->items(shape, Qt::IntersectsItemShape); - for (int i = 0; i < children.count(); i++) { - collindingItems.removeAll(children.at(i)); + if (projectScene()->editMode() == NORMALEDIT) { + shape = transitionGroupShape(newPos - pos()); + collindingItems = scene()->items(shape, Qt::IntersectsItemShape); + for (int i = 0; i < children.count(); i++) { + collindingItems.removeAll(children.at(i)); + } } if (collindingItems.isEmpty()) return newPos; else { diff --git a/src/clipitem.cpp b/src/clipitem.cpp index 92f9b565..e7fa498a 100644 --- a/src/clipitem.cpp +++ b/src/clipitem.cpp @@ -68,16 +68,16 @@ ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, i m_videoPix = KIcon("kdenlive-show-video").pixmap(QSize(16, 16)); m_audioPix = KIcon("kdenlive-show-audio").pixmap(QSize(16, 16)); - if (m_speed == 1.0) m_clipName = clip->name(); + if (m_speed == 1.0) m_clipName = m_clip->name(); else { - m_clipName = clip->name() + " - " + QString::number(m_speed * 100, 'f', 0) + '%'; + m_clipName = m_clip->name() + " - " + QString::number(m_speed * 100, 'f', 0) + '%'; } - m_producer = clip->getId(); - m_clipType = clip->clipType(); + m_producer = m_clip->getId(); + m_clipType = m_clip->clipType(); //m_cropStart = info.cropStart; - m_maxDuration = clip->maxDuration(); + m_maxDuration = m_clip->maxDuration(); setAcceptDrops(true); - m_audioThumbReady = clip->audioThumbCreated(); + m_audioThumbReady = m_clip->audioThumbCreated(); //setAcceptsHoverEvents(true); connect(this , SIGNAL(prepareAudioThumb(double, int, int, int)) , this, SLOT(slotPrepareAudioThumb(double, int, int, int))); @@ -89,11 +89,11 @@ ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, i m_endThumbTimer.setSingleShot(true); connect(&m_endThumbTimer, SIGNAL(timeout()), this, SLOT(slotGetEndThumb())); - connect(this, SIGNAL(getThumb(int, int)), clip->thumbProducer(), SLOT(extractImage(int, int))); + connect(this, SIGNAL(getThumb(int, int)), m_clip->thumbProducer(), SLOT(extractImage(int, int))); //connect(this, SIGNAL(getThumb(int, int)), clip->thumbProducer(), SLOT(getVideoThumbs(int, int))); - connect(clip->thumbProducer(), SIGNAL(thumbReady(int, QImage)), this, SLOT(slotThumbReady(int, QImage))); - connect(clip, SIGNAL(gotAudioData()), this, SLOT(slotGotAudioData())); + connect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QImage)), this, SLOT(slotThumbReady(int, QImage))); + connect(m_clip, SIGNAL(gotAudioData()), this, SLOT(slotGotAudioData())); if (generateThumbs) QTimer::singleShot(200, this, SLOT(slotFetchThumbs())); /*if (m_clip->producer()) { @@ -101,19 +101,19 @@ ClipItem::ClipItem(DocClipBase *clip, ItemInfo info, double fps, double speed, i slotFetchThumbs(); }*/ } else if (m_clipType == COLOR) { - QString colour = clip->getProperty("colour"); + QString colour = m_clip->getProperty("colour"); colour = colour.replace(0, 2, "#"); m_baseColor = QColor(colour.left(7)); } else if (m_clipType == IMAGE || m_clipType == TEXT) { m_baseColor = QColor(141, 166, 215); if (m_clipType == TEXT) { - connect(this, SIGNAL(getThumb(int, int)), clip->thumbProducer(), SLOT(extractImage(int, int))); - connect(clip->thumbProducer(), SIGNAL(thumbReady(int, QImage)), this, SLOT(slotThumbReady(int, QImage))); + connect(this, SIGNAL(getThumb(int, int)), m_clip->thumbProducer(), SLOT(extractImage(int, int))); + connect(m_clip->thumbProducer(), SIGNAL(thumbReady(int, QImage)), this, SLOT(slotThumbReady(int, QImage))); } //m_startPix = KThumb::getImage(KUrl(clip->getProperty("resource")), (int)(KdenliveSettings::trackheight() * KdenliveSettings::project_display_ratio()), KdenliveSettings::trackheight()); } else if (m_clipType == AUDIO) { m_baseColor = QColor(141, 215, 166); - connect(clip, SIGNAL(gotAudioData()), this, SLOT(slotGotAudioData())); + connect(m_clip, SIGNAL(gotAudioData()), this, SLOT(slotGotAudioData())); } } @@ -132,7 +132,7 @@ ClipItem *ClipItem::clone(ItemInfo info) const { ClipItem *duplicate = new ClipItem(m_clip, info, m_fps, m_speed, m_strobe); if (m_clipType == IMAGE || m_clipType == TEXT) duplicate->slotSetStartThumb(m_startPix); - else { + else if (m_clipType != COLOR) { if (info.cropStart == m_info.cropStart) duplicate->slotSetStartThumb(m_startPix); if (info.cropStart + (info.endPos - info.startPos) == m_info.cropStart + (m_info.endPos - m_info.startPos)) duplicate->slotSetEndThumb(m_endPix); } @@ -1585,7 +1585,13 @@ void ClipItem::setAudioOnly(bool force) { m_audioOnly = force; if (m_audioOnly) m_baseColor = QColor(141, 215, 166); - else m_baseColor = QColor(141, 166, 215); + else { + if (m_clipType == COLOR) { + QString colour = m_clip->getProperty("colour"); + colour = colour.replace(0, 2, "#"); + m_baseColor = QColor(colour.left(7)); + } else m_baseColor = QColor(141, 166, 215); + } m_audioThumbCachePic.clear(); } diff --git a/src/customtrackview.cpp b/src/customtrackview.cpp index 3d4751e1..79b36521 100644 --- a/src/customtrackview.cpp +++ b/src/customtrackview.cpp @@ -2000,7 +2000,7 @@ void CustomTrackView::dropEvent(QDropEvent * event) //TODO: take care of edit mode for undo item->baseClip()->addReference(); - item->setZValue(2); + item->setZValue(item->defaultZValue()); m_document->updateClip(item->baseClip()->getId()); ItemInfo info = item->info(); @@ -2085,6 +2085,41 @@ void CustomTrackView::adjustTimelineClips(EDITMODE mode, AbstractClipItem *item, } +void CustomTrackView::adjustTimelineTransitions(EDITMODE mode, Transition *item, QUndoCommand *command) +{ + if (mode == OVERWRITEEDIT) { + // if we are in overwrite or push mode, move clips accordingly + ItemInfo info = item->info(); + QRectF rect(info.startPos.frames(m_document->fps()), info.track * m_tracksHeight + m_tracksHeight, (info.endPos - info.startPos).frames(m_document->fps()) - 1, 5); + QList selection = m_scene->items(rect); + selection.removeAll(item); + for (int i = 0; i < selection.count(); i++) { + if (selection.at(i)->type() == TRANSITIONWIDGET) { + Transition *tr = static_cast(selection.at(i)); + if (tr->startPos() < info.startPos) { + ItemInfo firstPos = tr->info(); + ItemInfo newPos = firstPos; + firstPos.endPos = item->startPos(); + newPos.startPos = item->endPos(); + new MoveTransitionCommand(this, tr->info(), firstPos, true, command); + if (tr->endPos() > info.endPos) { + // clone transition + new AddTransitionCommand(this, newPos, tr->transitionEndTrack(), tr->toXML(), false, true, command); + } + } else if (tr->endPos() > info.endPos) { + // just resize + ItemInfo firstPos = tr->info(); + firstPos.startPos = item->endPos(); + new MoveTransitionCommand(this, tr->info(), firstPos, true, command); + } else { + // remove transition + new AddTransitionCommand(this, tr->info(), tr->transitionEndTrack(), tr->toXML(), true, true, command); + } + } + } + } +} + QStringList CustomTrackView::mimeTypes() const { QStringList qstrList; @@ -2674,8 +2709,8 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) if (m_operationMode == MOVE) { setCursor(Qt::OpenHandCursor); - if (m_dragItem) m_dragItem->setZValue(2); - if (m_selectionGroup) m_selectionGroup->setZValue(2); + if (m_dragItem) m_dragItem->setZValue(m_dragItem->defaultZValue()); + if (m_selectionGroup) m_selectionGroup->setZValue(1); if (m_dragItem->parentItem() == 0) { // we are moving one clip, easy if (m_dragItem->type() == AVWIDGET && (m_dragItemInfo.startPos != info.startPos || m_dragItemInfo.track != info.track)) { @@ -2734,6 +2769,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) // we have to move both transitions, remove the start one so that there is no collision new AddTransitionCommand(this, startTrInfo, startTransition->transitionEndTrack(), startTransition->toXML(), true, true, moveCommand); } + adjustTimelineTransitions(m_scene->editMode(), tr, moveCommand); new MoveTransitionCommand(this, trInfo, newTrInfo, true, moveCommand); if (moveStartTrans) { // re-add transition in correct place @@ -2741,13 +2777,17 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) if (m_dragItemInfo.track != info.track && !startTransition->forcedTrack()) { transTrack = getPreviousVideoTrack(info.track); } + adjustTimelineTransitions(m_scene->editMode(), startTransition, moveCommand); new AddTransitionCommand(this, newStartTrInfo, transTrack, startTransition->toXML(), false, true, moveCommand); } } } } - if (moveStartTrans && !moveEndTrans) new MoveTransitionCommand(this, startTrInfo, newStartTrInfo, true, moveCommand); + if (moveStartTrans && !moveEndTrans) { + adjustTimelineTransitions(m_scene->editMode(), startTransition, moveCommand); + new MoveTransitionCommand(this, startTrInfo, newStartTrInfo, true, moveCommand); + } // Also move automatic transitions (on upper track) Transition *tr = getTransitionItemAtStart(m_dragItemInfo.startPos, m_dragItemInfo.track - 1); @@ -2761,7 +2801,10 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) // transition end should be adjusted to clip on upper track newTrInfo.endPos = newTrInfo.endPos + (newTrInfo.startPos - trInfo.startPos); } - if (newTrInfo.startPos < newTrInfo.endPos) new MoveTransitionCommand(this, trInfo, newTrInfo, true, moveCommand); + if (newTrInfo.startPos < newTrInfo.endPos) { + adjustTimelineTransitions(m_scene->editMode(), tr, moveCommand); + new MoveTransitionCommand(this, trInfo, newTrInfo, true, moveCommand); + } } } if (m_dragItemInfo.track == info.track && (tr == NULL || tr->endPos() < m_dragItemInfo.endPos)) { @@ -2779,7 +2822,10 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) // transition start should be moved newTrInfo.startPos = newTrInfo.startPos + (newTrInfo.endPos - trInfo.endPos); } - if (newTrInfo.startPos < newTrInfo.endPos) new MoveTransitionCommand(this, trInfo, newTrInfo, true, moveCommand); + if (newTrInfo.startPos < newTrInfo.endPos) { + adjustTimelineTransitions(m_scene->editMode(), tr, moveCommand); + new MoveTransitionCommand(this, trInfo, newTrInfo, true, moveCommand); + } } } } @@ -2802,8 +2848,11 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) emit displayMessage(i18n("Cannot move transition"), ErrorMessage); transition->setPos((int) m_dragItemInfo.startPos.frames(m_document->fps()), (m_dragItemInfo.track) * m_tracksHeight + 1); } else { - MoveTransitionCommand *command = new MoveTransitionCommand(this, m_dragItemInfo, info, false); - m_commandStack->push(command); + QUndoCommand *moveCommand = new QUndoCommand(); + moveCommand->setText(i18n("Move transition")); + adjustTimelineTransitions(m_scene->editMode(), transition, moveCommand); + new MoveTransitionCommand(this, m_dragItemInfo, info, false, moveCommand); + m_commandStack->push(moveCommand); } } } else { @@ -2854,7 +2903,6 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) if (items.at(i)->type() != AVWIDGET && items.at(i)->type() != TRANSITIONWIDGET) continue; AbstractClipItem *item = static_cast (items.at(i)); item->updateItem(); - adjustTimelineClips(m_scene->editMode(), item, moveGroup); ItemInfo info = item->info(); int tracknumber = m_document->tracksCount() - info.track - 1; bool isLocked = m_document->trackInfoAt(tracknumber).isLocked; @@ -2867,6 +2915,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) ClipItem *clip = static_cast (item); info.track = m_document->tracksCount() - info.track; Mlt::Producer *prod; + adjustTimelineClips(m_scene->editMode(), item, moveGroup); if (clip->isAudioOnly()) prod = clip->baseClip()->audioProducer(info.track); else if (clip->isVideoOnly()) prod = clip->baseClip()->videoProducer(); else prod = clip->baseClip()->producer(info.track); @@ -2881,6 +2930,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event) newTrack = getPreviousVideoTrack(info.track); } tr->updateTransitionEndTrack(newTrack); + adjustTimelineTransitions(m_scene->editMode(), tr, moveGroup); m_document->renderer()->mltAddTransition(tr->transitionTag(), newTrack, m_document->tracksCount() - info.track, info.startPos, info.endPos, tr->toXML()); } } diff --git a/src/customtrackview.h b/src/customtrackview.h index 1bbe77f2..b45e283a 100644 --- a/src/customtrackview.h +++ b/src/customtrackview.h @@ -267,6 +267,7 @@ private: QList checkForGroups(const QRectF &rect, bool *ok); /** Adjust clips under another one when working in overwrite mode */ void adjustTimelineClips(EDITMODE mode, AbstractClipItem *item, QUndoCommand *command); + void adjustTimelineTransitions(EDITMODE mode, Transition *item, QUndoCommand *command); private slots: void slotRefreshGuides(); diff --git a/src/transition.cpp b/src/transition.cpp index a4700c8b..faca57f4 100644 --- a/src/transition.cpp +++ b/src/transition.cpp @@ -316,3 +316,8 @@ bool Transition::hasGeometry() return false; } +int Transition::defaultZValue() const +{ + return 3; +} + diff --git a/src/transition.h b/src/transition.h index 088fa15a..8009efdd 100644 --- a/src/transition.h +++ b/src/transition.h @@ -72,6 +72,7 @@ public: bool isAutomatic() const; void setAutomatic(bool automatic); bool hasGeometry(); + int defaultZValue() const; protected: virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); -- 2.39.2