Commit 5b7908a7 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Updates for rolling trim: fix split view sometimes not working.

Rolling cut now follows timeline cursor so you can use all timeline shortcuts to move it
Ref: T1953
parent a805630d
......@@ -7,20 +7,89 @@ Item {
// default size, but scalable by user
height: 300; width: 400
signal doAcceptRipple(bool doAccept)
signal switchTrimMode(int mode)
property int displayFontSize
property int trimmode
Rectangle {
id: info
x: root.x
y: root.height / 2
width: root.width
width: root.width / 4
height: root.displayFontSize * 2
color: "darkBlue"
border.width: 1
color: trimmode == 1 ? "darkRed" : "darkBlue"
Text {
text: 'Ripple'
color: "white"
anchors.centerIn: parent
}
MouseArea {
hoverEnabled: true
anchors.fill: info
cursorShape: Qt.PointingHandCursor
onClicked: { root.switchTrimMode(1);}
}
}
Rectangle {
id: info2
x: info.width
y: info.y
width: info.width
height: info.height
border.width: 1
color: trimmode == 2 ? "darkRed" : "darkBlue"
Text {
text: 'Rolling Mode'
text: 'Rolling'
color: "white"
anchors.centerIn: parent
}
MouseArea {
hoverEnabled: true
anchors.fill: info2
cursorShape: Qt.PointingHandCursor
onClicked: { root.switchTrimMode(2);}
}
}
Rectangle {
id: info3
x: info.width * 2
y: info.y
width: info.width
height: info.height
border.width: 1
color: trimmode == 3 ? "darkRed" : "darkBlue"
Text {
text: 'Slip'
color: "white"
anchors.centerIn: parent
}
MouseArea {
hoverEnabled: true
anchors.fill: info3
cursorShape: Qt.PointingHandCursor
onClicked: { root.switchTrimMode(3);}
}
}
Rectangle {
id: info4
x: info.width * 3
y: info.y
width: info.width
height: info.height
border.width: 1
color: trimmode == 4 ? "darkRed" : "darkBlue"
Text {
text: 'Slide'
color: "white"
anchors.centerIn: parent
}
MouseArea {
hoverEnabled: true
anchors.fill: info4
cursorShape: Qt.PointingHandCursor
onClicked: { root.switchTrimMode(4);}
}
}
MouseArea {
......
......@@ -1874,7 +1874,9 @@ void MainWindow::connectDocument()
connect(project, SIGNAL(docModified(bool)), this, SLOT(slotUpdateDocumentState(bool)));
connect(trackView->projectView(), SIGNAL(guidesUpdated()), this, SLOT(slotGuidesUpdated()));
connect(trackView->projectView(), SIGNAL(loadMonitorScene(MonitorSceneType,bool)), m_projectMonitor, SLOT(slotShowEffectScene(MonitorSceneType,bool)));
connect(trackView->projectView(), &CustomTrackView::setQmlProperty, m_projectMonitor, &Monitor::setQmlProperty);
connect(m_projectMonitor, SIGNAL(acceptRipple(bool)), trackView->projectView(), SLOT(slotAcceptRipple(bool)));
connect(m_projectMonitor, SIGNAL(switchTrimMode(int)), trackView->projectView(), SLOT(switchTrimMode(int)));
connect(project, SIGNAL(saveTimelinePreview(QString)), trackView, SLOT(slotSaveTimelinePreview(QString)));
connect(trackView, SIGNAL(showTrackEffects(int,TrackInfo)), this, SLOT(slotTrackSelected(int,TrackInfo)));
......@@ -1887,6 +1889,7 @@ void MainWindow::connectDocument()
connect(trackView->projectView(), SIGNAL(zoomIn()), this, SLOT(slotZoomIn()));
connect(trackView->projectView(), SIGNAL(zoomOut()), this, SLOT(slotZoomOut()));
connect(trackView, SIGNAL(setZoom(int)), this, SLOT(slotSetZoom(int)));
connect(trackView, SIGNAL(displayMessage(QString,MessageType)), m_messageLabel, SLOT(setMessage(QString,MessageType)));
connect(trackView->projectView(), SIGNAL(displayMessage(QString,MessageType)), m_messageLabel, SLOT(setMessage(QString,MessageType)));
connect(pCore->bin(), SIGNAL(clipNameChanged(QString)), trackView->projectView(), SLOT(clipNameChanged(QString)));
connect(pCore->bin(), SIGNAL(displayMessage(QString,int,MessageType)), m_messageLabel, SLOT(setProgressMessage(QString,int,MessageType)));
......
......@@ -1844,6 +1844,7 @@ void Monitor::loadQmlScene(MonitorSceneType type)
break;
case MonitorSceneRipple:
QObject::connect(root, SIGNAL(doAcceptRipple(bool)), this, SIGNAL(acceptRipple(bool)), Qt::UniqueConnection);
QObject::connect(root, SIGNAL(switchTrimMode(int)), this, SIGNAL(switchTrimMode(int)), Qt::UniqueConnection);
break;
case MonitorSceneDefault:
QObject::connect(root, SIGNAL(editCurrentMarker()), this, SLOT(slotEditInlineMarker()), Qt::UniqueConnection);
......
......@@ -362,6 +362,7 @@ signals:
void createSplitOverlay(Mlt::Filter *);
void removeSplitOverlay();
void acceptRipple(bool);
void switchTrimMode(int);
};
#endif
......@@ -221,29 +221,6 @@ void CustomTrackView::keyPressEvent(QKeyEvent * event)
slotTrackDown();
event->accept();
break;
case Qt::Key_Left:
case Qt::Key_Right:
if (event->modifiers() == Qt::ControlModifier) {
if (m_dragItem == NULL || m_dragItem->type() != AVWidget) {
QGraphicsView::keyPressEvent(event);
return;
}
// Enter rolling
int diffStart = qAbs(m_cursorPos - m_dragItem->startPos().frames(m_document->fps()));
int diffEnd = qAbs(m_cursorPos - m_dragItem->endPos().frames(m_document->fps()));
TrimManager *mgr = qobject_cast<TrimManager *>(m_toolManagers.value(TrimType));
if (m_moveOpMode == RollingEnd || m_moveOpMode == RollingStart) {
// Already in trim mode, move
mgr->moveRoll(event->key() == Qt::Key_Right);
} else {
// init trim
mgr->enterTrimMode(m_dragItem->info(), diffStart < diffEnd);
}
setFocus();
event->accept();
return;
}
break;
default:
break;
}
......@@ -2240,7 +2217,7 @@ bool CustomTrackView::createSplitOverlay(Mlt::Filter *filter)
return m_timeline->createOverlay(filter, m_dragItem->track(), m_dragItem->startPos().frames(m_document->fps()));
}
void CustomTrackView::rippleMode(bool enable)
void CustomTrackView::trimMode(bool enable)
{
if (!enable) {
m_timeline->removeSplitOverlay();
......@@ -2259,8 +2236,8 @@ void CustomTrackView::rippleMode(bool enable)
m_moveOpMode = RollingStart;
}
int ripplePos = m_moveOpMode == RollingStart ? m_dragItem->startPos().frames(m_document->fps()) : m_dragItem->endPos().frames(m_document->fps());
qDebug()<<" * **STARTING RIPPLE MODE: "<<ripplePos;
if (m_timeline->createRippleWindow(m_dragItem->track(), ripplePos)) {
emit loadMonitorScene(MonitorSceneRipple, true);
monitorRefresh();
}
}
......@@ -4129,6 +4106,10 @@ void CustomTrackView::setCursorPos(int pos)
{
if (pos != m_cursorPos) {
emit cursorMoved(m_cursorPos, pos);
if (m_moveOpMode == RollingStart || m_moveOpMode == RollingEnd) {
TrimManager *mgr = qobject_cast<TrimManager *>(m_toolManagers.value(TrimType));
mgr->moveRoll(pos > m_cursorPos, pos);
}
m_cursorPos = pos;
m_cursorLine->setPos(m_cursorPos + m_cursorOffset, 0);
if (m_autoScroll) checkScrolling();
......@@ -8670,13 +8651,20 @@ void CustomTrackView::sortGuides()
qSort(m_guides.begin(), m_guides.end(), sortGuidesList);
}
void CustomTrackView::switchTrimMode()
void CustomTrackView::switchTrimMode(int mode)
{
switchTrimMode((TrimMode) mode);
}
void CustomTrackView::switchTrimMode(TrimMode mode)
{
TrimManager *mgr = qobject_cast<TrimManager *>(m_toolManagers.value(TrimType));
TrimMode mode = (TrimMode) (((int) mgr->trimMode() + 1) %5);
if (mode == NormalTrim) {
mode = (TrimMode) (qMax(((int) mgr->trimMode() + 1) %5, 1));
}
// Find best clip to trim
ItemInfo info;
//TODO: if cursor is not on a cut, switch only between splip and slide
//TODO: if cursor is not on a cut, switch only between slip and slide
AbstractClipItem *trimItem = NULL;
if (m_dragItem && m_dragItem->type() == AVWidget) {
trimItem = m_dragItem;
......
......@@ -267,7 +267,7 @@ public:
void switchAllTrackLock();
/** @brief Insert space in timeline. track = -1 means all tracks */
void insertTimelineSpace(GenTime startPos, GenTime duration, int track = -1, QList <ItemInfo> excludeList = QList <ItemInfo>());
void rippleMode(bool enable);
void trimMode(bool enable);
/** @brief Returns a clip from timeline
* @param pos the end time position
* @param track the track where the clip is in MLT coordinates */
......@@ -326,7 +326,7 @@ public:
void sortGuides();
void initTools();
/** @brief Cycle through timeline trim modes, returns label text for trim mode */
void switchTrimMode();
void switchTrimMode(TrimMode mode = NormalTrim);
public slots:
/** @brief Send seek request to MLT. */
......@@ -411,6 +411,7 @@ public slots:
void extractZone(QPoint z, bool closeGap, QList <ItemInfo> excludedClips = QList <ItemInfo>(), QUndoCommand *masterCommand = NULL, int track = -1);
/** @brief Select an item in timeline. */
void slotSelectItem(AbstractClipItem *item);
void switchTrimMode(int mode);
protected:
virtual void drawBackground(QPainter * painter, const QRectF & rect);
......@@ -629,6 +630,7 @@ signals:
void setActiveKeyframe(int);
void loadMonitorScene(MonitorSceneType,bool);
void updateTrimMode(const QString mode = QString());
void setQmlProperty(const QString&, const QVariant&);
};
#endif
......
......@@ -62,51 +62,60 @@ void TrimManager::mouseRelease(GenTime)
bool TrimManager::enterTrimMode(ItemInfo info, bool trimStart)
{
if (trimStart) {
m_firstClip = m_view->getClipItemAtEnd(info.startPos, info.track);
m_secondClip = m_view->getClipItemAtStart(info.startPos, info.track);
} else {
m_firstClip = m_view->getClipItemAtEnd(info.endPos, info.track);
m_secondClip = m_view->getClipItemAtStart(info.endPos, info.track);
}
if (!m_firstClip || !m_secondClip) {
m_view->setOperationMode(None);
m_firstInfo = ItemInfo();
m_secondInfo = ItemInfo();
return false;
}
AbstractClipItem *dragItem = m_view->dragItem();
AbstractGroupItem *selectionGroup = m_view->selectionGroup();
if (selectionGroup) {
m_view->resetSelectionGroup(false);
dragItem->setSelected(true);
}
m_view->setOperationMode(trimStart ? RollingStart : RollingEnd);
m_firstInfo = m_firstClip->info();
m_secondInfo = m_secondClip->info();
m_view->rippleMode(true);
m_view->loadMonitorScene(MonitorSceneRipple, true);
m_view->seekCursorPos(trimStart ? info.startPos.frames(m_view->fps()) : info.endPos.frames(m_view->fps()));
m_view->setQmlProperty(QStringLiteral("trimmode"), (int) m_trimMode);
if (m_trimMode == RollingTrim) {
if (trimStart) {
m_firstClip = m_view->getClipItemAtEnd(info.startPos, info.track);
m_secondClip = m_view->getClipItemAtStart(info.startPos, info.track);
} else {
m_firstClip = m_view->getClipItemAtEnd(info.endPos, info.track);
m_secondClip = m_view->getClipItemAtStart(info.endPos, info.track);
}
if (!m_firstClip || !m_secondClip) {
m_view->displayMessage(i18n("Could not find necessary clips to perform rolling trim"), InformationMessage);
m_view->setOperationMode(None);
m_firstInfo = ItemInfo();
m_secondInfo = ItemInfo();
return false;
}
AbstractClipItem *dragItem = m_view->dragItem();
AbstractGroupItem *selectionGroup = m_view->selectionGroup();
if (selectionGroup) {
m_view->resetSelectionGroup(false);
dragItem->setSelected(true);
}
m_view->setOperationMode(trimStart ? RollingStart : RollingEnd);
m_firstInfo = m_firstClip->info();
m_secondInfo = m_secondClip->info();
m_view->trimMode(true);
m_view->seekCursorPos(trimStart ? info.startPos.frames(m_view->fps()) : info.endPos.frames(m_view->fps()));
return true;
}
return true;
}
void TrimManager::moveRoll(bool forward)
void TrimManager::moveRoll(bool forward, int pos)
{
if (!m_firstInfo.isValid() || !m_secondInfo.isValid())
return;
int pos = m_firstClip->endPos().frames(m_view->fps());
if (pos == -1) {
pos = m_firstClip->endPos().frames(m_view->fps());
if (forward)
pos++;
else
pos--;
}
bool snap = KdenliveSettings::snaptopoints();
KdenliveSettings::setSnaptopoints(false);
if (forward) {
pos++;
m_secondClip->resizeStart(pos, true, false);
m_firstClip->resizeEnd(pos, false);
} else {
pos--;
m_firstClip->resizeEnd(pos, false);
m_secondClip->resizeStart(pos, true, false);
}
m_view->seekCursorPos(pos);
//m_view->seekCursorPos(pos);
KdenliveSettings::setSnaptopoints(snap);
}
......@@ -114,7 +123,7 @@ void TrimManager::endRoll()
{
if (!m_firstInfo.isValid() || !m_secondInfo.isValid())
return;
m_view->rippleMode(false);
m_view->trimMode(false);
QUndoCommand *command = new QUndoCommand;
command->setText(i18n("Rolling Edit"));
if (m_firstClip->endPos() < m_firstInfo.endPos) {
......
......@@ -39,7 +39,7 @@ public:
void mouseMove(int pos);
void mouseRelease(GenTime pos = GenTime());
bool enterTrimMode(ItemInfo info, bool trimStart);
void moveRoll(bool forward);
void moveRoll(bool forward, int pos = -1);
void setTrimMode(TrimMode mode, ItemInfo info = ItemInfo(), bool fromStart = true);
TrimMode trimMode() const;
......
......@@ -1724,13 +1724,14 @@ bool Timeline::createRippleWindow(int tk, int startPos)
}
Mlt::Producer *firstClip = playlist.get_clip(clipIndex - 1);
Mlt::Producer *secondClip = playlist.get_clip(clipIndex);
qDebug()<<"** TRIM ON TK: "<<tk<<", POS: "<<startPos;
if (!firstClip || !firstClip->is_valid()) {
m_tractor->unlock();
emit displayMessage(i18n("Cannot find first clip to perform ripple trim"), ErrorMessage);
return false;
}
if (!secondClip || !secondClip->is_valid()) {
m_tractor->unlock();
emit displayMessage(i18n("Cannot find second clip to perform ripple trim"), ErrorMessage);
return false;
}
// Create duplicate of second clip
......@@ -1746,10 +1747,16 @@ bool Timeline::createRippleWindow(int tk, int startPos)
Mlt::Filter f1(*m_tractor->profile(), "affine");
f1.set("transition.geometry", "50% 0 50% 50%");
f1.set("transition.always_active", 1);
cln2->attach(f1);
Mlt::Playlist ripple1(*m_tractor->profile());
ripple1.insert_blank(0, secondStart);
if (secondStart < 0) {
cln2->set_in_and_out(-secondStart, -1);
secondStart = 0;
}
if (secondStart > 0)
ripple1.insert_blank(0, secondStart);
ripple1.insert_at(secondStart, cln2, 1);
Mlt::Playlist ripple2(*m_tractor->profile());
ripple2.insert_blank(0, rippleStart);
......
......@@ -293,6 +293,7 @@ signals:
void loadingBin(int);
/** @brief We are about to reload timeline, reset bin clip usage */
void resetUsageCount();
void displayMessage(const QString &, MessageType);
};
#endif
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment