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
2d6f0afe
Commit
2d6f0afe
authored
Dec 08, 2020
by
Jean-Baptiste Mardelle
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Effectstack: Add duplicate keyframe(s) button
parent
eb7c898d
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
73 additions
and
6 deletions
+73
-6
src/assets/keyframes/model/keyframemodel.cpp
src/assets/keyframes/model/keyframemodel.cpp
+15
-0
src/assets/keyframes/model/keyframemodel.hpp
src/assets/keyframes/model/keyframemodel.hpp
+2
-0
src/assets/keyframes/model/keyframemodellist.cpp
src/assets/keyframes/model/keyframemodellist.cpp
+9
-0
src/assets/keyframes/model/keyframemodellist.hpp
src/assets/keyframes/model/keyframemodellist.hpp
+3
-0
src/assets/keyframes/view/keyframeview.cpp
src/assets/keyframes/view/keyframeview.cpp
+32
-6
src/assets/keyframes/view/keyframeview.hpp
src/assets/keyframes/view/keyframeview.hpp
+3
-0
src/assets/view/widgets/keyframewidget.cpp
src/assets/view/widgets/keyframewidget.cpp
+8
-0
src/assets/view/widgets/keyframewidget.hpp
src/assets/view/widgets/keyframewidget.hpp
+1
-0
No files found.
src/assets/keyframes/model/keyframemodel.cpp
View file @
2d6f0afe
...
...
@@ -134,6 +134,21 @@ bool KeyframeModel::removeKeyframe(GenTime pos, Fun &undo, Fun &redo, bool notif
return
false
;
}
bool
KeyframeModel
::
duplicateKeyframe
(
GenTime
srcPos
,
GenTime
dstPos
,
Fun
&
undo
,
Fun
&
redo
)
{
QWriteLocker
locker
(
&
m_lock
);
Q_ASSERT
(
m_keyframeList
.
count
(
srcPos
)
>
0
);
KeyframeType
oldType
=
m_keyframeList
[
srcPos
].
first
;
QVariant
oldValue
=
m_keyframeList
[
srcPos
].
second
;
Fun
local_redo
=
addKeyframe_lambda
(
dstPos
,
oldType
,
oldValue
,
true
);
Fun
local_undo
=
deleteKeyframe_lambda
(
dstPos
,
true
);
if
(
local_redo
())
{
UPDATE_UNDO_REDO
(
local_redo
,
local_undo
,
undo
,
redo
);
return
true
;
}
return
false
;
}
bool
KeyframeModel
::
removeKeyframe
(
int
frame
)
{
GenTime
pos
(
frame
,
pCore
->
getCurrentFps
());
...
...
src/assets/keyframes/model/keyframemodel.hpp
View file @
2d6f0afe
...
...
@@ -81,6 +81,8 @@ protected:
/* @brief Removes the keyframe at the given position. */
bool
removeKeyframe
(
int
frame
);
bool
moveKeyframe
(
int
oldPos
,
int
pos
,
QVariant
newVal
);
/* @brief Duplicate a keyframe at the given position. */
bool
duplicateKeyframe
(
GenTime
srcPos
,
GenTime
dstPos
,
Fun
&
undo
,
Fun
&
redo
);
bool
removeKeyframe
(
GenTime
pos
);
/* @brief Delete all the keyframes of the model */
bool
removeAllKeyframes
();
...
...
src/assets/keyframes/model/keyframemodellist.cpp
View file @
2d6f0afe
...
...
@@ -160,6 +160,15 @@ bool KeyframeModelList::removeKeyframeWithUndo(GenTime pos, Fun &undo, Fun &redo
return
result
;
}
bool
KeyframeModelList
::
duplicateKeyframeWithUndo
(
GenTime
srcPos
,
GenTime
destPos
,
Fun
&
undo
,
Fun
&
redo
)
{
bool
result
=
true
;
for
(
const
auto
&
param
:
m_parameters
)
{
result
=
result
&&
param
.
second
->
duplicateKeyframe
(
srcPos
,
destPos
,
undo
,
redo
);
}
return
result
;
}
bool
KeyframeModelList
::
removeAllKeyframes
()
{
QWriteLocker
locker
(
&
m_lock
);
...
...
src/assets/keyframes/model/keyframemodellist.hpp
View file @
2d6f0afe
...
...
@@ -65,6 +65,9 @@ public:
/* @brief Removes the keyframe at the given position. */
bool
removeKeyframe
(
GenTime
pos
);
bool
removeKeyframeWithUndo
(
GenTime
pos
,
Fun
&
undo
,
Fun
&
redo
);
/* @brief Duplicate a keyframe at the given position. */
bool
duplicateKeyframeWithUndo
(
GenTime
srcPos
,
GenTime
destPos
,
Fun
&
undo
,
Fun
&
redo
);
/* @brief Delete all the keyframes of the model (except first) */
bool
removeAllKeyframes
();
/* @brief Delete all the keyframes after a certain position (except first) */
...
...
src/assets/keyframes/view/keyframeview.cpp
View file @
2d6f0afe
...
...
@@ -107,6 +107,20 @@ void KeyframeView::initKeyframePos()
emit
atKeyframe
(
m_model
->
hasKeyframe
(
m_position
),
m_model
->
singleKeyframe
());
}
void
KeyframeView
::
slotDuplicateKeyframe
()
{
int
offset
=
pCore
->
getItemIn
(
m_model
->
getOwnerId
());
if
(
m_currentKeyframe
>
-
1
&&
!
m_model
->
hasKeyframe
(
m_position
+
offset
))
{
Fun
undo
=
[]()
{
return
true
;
};
Fun
redo
=
[]()
{
return
true
;
};
int
delta
=
m_position
-
m_currentKeyframe
;
for
(
int
kf
:
m_selectedKeyframes
)
{
m_model
->
duplicateKeyframeWithUndo
(
GenTime
(
kf
+
offset
,
pCore
->
getCurrentFps
()),
GenTime
(
kf
+
delta
+
offset
,
pCore
->
getCurrentFps
()),
undo
,
redo
);
}
pCore
->
pushUndo
(
undo
,
redo
,
i18n
(
"Duplicate keyframe"
));
}
}
void
KeyframeView
::
slotAddKeyframe
(
int
pos
)
{
if
(
pos
<
0
)
{
...
...
@@ -219,9 +233,15 @@ void KeyframeView::slotCenterKeyframe()
if
(
!
m_model
->
hasKeyframe
(
m_currentKeyframeOriginal
+
offset
))
{
return
;
}
GenTime
initPos
(
m_currentKeyframeOriginal
+
offset
,
pCore
->
getCurrentFps
());
GenTime
targetPos
(
m_position
+
offset
,
pCore
->
getCurrentFps
());
m_model
->
moveKeyframe
(
initPos
,
targetPos
,
true
);
Fun
undo
=
[]()
{
return
true
;
};
Fun
redo
=
[]()
{
return
true
;
};
int
delta
=
m_position
-
m_currentKeyframeOriginal
;
for
(
int
kf
:
m_selectedKeyframes
)
{
GenTime
initPos
(
kf
+
offset
,
pCore
->
getCurrentFps
());
GenTime
targetPos
(
kf
+
delta
+
offset
,
pCore
->
getCurrentFps
());
m_model
->
moveKeyframeWithUndo
(
initPos
,
targetPos
,
undo
,
redo
);
}
pCore
->
pushUndo
(
undo
,
redo
,
i18n
(
"Move keyframe"
));
}
void
KeyframeView
::
mousePressEvent
(
QMouseEvent
*
event
)
...
...
@@ -369,6 +389,7 @@ void KeyframeView::mouseMoveEvent(QMouseEvent *event)
int
max
=
qMax
(
m_clickPoint
,
m_clickEnd
);
min
=
qMax
(
1
,
min
);
m_selectedKeyframes
.
clear
();
m_currentKeyframeOriginal
=
m_currentKeyframe
=
-
1
;
double
fps
=
pCore
->
getCurrentFps
();
for
(
const
auto
&
keyframe
:
*
m_model
.
get
())
{
int
pos
=
keyframe
.
first
.
frames
(
fps
)
-
offset
;
...
...
@@ -376,11 +397,14 @@ void KeyframeView::mouseMoveEvent(QMouseEvent *event)
m_selectedKeyframes
<<
pos
;
}
}
if
(
!
m_selectedKeyframes
.
isEmpty
())
{
m_currentKeyframeOriginal
=
m_currentKeyframe
=
m_selectedKeyframes
.
first
();
}
update
();
return
;
}
if
(
KdenliveSettings
::
keyframeseek
())
{
if
(
!
m_moveKeyframeMode
||
KdenliveSettings
::
keyframeseek
())
{
emit
seekToPos
(
pos
);
}
return
;
...
...
@@ -613,10 +637,12 @@ void KeyframeView::paintEvent(QPaintEvent *event)
if
(
scaledPos
<
m_zoomStart
||
qFloor
(
scaledPos
)
>
zoomEnd
)
{
continue
;
}
if
(
m_selectedKeyframes
.
contains
(
pos
))
{
if
(
pos
==
m_currentKeyframe
)
{
p
.
setBrush
(
Qt
::
red
);
}
else
if
(
m_selectedKeyframes
.
contains
(
pos
))
{
p
.
setBrush
(
m_colSelected
);
}
else
if
(
pos
==
m_currentKeyframe
||
pos
==
m_hoverKeyframe
)
{
p
.
setBrush
(
Qt
::
green
);
p
.
setBrush
(
Qt
::
yellow
);
}
else
{
p
.
setBrush
(
m_colKeyframe
);
}
...
...
src/assets/keyframes/view/keyframeview.hpp
View file @
2d6f0afe
...
...
@@ -47,6 +47,9 @@ public slots:
If pos is negative, then keyframe is added at current position
*/
void
slotAddKeyframe
(
int
pos
=
-
1
);
/* @brief Duplicate selected keyframe at cursor position
*/
void
slotDuplicateKeyframe
();
/* @brief If there is a keyframe at current position, it is removed.
Otherwise, we add a new one with given value.
*/
...
...
src/assets/view/widgets/keyframewidget.cpp
View file @
2d6f0afe
...
...
@@ -86,6 +86,12 @@ KeyframeWidget::KeyframeWidget(std::shared_ptr<AssetParameterModel> model, QMode
m_buttonCenter
->
setIcon
(
QIcon
::
fromTheme
(
QStringLiteral
(
"align-horizontal-center"
)));
m_buttonCenter
->
setToolTip
(
i18n
(
"Move selected keyframe to cursor"
));
// Duplicate selected keyframe at cursor pos
m_buttonCopy
=
new
QToolButton
(
this
);
m_buttonCopy
->
setAutoRaise
(
true
);
m_buttonCopy
->
setIcon
(
QIcon
::
fromTheme
(
QStringLiteral
(
"edit-copy"
)));
m_buttonCopy
->
setToolTip
(
i18n
(
"Duplicate selected keyframe"
));
// Keyframe type widget
m_selectType
=
new
KSelectAction
(
QIcon
::
fromTheme
(
QStringLiteral
(
"keyframes"
)),
i18n
(
"Keyframe interpolation"
),
this
);
QAction
*
linear
=
new
QAction
(
QIcon
::
fromTheme
(
QStringLiteral
(
"linear"
)),
i18n
(
"Linear"
),
this
);
...
...
@@ -117,6 +123,7 @@ KeyframeWidget::KeyframeWidget(std::shared_ptr<AssetParameterModel> model, QMode
m_toolbar
->
addWidget
(
m_buttonAddDelete
);
m_toolbar
->
addWidget
(
m_buttonNext
);
m_toolbar
->
addWidget
(
m_buttonCenter
);
m_toolbar
->
addWidget
(
m_buttonCopy
);
m_toolbar
->
addAction
(
m_selectType
);
QAction
*
seekKeyframe
=
new
QAction
(
i18n
(
"Seek to keyframe on select"
),
this
);
...
...
@@ -191,6 +198,7 @@ KeyframeWidget::KeyframeWidget(std::shared_ptr<AssetParameterModel> model, QMode
connect
(
m_buttonPrevious
,
&
QAbstractButton
::
pressed
,
m_keyframeview
,
&
KeyframeView
::
slotGoToPrev
);
connect
(
m_buttonNext
,
&
QAbstractButton
::
pressed
,
m_keyframeview
,
&
KeyframeView
::
slotGoToNext
);
connect
(
m_buttonCenter
,
&
QAbstractButton
::
pressed
,
m_keyframeview
,
&
KeyframeView
::
slotCenterKeyframe
);
connect
(
m_buttonCopy
,
&
QAbstractButton
::
pressed
,
m_keyframeview
,
&
KeyframeView
::
slotDuplicateKeyframe
);
//m_baseHeight = m_keyframeview->height() + m_selectType->defaultWidget()->sizeHint().height();
QMargins
mrg
=
m_lay
->
contentsMargins
();
m_baseHeight
=
m_keyframeview
->
height
()
+
m_toolbar
->
sizeHint
().
height
()
+
mrg
.
top
()
+
mrg
.
bottom
();
...
...
src/assets/view/widgets/keyframewidget.hpp
View file @
2d6f0afe
...
...
@@ -93,6 +93,7 @@ private:
QToolButton
*
m_buttonPrevious
;
QToolButton
*
m_buttonNext
;
QToolButton
*
m_buttonCenter
;
QToolButton
*
m_buttonCopy
;
KSelectAction
*
m_selectType
;
TimecodeDisplay
*
m_time
;
MonitorSceneType
m_neededScene
;
...
...
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