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
9afc4a55
Commit
9afc4a55
authored
Dec 12, 2020
by
Jean-Baptiste Mardelle
Browse files
Add preliminary support to copy a keyframe param value to other selected keyframes
parent
ee1d1a97
Changes
10
Hide whitespace changes
Inline
Side-by-side
src/assets/keyframes/model/keyframemodellist.cpp
View file @
9afc4a55
...
...
@@ -236,7 +236,7 @@ bool KeyframeModelList::updateKeyframe(GenTime oldPos, GenTime pos, const QVaria
return
applyOperation
(
op
,
logUndo
?
i18n
(
"Move keyframe"
)
:
QString
());
}
bool
KeyframeModelList
::
updateKeyframe
(
GenTime
pos
,
const
QVariant
&
value
,
const
QPersistentModelIndex
&
index
)
bool
KeyframeModelList
::
updateKeyframe
(
GenTime
pos
,
const
QVariant
&
value
,
const
QPersistentModelIndex
&
index
,
QUndoCommand
*
parentCommand
)
{
if
(
singleKeyframe
())
{
bool
ok
=
false
;
...
...
@@ -244,8 +244,10 @@ bool KeyframeModelList::updateKeyframe(GenTime pos, const QVariant &value, const
pos
=
kf
.
first
;
}
if
(
auto
ptr
=
m_model
.
lock
())
{
auto
*
command
=
new
AssetKeyframeCommand
(
ptr
,
index
,
value
,
pos
);
pCore
->
pushUndo
(
command
);
auto
*
command
=
new
AssetKeyframeCommand
(
ptr
,
index
,
value
,
pos
,
parentCommand
);
if
(
parentCommand
==
nullptr
)
{
pCore
->
pushUndo
(
command
);
}
}
return
true
;
}
...
...
@@ -546,3 +548,13 @@ GenTime KeyframeModelList::getPosAtIndex(int ix)
}
return
positions
.
at
(
ix
);
}
QModelIndex
KeyframeModelList
::
getIndexAtRow
(
int
row
)
{
for
(
auto
&
w
:
m_parameters
)
{
if
(
w
.
first
.
row
()
==
row
)
{
return
w
.
first
;
}
}
return
QModelIndex
();
}
src/assets/keyframes/model/keyframemodellist.hpp
View file @
9afc4a55
...
...
@@ -86,7 +86,7 @@ public:
@param value is the new value of the param
@param index is the index of the wanted keyframe
*/
bool
updateKeyframe
(
GenTime
pos
,
const
QVariant
&
value
,
const
QPersistentModelIndex
&
index
);
bool
updateKeyframe
(
GenTime
pos
,
const
QVariant
&
value
,
const
QPersistentModelIndex
&
index
,
QUndoCommand
*
parentCommand
=
nullptr
);
bool
updateKeyframeType
(
GenTime
pos
,
int
type
,
const
QPersistentModelIndex
&
index
);
bool
updateKeyframe
(
GenTime
oldPos
,
GenTime
pos
,
const
QVariant
&
normalizedVal
,
bool
logUndo
=
true
);
KeyframeType
keyframeType
(
GenTime
pos
)
const
;
...
...
@@ -149,6 +149,7 @@ public:
/** @brief Return position of the nth keyframe (ix = nth)*/
GenTime
getPosAtIndex
(
int
ix
);
QModelIndex
getIndexAtRow
(
int
row
);
/** @brief Check that all keyframable parameters have the same keyframes on loading
* (that's how our model works) */
...
...
src/assets/keyframes/view/keyframeview.cpp
View file @
9afc4a55
...
...
@@ -710,3 +710,46 @@ void KeyframeView::paintEvent(QPaintEvent *event)
p
.
setBrush
(
palette
().
highlight
());
p
.
drawRoundedRect
(
m_offset
+
(
width
()
-
m_offset
)
*
m_zoomHandle
.
x
(),
m_zoomHeight
+
3
,
(
width
()
-
2
*
m_offset
)
*
(
m_zoomHandle
.
y
()
-
m_zoomHandle
.
x
()),
m_size
-
m_zoomHeight
-
3
,
m_lineHeight
/
5
,
m_lineHeight
/
5
);
}
void
KeyframeView
::
copyCurrentValue
(
QModelIndex
ix
,
const
QString
paramName
)
{
const
QString
val
=
m_model
->
getInterpolatedValue
(
m_position
,
ix
).
toString
();
QString
newVal
;
const
QStringList
vals
=
val
.
split
(
QLatin1Char
(
' '
));
int
offset
=
pCore
->
getItemIn
(
m_model
->
getOwnerId
());
qDebug
()
<<
"=== COPYING VALS: "
<<
val
<<
", PARAM NAME_ "
<<
paramName
;
QUndoCommand
*
parentCommand
=
new
QUndoCommand
();
for
(
int
kf
:
m_selectedKeyframes
)
{
QString
oldValue
=
m_model
->
getInterpolatedValue
(
kf
,
ix
).
toString
();
QStringList
oldVals
=
oldValue
.
split
(
QLatin1Char
(
' '
));
if
(
paramName
==
QLatin1String
(
"spinX"
))
{
oldVals
[
0
]
=
vals
.
at
(
0
);
newVal
=
oldVals
.
join
(
QLatin1Char
(
' '
));
parentCommand
->
setText
(
i18n
(
"Update keyframes X position"
));
}
else
if
(
paramName
==
QLatin1String
(
"spinY"
))
{
oldVals
[
1
]
=
vals
.
at
(
1
);
newVal
=
oldVals
.
join
(
QLatin1Char
(
' '
));
parentCommand
->
setText
(
i18n
(
"Update keyframes Y position"
));
}
else
if
(
paramName
==
QLatin1String
(
"spinW"
))
{
oldVals
[
2
]
=
vals
.
at
(
2
);
newVal
=
oldVals
.
join
(
QLatin1Char
(
' '
));
parentCommand
->
setText
(
i18n
(
"Update keyframes width"
));
}
else
if
(
paramName
==
QLatin1String
(
"spinH"
))
{
oldVals
[
3
]
=
vals
.
at
(
3
);
newVal
=
oldVals
.
join
(
QLatin1Char
(
' '
));
parentCommand
->
setText
(
i18n
(
"Update keyframes height"
));
}
else
if
(
paramName
==
QLatin1String
(
"spinO"
))
{
oldVals
[
4
]
=
vals
.
at
(
4
);
newVal
=
oldVals
.
join
(
QLatin1Char
(
' '
));
parentCommand
->
setText
(
i18n
(
"Update keyframes opacity"
));
}
else
{
newVal
=
val
;
parentCommand
->
setText
(
i18n
(
"Update keyframes value"
));
}
qDebug
()
<<
"=== UPDATED VAL: "
<<
newVal
;
m_model
->
updateKeyframe
(
GenTime
(
kf
+
offset
,
pCore
->
getCurrentFps
()),
newVal
,
ix
,
parentCommand
);
}
pCore
->
pushUndo
(
parentCommand
);
//m_model->copyCurrentValue(paramName);
}
src/assets/keyframes/view/keyframeview.hpp
View file @
9afc4a55
...
...
@@ -35,6 +35,8 @@ public:
explicit
KeyframeView
(
std
::
shared_ptr
<
KeyframeModelList
>
model
,
int
duration
,
QWidget
*
parent
=
nullptr
);
void
setDuration
(
int
dur
);
const
QString
getAssetId
();
/** @brief Copy a keyframe parameter to selected keyframes. */
void
copyCurrentValue
(
QModelIndex
ix
,
const
QString
paramName
);
public
slots
:
/* @brief moves the current position*/
...
...
src/assets/view/widgets/keyframewidget.cpp
View file @
9afc4a55
...
...
@@ -92,6 +92,21 @@ KeyframeWidget::KeyframeWidget(std::shared_ptr<AssetParameterModel> model, QMode
m_buttonCopy
->
setIcon
(
QIcon
::
fromTheme
(
QStringLiteral
(
"edit-copy"
)));
m_buttonCopy
->
setToolTip
(
i18n
(
"Duplicate selected keyframe"
));
// Apply current value to selected keyframes
m_buttonApply
=
new
QToolButton
(
this
);
m_buttonApply
->
setAutoRaise
(
true
);
m_buttonApply
->
setIcon
(
QIcon
::
fromTheme
(
QStringLiteral
(
"edit-paste"
)));
m_buttonApply
->
setToolTip
(
i18n
(
"Apply value to selected keyframes"
));
m_buttonApply
->
setFocusPolicy
(
Qt
::
StrongFocus
);
connect
(
qApp
,
&
QApplication
::
focusChanged
,
[
this
](
QWidget
*
old
,
QWidget
*
now
)
{
if
(
now
==
m_buttonApply
)
{
if
(
old
&&
old
->
parentWidget
())
{
m_lastFocusedParam
=
old
->
parentWidget
()
->
objectName
();
qDebug
()
<<
"======= FROM PARENT: "
<<
old
->
parentWidget
()
->
objectName
();
}
}
});
// 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
);
...
...
@@ -124,6 +139,7 @@ KeyframeWidget::KeyframeWidget(std::shared_ptr<AssetParameterModel> model, QMode
m_toolbar
->
addWidget
(
m_buttonNext
);
m_toolbar
->
addWidget
(
m_buttonCenter
);
m_toolbar
->
addWidget
(
m_buttonCopy
);
m_toolbar
->
addWidget
(
m_buttonApply
);
m_toolbar
->
addAction
(
m_selectType
);
QAction
*
seekKeyframe
=
new
QAction
(
i18n
(
"Seek to keyframe on select"
),
this
);
...
...
@@ -199,6 +215,23 @@ KeyframeWidget::KeyframeWidget(std::shared_ptr<AssetParameterModel> model, QMode
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
);
connect
(
m_buttonApply
,
&
QAbstractButton
::
pressed
,
[
this
]()
{
if
(
!
m_lastFocusedParam
.
isEmpty
())
{
qDebug
()
<<
"=== ADJUSTING KF PARAM: "
<<
m_lastFocusedParam
;
if
(
m_lastFocusedParam
.
startsWith
(
QLatin1String
(
"spin"
)))
{
for
(
const
auto
&
w
:
m_parameters
)
{
auto
type
=
m_model
->
data
(
w
.
first
,
AssetParameterModel
::
TypeRole
).
value
<
ParamType
>
();
if
(
type
!=
ParamType
::
AnimatedRect
)
{
continue
;
}
QModelIndex
ix
=
w
.
first
;
m_keyframeview
->
copyCurrentValue
(
ix
,
m_lastFocusedParam
);
}
}
else
{
m_keyframeview
->
copyCurrentValue
(
m_keyframes
->
getIndexAtRow
(
m_lastFocusedParam
.
toInt
()),
QString
());
}
}
});
//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
();
...
...
@@ -422,6 +455,7 @@ void KeyframeWidget::addParameter(const QPersistentModelIndex &index)
emit
activateEffect
();
m_keyframes
->
updateKeyframe
(
GenTime
(
getPosition
(),
pCore
->
getCurrentFps
()),
QVariant
(
v
),
index
);
});
doubleWidget
->
setDragObjectName
(
QString
::
number
(
index
.
row
()));
paramWidget
=
doubleWidget
;
}
if
(
paramWidget
)
{
...
...
src/assets/view/widgets/keyframewidget.hpp
View file @
9afc4a55
...
...
@@ -94,6 +94,7 @@ private:
QToolButton
*
m_buttonNext
;
QToolButton
*
m_buttonCenter
;
QToolButton
*
m_buttonCopy
;
QToolButton
*
m_buttonApply
;
KSelectAction
*
m_selectType
;
TimecodeDisplay
*
m_time
;
MonitorSceneType
m_neededScene
;
...
...
@@ -102,6 +103,7 @@ private:
std
::
unordered_map
<
QPersistentModelIndex
,
QWidget
*>
m_parameters
;
int
m_baseHeight
;
int
m_addedHeight
;
QString
m_lastFocusedParam
;
signals:
void
addIndex
(
QPersistentModelIndex
ix
);
...
...
src/widgets/doublewidget.cpp
View file @
9afc4a55
...
...
@@ -43,6 +43,11 @@ DoubleWidget::DoubleWidget(const QString &name, double value, double min, double
connect
(
m_dragVal
,
&
DragValue
::
valueChanged
,
this
,
&
DoubleWidget
::
slotSetValue
);
}
void
DoubleWidget
::
setDragObjectName
(
const
QString
&
name
)
{
m_dragVal
->
setObjectName
(
name
);
}
bool
DoubleWidget
::
hasEditFocus
()
const
{
return
m_dragVal
->
hasEditFocus
();
...
...
src/widgets/doublewidget.h
View file @
9afc4a55
...
...
@@ -58,6 +58,8 @@ public:
void
enableEdit
(
bool
enable
);
/** @brief Returns true if widget is currently being edited */
bool
hasEditFocus
()
const
;
/** @brief Define dragValue object name */
void
setDragObjectName
(
const
QString
&
name
);
public
slots
:
/** @brief Sets the value to @param value. */
...
...
src/widgets/dragvalue.cpp
View file @
9afc4a55
...
...
@@ -59,6 +59,7 @@ DragValue::DragValue(const QString &label, double defaultValue, int decimals, do
l
->
setSpacing
(
0
);
l
->
setContentsMargins
(
0
,
0
,
0
,
0
);
m_label
=
new
CustomLabel
(
label
,
showSlider
,
m_maximum
-
m_minimum
,
this
);
m_label
->
setObjectName
(
"draggLabel"
);
l
->
addWidget
(
m_label
);
setMinimumHeight
(
m_label
->
sizeHint
().
height
());
if
(
decimals
==
0
)
{
...
...
src/widgets/geometrywidget.cpp
View file @
9afc4a55
...
...
@@ -56,14 +56,17 @@ GeometryWidget::GeometryWidget(Monitor *monitor, QPair<int, int> range, const QR
m_spinX
=
new
DragValue
(
i18nc
(
"x axis position"
,
"X"
),
0
,
0
,
-
99000
,
99000
,
-
1
,
QString
(),
false
,
false
,
this
);
connect
(
m_spinX
,
&
DragValue
::
valueChanged
,
this
,
&
GeometryWidget
::
slotAdjustRectKeyframeValue
);
horLayout
->
addWidget
(
m_spinX
);
m_spinX
->
setObjectName
(
"spinX"
);
m_spinY
=
new
DragValue
(
i18nc
(
"y axis position"
,
"Y"
),
0
,
0
,
-
99000
,
99000
,
-
1
,
QString
(),
false
,
false
,
this
);
connect
(
m_spinY
,
&
DragValue
::
valueChanged
,
this
,
&
GeometryWidget
::
slotAdjustRectKeyframeValue
);
horLayout
->
addWidget
(
m_spinY
);
m_spinY
->
setObjectName
(
"spinY"
);
m_spinWidth
=
new
DragValue
(
i18nc
(
"Frame width"
,
"W"
),
m_defaultSize
.
width
(),
0
,
1
,
99000
,
-
1
,
QString
(),
false
,
false
,
this
);
connect
(
m_spinWidth
,
&
DragValue
::
valueChanged
,
this
,
&
GeometryWidget
::
slotAdjustRectWidth
);
horLayout
->
addWidget
(
m_spinWidth
);
m_spinWidth
->
setObjectName
(
"spinW"
);
// Lock ratio stuff
m_lockRatio
=
new
QAction
(
QIcon
::
fromTheme
(
QStringLiteral
(
"link"
)),
i18n
(
"Lock aspect ratio"
),
this
);
...
...
@@ -75,6 +78,7 @@ GeometryWidget::GeometryWidget(Monitor *monitor, QPair<int, int> range, const QR
m_spinHeight
=
new
DragValue
(
i18nc
(
"Frame height"
,
"H"
),
m_defaultSize
.
height
(),
0
,
1
,
99000
,
-
1
,
QString
(),
false
,
false
,
this
);
connect
(
m_spinHeight
,
&
DragValue
::
valueChanged
,
this
,
&
GeometryWidget
::
slotAdjustRectHeight
);
m_spinHeight
->
setObjectName
(
"spinH"
);
horLayout
->
addWidget
(
m_spinHeight
);
horLayout
->
addStretch
(
10
);
...
...
@@ -82,6 +86,7 @@ GeometryWidget::GeometryWidget(Monitor *monitor, QPair<int, int> range, const QR
horLayout2
->
setSpacing
(
2
);
m_spinSize
=
new
DragValue
(
i18n
(
"Size"
),
100
,
2
,
1
,
99000
,
-
1
,
i18n
(
"%"
),
false
,
false
,
this
);
m_spinSize
->
setStep
(
5
);
m_spinSize
->
setObjectName
(
"spinS"
);
connect
(
m_spinSize
,
&
DragValue
::
valueChanged
,
this
,
&
GeometryWidget
::
slotResize
);
horLayout2
->
addWidget
(
m_spinSize
);
...
...
@@ -89,6 +94,7 @@ GeometryWidget::GeometryWidget(Monitor *monitor, QPair<int, int> range, const QR
m_opacity
=
new
DragValue
(
i18n
(
"Opacity"
),
100
,
0
,
0
,
100
,
-
1
,
i18n
(
"%"
),
true
,
false
,
this
);
m_opacity
->
setValue
((
int
)(
opacity
*
m_opacityFactor
));
connect
(
m_opacity
,
&
DragValue
::
valueChanged
,
this
,
[
&
]()
{
emit
valueChanged
(
getValue
());
});
m_opacity
->
setObjectName
(
"spinO"
);
horLayout2
->
addWidget
(
m_opacity
);
}
horLayout2
->
addStretch
(
10
);
...
...
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