Skip to content
GitLab
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
b2235e3f
Commit
b2235e3f
authored
Nov 29, 2016
by
Jean-Baptiste Mardelle
Browse files
Fix several issues with effect keyframes behaving incorrectly
parent
13535766
Changes
11
Hide whitespace changes
Inline
Side-by-side
src/effectstack/dragvalue.cpp
View file @
b2235e3f
...
...
@@ -363,7 +363,6 @@ void DragValue::setInTimelineProperty(bool intimeline)
style
()
->
polish
(
m_doubleEdit
);
m_doubleEdit
->
update
();
}
}
CustomLabel
::
CustomLabel
(
const
QString
&
label
,
bool
showSlider
,
int
range
,
QWidget
*
parent
)
:
...
...
src/effectstack/effectstackview2.cpp
View file @
b2235e3f
...
...
@@ -67,6 +67,10 @@ EffectStackView2::EffectStackView2(Monitor *projectMonitor, QWidget *parent) :
connect
(
m_effect
->
checkAll
,
SIGNAL
(
stateChanged
(
int
)),
this
,
SLOT
(
slotCheckAll
(
int
)));
connect
(
m_effect
->
effectCompare
,
&
QToolButton
::
toggled
,
this
,
&
EffectStackView2
::
slotSwitchCompare
);
m_scrollTimer
.
setSingleShot
(
true
);
m_scrollTimer
.
setInterval
(
200
);
connect
(
&
m_scrollTimer
,
&
QTimer
::
timeout
,
this
,
&
EffectStackView2
::
slotCheckWheelEventFilter
);
m_layout
.
addWidget
(
m_effect
);
m_layout
.
addWidget
(
m_transition
);
m_transition
->
setHidden
(
true
);
...
...
@@ -278,12 +282,19 @@ void EffectStackView2::slotTrackItemSelected(int ix, const TrackInfo &info, Moni
void
EffectStackView2
::
setupListView
()
{
blockSignals
(
true
);
m_scrollTimer
.
stop
();
m_monitorSceneWanted
=
MonitorSceneDefault
;
m_draggedEffect
=
NULL
;
m_draggedGroup
=
NULL
;
disconnect
(
m_effectMetaInfo
.
monitor
,
SIGNAL
(
renderPosition
(
int
)),
this
,
SLOT
(
slotRenderPos
(
int
)));
QWidget
*
view
=
m_effect
->
container
->
takeWidget
();
if
(
view
)
{
/*QList<CollapsibleEffect *> allChildren = view->findChildren<CollapsibleEffect *>();
qDebug()<<" * * *FOUND CHLD: "<<allChildren.count();
foreach(CollapsibleEffect *eff, allChildren) {
eff->setEnabled(false);
}*/
//delete view;
view
->
setEnabled
(
false
);
view
->
setHidden
(
true
);
view
->
deleteLater
();
...
...
@@ -409,7 +420,7 @@ void EffectStackView2::setupListView()
slotUpdateCheckAllButton
();
// Wait a little bit for the new layout to be ready, then check if we have a scrollbar
QTimer
::
singleShot
(
200
,
this
,
SLOT
(
slotCheckWheelEventFilter
())
);
m_scrollTimer
.
start
(
);
}
int
EffectStackView2
::
activeEffectIndex
()
const
...
...
@@ -759,7 +770,7 @@ void EffectStackView2::slotUpdateEffectParams(const QDomElement &old, const QDom
else
if
(
m_status
==
MASTER_CLIP
)
{
emit
updateMasterEffect
(
m_masterclipref
->
clipId
(),
old
,
e
,
ix
);
}
QTimer
::
singleShot
(
200
,
this
,
SLOT
(
slotCheckWheelEventFilter
())
);
m_scrollTimer
.
start
(
);
}
void
EffectStackView2
::
slotSetCurrentEffect
(
int
ix
)
...
...
@@ -992,7 +1003,7 @@ void EffectStackView2::slotCreateRegion(int ix, QUrl url)
// Check drag & drop
currentEffect
->
installEventFilter
(
this
);
QTimer
::
singleShot
(
200
,
this
,
SLOT
(
slotCheckWheelEventFilter
())
);
m_scrollTimer
.
start
(
);
}
...
...
src/effectstack/effectstackview2.h
View file @
b2235e3f
...
...
@@ -27,6 +27,8 @@
#include
"collapsibleeffect.h"
#include
"collapsiblegroup.h"
#include
<QTimer>
class
EffectsList
;
class
ClipItem
;
class
Transition
;
...
...
@@ -124,6 +126,7 @@ private:
/** @brief The current effect may require an on monitor scene. */
MonitorSceneType
m_monitorSceneWanted
;
QMutex
m_mutex
;
QTimer
m_scrollTimer
;
/** If in track mode: Info of the edited track to be able to access its duration. */
TrackInfo
m_trackInfo
;
...
...
src/effectstack/widgets/animationwidget.cpp
View file @
b2235e3f
...
...
@@ -269,11 +269,11 @@ void AnimationWidget::slotPrevious()
void
AnimationWidget
::
slotNext
()
{
int
next
=
m_animController
.
next_key
(
m_timePos
->
getValue
()
-
m_offset
+
1
)
+
m_offset
;
if
(
!
m_animController
.
is_key
(
next
))
{
if
(
!
m_animController
.
is_key
(
next
-
m_offset
))
{
// No keyframe after current pos, return end position
next
=
m_timePos
->
maximum
();
}
else
{
m_ruler
->
setActiveKeyframe
(
next
);
m_ruler
->
setActiveKeyframe
(
next
-
m_offset
);
}
slotPositionChanged
(
next
,
true
);
}
...
...
@@ -350,7 +350,7 @@ void AnimationWidget::slotAddDeleteKeyframe(bool add, int pos)
for
(
int
i
=
0
;
i
<
paramNames
.
count
();
i
++
)
{
m_animController
=
m_animProperties
.
get_animation
(
paramNames
.
at
(
i
).
toUtf8
().
constData
());
if
(
!
m_animController
.
is_key
(
pos
-
m_offset
))
{
doAddKeyframe
(
pos
-
m_offset
,
paramNames
.
at
(
i
),
false
);
doAddKeyframe
(
pos
,
paramNames
.
at
(
i
),
false
);
}
}
m_ruler
->
setActiveKeyframe
(
pos
);
...
...
src/timeline/abstractclipitem.cpp
View file @
b2235e3f
...
...
@@ -624,3 +624,18 @@ QString AbstractClipItem::resizeAnimations(QDomElement effect, int previousDurat
}
return
keyframes
;
}
bool
AbstractClipItem
::
switchKeyframes
(
QDomElement
param
,
int
in
,
int
oldin
,
int
out
,
int
oldout
)
{
QString
animation
=
param
.
attribute
(
QStringLiteral
(
"value"
));
if
(
in
!=
oldin
)
animation
=
KeyframeView
::
switchAnimation
(
animation
,
in
,
oldin
,
out
,
oldout
,
param
.
attribute
(
QStringLiteral
(
"type"
))
==
QLatin1String
(
"animatedrect"
));
if
(
out
!=
oldout
)
animation
=
KeyframeView
::
switchAnimation
(
animation
,
out
-
1
,
oldout
-
1
,
out
,
oldout
,
param
.
attribute
(
QStringLiteral
(
"type"
))
==
QLatin1String
(
"animatedrect"
));
if
(
animation
!=
param
.
attribute
(
QStringLiteral
(
"value"
)))
{
param
.
setAttribute
(
QStringLiteral
(
"value"
),
animation
);
return
true
;
}
return
false
;
}
src/timeline/abstractclipitem.h
View file @
b2235e3f
...
...
@@ -123,6 +123,7 @@ protected:
int
posForTrack
(
int
track
);
bool
resizeGeometries
(
QDomElement
effect
,
int
width
,
int
height
,
int
previousDuration
,
int
start
,
int
duration
,
int
cropstart
);
QString
resizeAnimations
(
QDomElement
effect
,
int
previousDuration
,
int
start
,
int
duration
,
int
cropstart
);
bool
switchKeyframes
(
QDomElement
param
,
int
in
,
int
oldin
,
int
out
,
int
oldout
);
signals:
void
selectItem
(
AbstractClipItem
*
);
...
...
src/timeline/clipitem.cpp
View file @
b2235e3f
...
...
@@ -1735,7 +1735,7 @@ void ClipItem::setState(PlaylistState::ClipState state)
QMap
<
int
,
QDomElement
>
ClipItem
::
adjustEffectsToDuration
(
const
ItemInfo
&
oldInfo
)
{
QMap
<
int
,
QDomElement
>
effects
;
qDebug
()
<<
"Adjusting effect to duraion
"
;
//
qDebug()<<"Adjusting effect to dura
t
ion
: "<<oldInfo.cropStart.frames(25)<<" - "<<cropStart().frames(25)
;
for
(
int
i
=
0
;
i
<
m_effectList
.
count
();
++
i
)
{
QDomElement
effect
=
m_effectList
.
at
(
i
);
...
...
@@ -1790,7 +1790,6 @@ QMap<int, QDomElement> ClipItem::adjustEffectsToDuration(const ItemInfo &oldInfo
QDomNodeList
params
=
effect
.
elementsByTagName
(
QStringLiteral
(
"parameter"
));
for
(
int
j
=
0
;
j
<
params
.
count
();
++
j
)
{
QDomElement
param
=
params
.
item
(
j
).
toElement
();
QString
type
=
param
.
attribute
(
QStringLiteral
(
"type"
));
if
(
type
==
QLatin1String
(
"geometry"
)
&&
!
param
.
hasAttribute
(
QStringLiteral
(
"fixed"
)))
{
if
(
!
effects
.
contains
(
i
))
{
...
...
@@ -1805,10 +1804,13 @@ QMap<int, QDomElement> ClipItem::adjustEffectsToDuration(const ItemInfo &oldInfo
if
(
!
effects
.
contains
(
i
))
effects
[
i
]
=
effect
.
cloneNode
().
toElement
();
updateNormalKeyframes
(
param
,
oldInfo
);
}
else
if
(
type
==
QLatin1String
(
"animated"
))
{
}
else
if
(
type
.
startsWith
(
QLatin1String
(
"animated"
))
)
{
if
(
effect
.
attribute
(
QStringLiteral
(
"sync_in_out"
))
==
QLatin1String
(
"1"
))
{
effect
.
setAttribute
(
QStringLiteral
(
"in"
),
cropStart
().
frames
(
m_fps
));
effect
.
setAttribute
(
QStringLiteral
(
"out"
),
(
cropStart
()
+
cropDuration
()).
frames
(
m_fps
)
-
1
);
}
else
{
// Check if we have keyframes at in/out points
updateAnimatedKeyframes
(
i
,
param
,
oldInfo
);
}
effects
[
i
]
=
effect
.
cloneNode
().
toElement
();
}
else
if
(
type
==
QLatin1String
(
"roto-spline"
))
{
...
...
@@ -1823,7 +1825,17 @@ QMap<int, QDomElement> ClipItem::adjustEffectsToDuration(const ItemInfo &oldInfo
return
effects
;
}
bool
ClipItem
::
updateNormalKeyframes
(
QDomElement
parameter
,
ItemInfo
oldInfo
)
bool
ClipItem
::
updateAnimatedKeyframes
(
int
ix
,
QDomElement
parameter
,
const
ItemInfo
&
oldInfo
)
{
int
in
=
cropStart
().
frames
(
m_fps
);
int
out
=
(
cropStart
()
+
cropDuration
()).
frames
(
m_fps
)
-
1
;
int
oldin
=
oldInfo
.
cropStart
.
frames
(
m_fps
);
int
oldout
=
oldin
+
oldInfo
.
cropDuration
.
frames
(
m_fps
)
-
1
;
return
switchKeyframes
(
parameter
,
in
,
oldin
,
out
,
oldout
);
}
bool
ClipItem
::
updateNormalKeyframes
(
QDomElement
parameter
,
const
ItemInfo
&
oldInfo
)
{
int
in
=
cropStart
().
frames
(
m_fps
);
int
out
=
(
cropStart
()
+
cropDuration
()).
frames
(
m_fps
)
-
1
;
...
...
src/timeline/clipitem.h
View file @
b2235e3f
...
...
@@ -166,8 +166,8 @@ public:
QPixmap
endThumb
()
const
;
void
setState
(
PlaylistState
::
ClipState
state
);
void
updateState
(
const
QString
&
id
,
int
aIndex
,
int
vIndex
,
PlaylistState
::
ClipState
originalState
);
bool
updateNormalKeyframes
(
QDomElement
parameter
,
ItemInfo
oldInfo
);
bool
updateAnimatedKeyframes
(
int
ix
,
QDomElement
parameter
,
const
ItemInfo
&
oldInfo
);
bool
updateNormalKeyframes
(
QDomElement
parameter
,
const
ItemInfo
&
oldInfo
);
/** @brief Adjusts effects after a clip duration change. */
QMap
<
int
,
QDomElement
>
adjustEffectsToDuration
(
const
ItemInfo
&
oldInfo
);
...
...
src/timeline/customtrackview.cpp
View file @
b2235e3f
...
...
@@ -7791,10 +7791,6 @@ void CustomTrackView::adjustEffects(ClipItem* item, ItemInfo oldInfo, QUndoComma
++i;
}
}
if (item == m_dragItem) {
// clip is selected, update effect stack
emit clipItemSelected(item);
}
}
...
...
src/timeline/keyframeview.cpp
View file @
b2235e3f
...
...
@@ -529,7 +529,7 @@ void KeyframeView::updateKeyFramePos(QRectF br, int frame, const double y)
}
int
prev
=
m_keyAnim
.
key_count
()
<=
1
||
m_keyAnim
.
key_get_frame
(
0
)
==
activeKeyframe
?
0
:
m_keyAnim
.
previous_key
(
activeKeyframe
-
1
)
+
1
;
prev
=
qMax
(
prev
,
-
m_offset
);
int
next
=
m_keyAnim
.
key_count
()
<=
1
||
m_keyAnim
.
key_get_frame
(
m_keyAnim
.
key_count
()
-
1
)
==
activeKeyframe
?
duration
-
m_offset
:
m_keyAnim
.
next_key
(
activeKeyframe
+
1
)
-
1
;
int
next
=
m_keyAnim
.
key_count
()
<=
1
||
m_keyAnim
.
key_get_frame
(
m_keyAnim
.
key_count
()
-
1
)
==
activeKeyframe
?
duration
-
m_offset
-
1
:
m_keyAnim
.
next_key
(
activeKeyframe
+
1
)
-
1
;
if
(
next
<
0
)
next
+=
duration
;
int
newpos
=
qBound
(
prev
,
frame
-
m_offset
,
next
);
double
newval
=
keyframeUnmap
(
br
,
y
);
...
...
@@ -961,6 +961,29 @@ QString KeyframeView::cutAnimation(const QString &animation, int start, int dura
return
anim
.
serialize_cut
(
start
,
start
+
duration
);
}
//static
QString
KeyframeView
::
switchAnimation
(
QString
animation
,
int
newPos
,
int
oldPos
,
int
newDuration
,
int
oldDuration
,
bool
isRect
)
{
Mlt
::
Properties
props
;
props
.
set
(
"keyframes"
,
animation
.
toUtf8
().
constData
());
props
.
anim_get_double
(
"keyframes"
,
0
,
oldDuration
);
Mlt
::
Animation
anim
=
props
.
get_animation
(
"keyframes"
);
if
(
anim
.
is_key
(
oldPos
))
{
// insert new keyframe at start
if
(
isRect
)
{
mlt_rect
rect
=
props
.
anim_get_rect
(
"keyframes"
,
oldPos
);
props
.
anim_set
(
"keyframes"
,
rect
,
newPos
,
newDuration
,
anim
.
keyframe_type
(
oldPos
));
anim
.
remove
(
oldPos
);
}
else
{
double
value
=
props
.
anim_get_double
(
"keyframes"
,
oldPos
,
oldDuration
);
props
.
anim_set
(
"keyframes"
,
value
,
newPos
,
newDuration
,
anim
.
keyframe_type
(
oldPos
));
anim
.
remove
(
oldPos
);
}
}
return
anim
.
serialize_cut
();
//return anim.serialize_cut(start, start + duration);
}
/*
void KeyframeView::updateAnimatedKeyframes(QDomElement effect, int paramIndex, ItemInfo oldInfo)
...
...
src/timeline/keyframeview.h
View file @
b2235e3f
...
...
@@ -93,6 +93,8 @@ public:
void
showMenu
(
QWidget
*
parent
,
QPoint
pos
);
QAction
*
parseKeyframeActions
(
QList
<
QAction
*>
actions
);
static
QString
cutAnimation
(
const
QString
&
animation
,
int
start
,
int
duration
,
int
fullduration
,
bool
doCut
=
true
);
/** @brief when an animation is resized, update in / out point keyframes */
static
QString
switchAnimation
(
QString
animation
,
int
newPos
,
int
oldPos
,
int
newDuration
,
int
oldDuration
,
bool
isRect
);
/** @brief when loading an animation from a serialized string, check where is the first negative keyframe) */
static
int
checkNegatives
(
const
QString
&
data
,
int
maxDuration
);
/** @brief returns true if currently edited parameter name is name */
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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