Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Multimedia
Kdenlive
Commits
ee8fb1c2
Commit
ee8fb1c2
authored
Sep 10, 2020
by
Jean-Baptiste Mardelle
Browse files
Implement moving left clip in a mix transition
parent
5d1a81b6
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/timeline2/model/timelinemodel.cpp
View file @
ee8fb1c2
...
...
@@ -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\n
INSERTION 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
;
...
...
src/timeline2/model/trackmodel.cpp
View file @
ee8fb1c2
...
...
@@ -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
[
secondC
lip
].
get
();
std
::
shared_ptr
<
ClipModel
>
moved
Clip
(
ptr
->
getClipPtr
(
secondC
lip
));
Mlt
::
Transition
&
transition
=
*
m_sameCompositions
[
c
lip
Id
].
get
();
std
::
shared_ptr
<
ClipModel
>
ref
Clip
(
ptr
->
getClipPtr
(
c
lip
Id
));
int
in
=
transition
.
get_in
();
int
out
=
position
;
transition
.
set_in_and_out
(
in
,
out
);
int
updatedDuration
=
out
-
in
;
moved
Clip
->
setMixDuration
(
qMax
(
1
,
updatedDuration
));
QModelIndex
ix
=
ptr
->
makeClipIndexFromID
(
secondC
lip
);
ref
Clip
->
setMixDuration
(
qMax
(
1
,
updatedDuration
));
QModelIndex
ix
=
ptr
->
makeClipIndexFromID
(
c
lip
Id
);
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
;
...
...
tests/mixtest.cpp
View file @
ee8fb1c2
...
...
@@ -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
\n
CLIPS: "
<<
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
(
tid
1
)
->
mixCount
()
==
1
);
REQUIRE
(
timeline
->
getTrackById_const
(
tid
3
)
->
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
clip
s
"
)
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
(
tid
1
)
->
mixCount
()
==
1
);
REQUIRE
(
timeline
->
getTrackById_const
(
tid
3
)
->
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
(
tid
1
)
->
mixCount
()
==
0
);
REQUIRE
(
timeline
->
getTrackById_const
(
tid
3
)
->
mixCount
()
==
0
);
REQUIRE
(
timeline
->
getTrackById_const
(
tid2
)
->
mixCount
()
==
0
);
undoStack
->
undo
();
state1
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment