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

Implement moving left clip in a mix transition

parent 5d1a81b6
......@@ -612,21 +612,25 @@ bool TimelineModel::requestClipMove(int clipId, int trackId, int position, bool
Fun move_mix = []() { return true; };
Fun restore_mix = []() { return true; };
Fun update_mix = []() { return true; };
Fun move_mix_end = []() { return true; };
Fun restore_mix_end = []() { return true; };
Fun update_mix_end = []() { return true; };
if (isTrack(old_trackId) && getTrackById_const(old_trackId)->hasMix(clipId)) {
std::pair<MixInfo, MixInfo> mixData = getTrackById_const(old_trackId)->getMixInfo(clipId);
if (mixData.first.firstClipId > -1) {
// We have a mix at clip start
update_mix = [this, mixData]() {
QModelIndex ix = makeClipIndexFromID(mixData.first.secondClipId);
emit dataChanged(ix, ix, {TimelineModel::StartRole,TimelineModel::MixRole});
return true;
};
// We have a mix at clip start
if (old_trackId != trackId || position >= mixData.first.firstClipInOut.second) {
// Clip moved to another track, or outside of mix duration, delete mix
int subPlaylist = m_allClips[clipId]->getSubPlaylistIndex();
move_mix = [this, old_trackId, clipId, finalMove, subPlaylist]() {
bool result = getTrackById_const(old_trackId)->deleteMix(clipId, finalMove);
if (finalMove) {
//TODO: check if there is another mix on this clip
m_allClips[clipId]->setSubPlaylistIndex(subPlaylist == 0 ? 1 : 0);
}
return result;
......@@ -649,8 +653,47 @@ bool TimelineModel::requestClipMove(int clipId, int trackId, int position, bool
};
}
}
if (mixData.second.firstClipId > -1) {
// We have a mix at clip end
update_mix_end = [this, mixData]() {
QModelIndex ix = makeClipIndexFromID(mixData.second.secondClipId);
emit dataChanged(ix, ix, {TimelineModel::StartRole,TimelineModel::MixRole});
return true;
};
int clipDuration = mixData.second.firstClipInOut.second - mixData.second.firstClipInOut.first;
if (old_trackId != trackId || (position + clipDuration <= mixData.second.secondClipInOut.first)) {
// Clip moved to another track, or outside of mix duration, delete mix
int subPlaylist = m_allClips[mixData.second.secondClipId]->getSubPlaylistIndex();
move_mix_end = [this, old_trackId, mixData, finalMove, subPlaylist]() {
bool result = getTrackById_const(old_trackId)->deleteMix(mixData.second.secondClipId, finalMove);
if (finalMove) {
//TODO: check if there is another mix on this clip
m_allClips[mixData.second.secondClipId]->setSubPlaylistIndex(subPlaylist == 0 ? 1 : 0);
}
return result;
};
restore_mix_end = [this, old_trackId, mixData, finalMove, subPlaylist]() {
if (finalMove) {
m_allClips[mixData.second.secondClipId]->setSubPlaylistIndex(subPlaylist);
}
bool result = getTrackById_const(old_trackId)->createMix({mixData.second.firstClipId,mixData.second.secondClipId}, {mixData.second.secondClipInOut.first, mixData.second.firstClipInOut.second - mixData.second.secondClipInOut.first});
return result;
};
} else if (old_trackId == trackId) {
// Clip moved on same track, resize mix
move_mix_end = [this, old_trackId, mixData, position, clipDuration]() {
return getTrackById_const(old_trackId)->resizeMixEnd(mixData.second.secondClipId, position + clipDuration);
};
restore_mix_end = [this, old_trackId, mixData]() {
// Resize mix to oringinal start
return getTrackById_const(old_trackId)->resizeMixEnd(mixData.second.secondClipId, mixData.second.firstClipInOut.second);
};
}
}
}
move_mix_end();
PUSH_LAMBDA(update_mix, local_undo);
PUSH_LAMBDA(update_mix_end, local_undo);
if (old_trackId != -1) {
if (notifyViewOnly) {
PUSH_LAMBDA(update_model, local_undo);
......@@ -664,6 +707,7 @@ bool TimelineModel::requestClipMove(int clipId, int trackId, int position, bool
}
move_mix();
UPDATE_UNDO_REDO(move_mix, restore_mix, local_undo, local_redo);
UPDATE_UNDO_REDO(move_mix_end, restore_mix_end, local_undo, local_redo);
ok = getTrackById(trackId)->requestClipInsertion(clipId, position, updateView, finalMove, local_undo, local_redo, groupMove);
if (!ok) {
qDebug() << "-------------\n\nINSERTION FAILED, REVERTING\n\n-------------------";
......@@ -676,6 +720,7 @@ bool TimelineModel::requestClipMove(int clipId, int trackId, int position, bool
if (notifyViewOnly) {
PUSH_LAMBDA(update_model, local_redo);
PUSH_LAMBDA(update_mix, local_redo);
PUSH_LAMBDA(update_mix_end, local_redo);
}
UPDATE_UNDO_REDO(local_redo, local_undo, undo, redo);
return true;
......
......@@ -1540,10 +1540,7 @@ std::pair<MixInfo, MixInfo> TrackModel::getMixInfo(int clipId) const
bool TrackModel::deleteMix(int clipId, bool final)
{
qDebug()<<"=== DELETING MIX FROM CLIP: "<<clipId;
if (m_sameCompositions.count(clipId) <= 0) {
return false;
}
Q_ASSERT(m_sameCompositions.count(clipId) > 0);
if (auto ptr = m_parent.lock()) {
std::shared_ptr<ClipModel> movedClip(ptr->getClipPtr(clipId));
movedClip->setMixDuration(final ? 0 : 1);
......@@ -1594,9 +1591,7 @@ bool TrackModel::createMix(std::pair<int, int> clipIds, std::pair<int, int> mixD
bool TrackModel::resizeMixStart(int clipId, int position)
{
if (m_sameCompositions.count(clipId) <= 0) {
return false;
}
Q_ASSERT(m_sameCompositions.count(clipId) > 0);
if (auto ptr = m_parent.lock()) {
Mlt::Transition &transition = *m_sameCompositions[clipId].get();
std::shared_ptr<ClipModel> movedClip(ptr->getClipPtr(clipId));
......@@ -1605,8 +1600,6 @@ bool TrackModel::resizeMixStart(int clipId, int position)
transition.set_in_and_out(in, out);
int updatedDuration = out - in;
movedClip->setMixDuration(qMax(1, updatedDuration));
QModelIndex ix = ptr->makeClipIndexFromID(clipId);
emit ptr->dataChanged(ix, ix, {TimelineModel::StartRole,TimelineModel::MixRole});
return true;
}
return false;
......@@ -1614,19 +1607,16 @@ bool TrackModel::resizeMixStart(int clipId, int position)
bool TrackModel::resizeMixEnd(int clipId, int position)
{
int secondClip = m_mixList.value(clipId, -1);
if (secondClip == -1) {
return false;
}
Q_ASSERT(m_sameCompositions.count(clipId) > 0);
if (auto ptr = m_parent.lock()) {
Mlt::Transition &transition = *m_sameCompositions[secondClip].get();
std::shared_ptr<ClipModel> movedClip(ptr->getClipPtr(secondClip));
Mlt::Transition &transition = *m_sameCompositions[clipId].get();
std::shared_ptr<ClipModel> refClip(ptr->getClipPtr(clipId));
int in = transition.get_in();
int out = position;
transition.set_in_and_out(in, out);
int updatedDuration = out - in;
movedClip->setMixDuration(qMax(1, updatedDuration));
QModelIndex ix = ptr->makeClipIndexFromID(secondClip);
refClip->setMixDuration(qMax(1, updatedDuration));
QModelIndex ix = ptr->makeClipIndexFromID(clipId);
emit ptr->dataChanged(ix, ix, {TimelineModel::MixRole});
return true;
}
......@@ -1644,7 +1634,7 @@ bool TrackModel::hasMix(int cid) const
if (m_mixList.contains(cid)) {
return true;
}
if (m_mixList.key(cid, -1) >= 0) {
if (m_sameCompositions.count(cid) > 0) {
return true;
}
return false;
......
......@@ -41,7 +41,9 @@ TEST_CASE("Simple Mix", "[SameTrackMix]")
// Create a request
int tid1 = TrackModel::construct(timeline, -1, -1, QString(), true);
int tid3 = TrackModel::construct(timeline, -1, -1, QString(), true);
int tid2 = TrackModel::construct(timeline);
int tid4 = TrackModel::construct(timeline);
// Create clip with audio
QString binId = createProducerWithSound(profile_mix, binModel, 50);
......@@ -89,12 +91,11 @@ TEST_CASE("Simple Mix", "[SameTrackMix]")
auto state1 = [&]() {
REQUIRE(timeline->getClipsCount() == 6);
qDebug()<<"HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH\nCLIPS: "<<timeline->getClipPosition(cid1)<<"-"<<timeline->getClipPlaytime(cid1)<<" / CID2: "<<timeline->getClipPosition(cid2)<<"-"<<timeline->getClipPlaytime(cid2);
REQUIRE(timeline->getClipPlaytime(cid1) > 10);
REQUIRE(timeline->getClipPosition(cid1) == 100);
REQUIRE(timeline->getClipPlaytime(cid2) > 10);
REQUIRE(timeline->getClipPosition(cid2) < 110);
REQUIRE(timeline->getTrackById_const(tid1)->mixCount() == 1);
REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 1);
REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1);
};
......@@ -113,7 +114,6 @@ TEST_CASE("Simple Mix", "[SameTrackMix]")
{
state0();
REQUIRE(timeline->mixClip(cid4));
state2();
undoStack->undo();
state0();
......@@ -136,7 +136,7 @@ TEST_CASE("Simple Mix", "[SameTrackMix]")
state0();
}
SECTION("Create mix and move color clips")
SECTION("Create mix on color clips and move main (right side) clip")
{
state0();
REQUIRE(timeline->mixClip(cid4));
......@@ -152,6 +152,38 @@ TEST_CASE("Simple Mix", "[SameTrackMix]")
REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0);
undoStack->undo();
state2();
// Move clip to another track, should delete mix
REQUIRE(timeline->requestClipMove(cid4, tid4, 600));
REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0);
REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0);
REQUIRE(timeline->getTrackById_const(tid4)->mixCount() == 0);
undoStack->undo();
state2();
undoStack->undo();
state0();
}
SECTION("Create mix on color clip and left side clip")
{
state0();
REQUIRE(timeline->mixClip(cid4));
state2();
// Move clip inside mix zone, should resize the mix
REQUIRE(timeline->requestClipMove(cid3, tid2, 502));
REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1);
undoStack->undo();
state2();
// Move clip outside mix zone, should delete the mix
REQUIRE(timeline->requestClipMove(cid3, tid2, 450));
REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0);
undoStack->undo();
state2();
// Move clip to another track, should delete mix
REQUIRE(timeline->requestClipMove(cid3, tid4, 600));
REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0);
REQUIRE(timeline->getTrackById_const(tid4)->mixCount() == 0);
undoStack->undo();
state2();
undoStack->undo();
state0();
}
......@@ -163,13 +195,13 @@ TEST_CASE("Simple Mix", "[SameTrackMix]")
state1();
// Move clip inside mix zone, should resize the mix
REQUIRE(timeline->requestClipMove(cid2, tid2, 100));
REQUIRE(timeline->getTrackById_const(tid1)->mixCount() == 1);
REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 1);
REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1);
undoStack->undo();
state1();
// Move clip outside mix zone, should delete the mix
REQUIRE(timeline->requestClipMove(cid2, tid2, 200));
REQUIRE(timeline->getTrackById_const(tid1)->mixCount() == 0);
REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 0);
REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0);
undoStack->undo();
state1();
......
Markdown is supported
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