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
cb49900d
Commit
cb49900d
authored
Sep 19, 2017
by
Nicolas Carion
Browse files
Display and allow edit of keyframable parameters
parent
3c98024b
Changes
8
Hide whitespace changes
Inline
Side-by-side
src/assets/keyframes/model/keyframemodel.cpp
View file @
cb49900d
...
...
@@ -182,11 +182,11 @@ bool KeyframeModel::updateKeyframe(GenTime pos, double value, Fun &undo, Fun &re
{
QWriteLocker
locker
(
&
m_lock
);
Q_ASSERT
(
m_keyframeList
.
count
(
pos
)
>
0
);
KeyframeType
oldT
ype
=
m_keyframeList
[
pos
].
first
;
KeyframeType
t
ype
=
m_keyframeList
[
pos
].
first
;
double
oldValue
=
m_keyframeList
[
pos
].
second
;
if
(
qAbs
(
oldValue
-
value
)
<
1e-6
)
return
true
;
auto
operation
=
updateKeyframe_lambda
(
pos
,
oldT
ype
,
oldV
alue
,
true
);
auto
reverse
=
updateKeyframe_lambda
(
pos
,
oldT
ype
,
v
alue
,
true
);
auto
operation
=
updateKeyframe_lambda
(
pos
,
t
ype
,
v
alue
,
true
);
auto
reverse
=
updateKeyframe_lambda
(
pos
,
t
ype
,
oldV
alue
,
true
);
bool
res
=
operation
();
if
(
res
)
{
UPDATE_UNDO_REDO
(
operation
,
reverse
,
undo
,
redo
);
...
...
src/assets/keyframes/model/keyframemodellist.cpp
View file @
cb49900d
...
...
@@ -111,14 +111,17 @@ bool KeyframeModelList::moveKeyframe(GenTime oldPos, GenTime pos, bool logUndo)
return
applyOperation
(
op
,
logUndo
?
i18n
(
"Move keyframe"
)
:
QString
());
}
bool
KeyframeModelList
::
updateKeyframe
(
GenTime
pos
,
double
value
)
bool
KeyframeModelList
::
updateKeyframe
(
GenTime
pos
,
double
value
,
const
QPersistentModelIndex
&
index
)
{
QWriteLocker
locker
(
&
m_lock
);
Q_ASSERT
(
m_parameters
.
size
()
>
0
);
auto
op
=
[
value
,
pos
](
std
::
shared_ptr
<
KeyframeModel
>
param
,
Fun
&
undo
,
Fun
&
redo
){
return
param
->
updateKeyframe
(
pos
,
value
,
undo
,
redo
);
};
return
applyOperation
(
op
,
i18n
(
"Update keyframe"
));
Q_ASSERT
(
m_parameters
.
count
(
index
)
>
0
);
Fun
undo
=
[]()
{
return
true
;
};
Fun
redo
=
[]()
{
return
true
;
};
bool
res
=
m_parameters
.
at
(
index
)
->
updateKeyframe
(
pos
,
value
,
undo
,
redo
);
if
(
res
)
{
PUSH_UNDO
(
undo
,
redo
,
i18n
(
"Update keyframe"
));
}
return
res
;
}
...
...
@@ -160,7 +163,15 @@ bool KeyframeModelList::hasKeyframe(int frame) const
void
KeyframeModelList
::
refresh
()
{
QWriteLocker
locker
(
&
m_lock
);
for
(
const
auto
&
param
:
m_parameters
)
{
param
.
second
->
refresh
();
}
}
double
KeyframeModelList
::
getInterpolatedValue
(
int
pos
,
const
QPersistentModelIndex
&
index
)
const
{
READ_LOCK
();
Q_ASSERT
(
m_parameters
.
count
(
index
)
>
0
);
return
m_parameters
.
at
(
index
)
->
getInterpolatedValue
(
pos
);
}
src/assets/keyframes/model/keyframemodellist.hpp
View file @
cb49900d
...
...
@@ -78,8 +78,9 @@ public:
/* @brief updates the value of a keyframe
@param old is the position of the keyframe
@param value is the new value of the param
@param index is the index of the wanted keyframe
*/
bool
updateKeyframe
(
GenTime
pos
,
double
value
);
bool
updateKeyframe
(
GenTime
pos
,
double
value
,
const
QPersistentModelIndex
&
index
);
/* @brief Returns a keyframe data at given pos
ok is a return parameter, set to true if everything went good
...
...
@@ -108,6 +109,11 @@ public:
*/
Q_INVOKABLE
bool
hasKeyframe
(
int
frame
)
const
;
/* @brief Return the interpolated value of a parameter.
@param pos is the position where we interpolate
@param index is the index of the queried parameter. */
double
getInterpolatedValue
(
int
pos
,
const
QPersistentModelIndex
&
index
)
const
;
void
refresh
();
protected:
...
...
src/assets/keyframes/view/keyframeview.cpp
View file @
cb49900d
...
...
@@ -57,6 +57,7 @@ KeyframeView::KeyframeView(std::shared_ptr<KeyframeModelList> model, QWidget *pa
void
KeyframeView
::
slotModelChanged
()
{
emit
atKeyframe
(
m_model
->
hasKeyframe
(
m_position
));
emit
modified
();
update
();
}
void
KeyframeView
::
slotSetPosition
(
int
pos
)
...
...
src/assets/keyframes/view/keyframeview.hpp
View file @
cb49900d
...
...
@@ -81,6 +81,7 @@ private:
signals:
void
seekToPos
(
int
pos
);
void
atKeyframe
(
bool
);
void
modified
();
};
#endif
src/assets/view/widgets/keyframewidget.cpp
View file @
cb49900d
...
...
@@ -26,6 +26,7 @@
#include
"timecode.h"
#include
"timecodedisplay.h"
#include
"utils/KoIconUtils.h"
#include
"widgets/doublewidget.h"
#include
<QGridLayout>
#include
<QToolButton>
...
...
@@ -39,7 +40,7 @@ KeyframeWidget::KeyframeWidget(std::shared_ptr<AssetParameterModel> model, QMode
setSizePolicy
(
QSizePolicy
::
Expanding
,
QSizePolicy
::
Preferred
);
auto
*
l
=
new
QGridLayout
(
this
);
m_lay
=
new
QGridLayout
(
this
);
bool
ok
=
false
;
int
duration
=
m_model
->
data
(
m_index
,
AssetParameterModel
::
ParentDurationRole
).
toInt
(
&
ok
);
...
...
@@ -66,20 +67,23 @@ KeyframeWidget::KeyframeWidget(std::shared_ptr<AssetParameterModel> model, QMode
m_time
=
new
TimecodeDisplay
(
pCore
->
getMonitor
(
m_model
->
monitorId
)
->
timecode
(),
this
);
m_time
->
setRange
(
0
,
duration
);
l
->
addWidget
(
m_keyframeview
,
0
,
0
,
1
,
-
1
);
l
->
addWidget
(
m_buttonPrevious
,
1
,
0
);
l
->
addWidget
(
m_buttonAddDelete
,
1
,
1
);
l
->
addWidget
(
m_buttonNext
,
1
,
2
);
l
->
addWidget
(
m_time
,
1
,
3
,
Qt
::
AlignRight
);
m_lay
->
addWidget
(
m_keyframeview
,
0
,
0
,
1
,
-
1
);
m_lay
->
addWidget
(
m_buttonPrevious
,
1
,
0
);
m_lay
->
addWidget
(
m_buttonAddDelete
,
1
,
1
);
m_lay
->
addWidget
(
m_buttonNext
,
1
,
2
);
m_lay
->
addWidget
(
m_time
,
1
,
3
,
Qt
::
AlignRight
);
slotSetPosition
(
0
,
false
);
connect
(
m_time
,
&
TimecodeDisplay
::
timeCodeEditingFinished
,
[
&
](){
slotSetPosition
(
-
1
,
true
);});
connect
(
m_keyframeview
,
&
KeyframeView
::
seekToPos
,
[
&
](
int
p
){
slotSetPosition
(
p
,
true
);});
connect
(
m_keyframeview
,
&
KeyframeView
::
atKeyframe
,
this
,
&
KeyframeWidget
::
slotAtKeyframe
);
connect
(
m_keyframeview
,
&
KeyframeView
::
modified
,
this
,
&
KeyframeWidget
::
slotRefreshParams
);
connect
(
m_buttonAddDelete
,
&
QAbstractButton
::
pressed
,
m_keyframeview
,
&
KeyframeView
::
slotAddRemove
);
connect
(
m_buttonPrevious
,
&
QAbstractButton
::
pressed
,
m_keyframeview
,
&
KeyframeView
::
slotGoToPrev
);
connect
(
m_buttonNext
,
&
QAbstractButton
::
pressed
,
m_keyframeview
,
&
KeyframeView
::
slotGoToNext
);
addParameter
(
index
);
}
KeyframeWidget
::~
KeyframeWidget
()
...
...
@@ -91,6 +95,13 @@ KeyframeWidget::~KeyframeWidget()
delete
m_time
;
}
void
KeyframeWidget
::
slotRefreshParams
()
{
int
pos
=
getPosition
();
for
(
const
auto
&
w
:
m_parameters
)
{
w
.
second
->
setValue
(
m_keyframes
->
getInterpolatedValue
(
pos
,
w
.
first
));
}
}
void
KeyframeWidget
::
slotSetPosition
(
int
pos
,
bool
update
)
{
if
(
pos
<
0
)
{
...
...
@@ -101,6 +112,8 @@ void KeyframeWidget::slotSetPosition(int pos, bool update)
m_keyframeview
->
slotSetPosition
(
pos
);
}
slotRefreshParams
();
if
(
update
)
{
emit
seekToPos
(
pos
);
}
...
...
@@ -134,6 +147,9 @@ void KeyframeWidget::slotAtKeyframe(bool atKeyframe)
m_buttonAddDelete
->
setIcon
(
KoIconUtils
::
themedIcon
(
QStringLiteral
(
"list-add"
)));
m_buttonAddDelete
->
setToolTip
(
i18n
(
"Add keyframe"
));
}
for
(
const
auto
&
w
:
m_parameters
)
{
w
.
second
->
setEnabled
(
atKeyframe
);
}
}
void
KeyframeWidget
::
slotSetRange
(
QPair
<
int
,
int
>
/*range*/
)
...
...
@@ -153,3 +169,29 @@ void KeyframeWidget::slotRefresh()
// refresh keyframes
m_keyframes
->
refresh
();
}
void
KeyframeWidget
::
addParameter
(
const
QPersistentModelIndex
&
index
)
{
QLocale
locale
;
locale
.
setNumberOptions
(
QLocale
::
OmitGroupSeparator
);
// Retrieve parameters from the model
QString
name
=
m_model
->
data
(
m_index
,
Qt
::
DisplayRole
).
toString
();
double
value
=
m_keyframes
->
getInterpolatedValue
(
getPosition
(),
index
);
double
min
=
m_model
->
data
(
m_index
,
AssetParameterModel
::
MinRole
).
toDouble
();
double
max
=
m_model
->
data
(
m_index
,
AssetParameterModel
::
MaxRole
).
toDouble
();
double
defaultValue
=
locale
.
toDouble
(
m_model
->
data
(
m_index
,
AssetParameterModel
::
DefaultRole
).
toString
());
QString
comment
=
m_model
->
data
(
m_index
,
AssetParameterModel
::
CommentRole
).
toString
();
QString
suffix
=
m_model
->
data
(
m_index
,
AssetParameterModel
::
SuffixRole
).
toString
();
int
decimals
=
m_model
->
data
(
m_index
,
AssetParameterModel
::
DecimalsRole
).
toInt
();
double
factor
=
m_model
->
data
(
m_index
,
AssetParameterModel
::
FactorRole
).
toDouble
();
// Construct object
auto
doubleWidget
=
new
DoubleWidget
(
name
,
value
,
min
,
max
,
defaultValue
,
comment
,
-
1
,
suffix
,
decimals
,
this
);
doubleWidget
->
factor
=
factor
;
m_parameters
[
index
]
=
doubleWidget
;
m_lay
->
addWidget
(
doubleWidget
,
1
+
(
int
)
m_parameters
.
size
(),
0
,
1
,
-
1
);
connect
(
doubleWidget
,
&
DoubleWidget
::
valueChanged
,
[
this
,
index
](
double
v
){
m_keyframes
->
updateKeyframe
(
GenTime
(
getPosition
(),
pCore
->
getCurrentFps
()),
v
,
index
);
});
}
src/assets/view/widgets/keyframewidget.hpp
View file @
cb49900d
...
...
@@ -24,10 +24,14 @@
#include
<QPersistentModelIndex>
#include
<memory>
#include
<unordered_map>
#include
"definitions.h"
class
AssetParameterModel
;
class
KeyframeModelLis
t
;
class
DoubleWidge
t
;
class
KeyframeView
;
class
KeyframeModelList
;
class
QGridLayout
;
class
QToolButton
;
class
TimecodeDisplay
;
...
...
@@ -39,6 +43,8 @@ public:
explicit
KeyframeWidget
(
std
::
shared_ptr
<
AssetParameterModel
>
model
,
QModelIndex
index
,
QWidget
*
parent
=
nullptr
);
~
KeyframeWidget
();
/* @brief Add a new parameter to be managed using the same keyframe viewer */
void
addParameter
(
const
QPersistentModelIndex
&
index
);
int
getPosition
()
const
;
void
addKeyframe
(
int
pos
=
-
1
);
...
...
@@ -50,9 +56,12 @@ public slots:
void
slotSetPosition
(
int
pos
=
-
1
,
bool
update
=
true
);
private
slots
:
/* brief Update the value of the widgets to reflect keyframe change */
void
slotRefreshParams
();
void
slotAtKeyframe
(
bool
atKeyframe
);
private:
QGridLayout
*
m_lay
;
std
::
shared_ptr
<
KeyframeModelList
>
m_keyframes
;
KeyframeView
*
m_keyframeview
;
...
...
@@ -60,6 +69,8 @@ private:
QToolButton
*
m_buttonPrevious
;
QToolButton
*
m_buttonNext
;
TimecodeDisplay
*
m_time
;
std
::
unordered_map
<
QPersistentModelIndex
,
DoubleWidget
*>
m_parameters
;
};
#endif
src/widgets/doublewidget.h
View file @
cb49900d
...
...
@@ -80,6 +80,9 @@ private:
signals:
void
valueChanged
(
double
);
// same signal as valueChanged, but add an extra boolean to tell if user is dragging value or not
void
valueChanging
(
double
,
bool
);
};
#endif
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