Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Kdenlive
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
259
Issues
259
List
Boards
Labels
Service Desk
Milestones
Merge Requests
14
Merge Requests
14
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Multimedia
Kdenlive
Commits
ee8fb1c2
Commit
ee8fb1c2
authored
Sep 10, 2020
by
Jean-Baptiste Mardelle
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement moving left clip in a mix transition
parent
5d1a81b6
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
92 additions
and
25 deletions
+92
-25
src/timeline2/model/timelinemodel.cpp
src/timeline2/model/timelinemodel.cpp
+46
-1
src/timeline2/model/trackmodel.cpp
src/timeline2/model/trackmodel.cpp
+8
-18
tests/mixtest.cpp
tests/mixtest.cpp
+38
-6
No files found.
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
[
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
;
moved
Clip
->
setMixDuration
(
qMax
(
1
,
updatedDuration
));
QModelIndex
ix
=
ptr
->
makeClipIndexFromID
(
secondClip
);
ref
Clip
->
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
;
...
...
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 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
(
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