Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Fix handling of composition keyframes in timeline

parent 807d5886
......@@ -134,7 +134,9 @@ bool CompositionModel::requestResize(int size, bool right, Fun &undo, Fun &redo,
auto kfr = getKeyframeModel();
if (kfr) {
// Adjust keyframe length
kfr->resizeKeyframes(0, oldDuration, 0, out, undo, redo);
if (oldDuration > 0) {
kfr->resizeKeyframes(0, oldDuration, 0, out - in, undo, redo);
}
Fun refresh = [kfr, this]() {
kfr->modelChanged();
return true;
......@@ -205,6 +207,7 @@ void CompositionModel::setATrack(int trackMltPosition, int trackId)
KeyframeModel *CompositionModel::getEffectKeyframeModel()
{
prepareKeyframes();
if (getKeyframeModel()) {
return getKeyframeModel()->getKeyModel();
}
......
......@@ -427,14 +427,14 @@ void TimelineFunctions::showClipKeyframes(std::shared_ptr<TimelineItemModel> tim
{
timeline->m_allClips[clipId]->setShowKeyframes(value);
QModelIndex modelIndex = timeline->makeClipIndexFromID(clipId);
timeline->dataChanged(modelIndex, modelIndex, {TimelineModel::KeyframesRole});
timeline->dataChanged(modelIndex, modelIndex, {TimelineModel::ShowKeyframesRole});
}
void TimelineFunctions::showCompositionKeyframes(std::shared_ptr<TimelineItemModel> timeline, int compoId, bool value)
{
timeline->m_allCompositions[compoId]->setShowKeyframes(value);
QModelIndex modelIndex = timeline->makeCompositionIndexFromID(compoId);
timeline->dataChanged(modelIndex, modelIndex, {TimelineModel::KeyframesRole});
timeline->dataChanged(modelIndex, modelIndex, {TimelineModel::ShowKeyframesRole});
}
bool TimelineFunctions::switchEnableState(std::shared_ptr<TimelineItemModel> timeline, int clipId)
......
......@@ -393,6 +393,7 @@ Rectangle {
selected: clipRoot.selected
inPoint: clipRoot.inPoint
outPoint: clipRoot.outPoint
masterObject: clipRoot
}
}
......
......@@ -114,80 +114,14 @@ Item {
var itemPos = mapToItem(tracksContainerArea, 0, displayRect.y, displayRect.width, displayRect.height)
initDrag(compositionRoot, itemPos, compositionRoot.clipId, compositionRoot.modelStart, compositionRoot.trackId, true)
}
Rectangle {
id: displayRect
MouseArea {
id: mouseArea
anchors.top: compositionRoot.top
anchors.right: compositionRoot.right
anchors.left: compositionRoot.left
anchors.topMargin: displayHeight
height: displayHeight
color: Qt.darker('mediumpurple')
border.color: selected? 'red' : borderColor
border.width: isGrabbed ? 8 : 1.5
opacity: dragProxyArea.drag.active && dragProxy.draggedItem == clipId ? 0.5 : 1.0
Item {
// clipping container
id: container
anchors.fill: displayRect
anchors.margins:1.5
clip: true
Rectangle {
// text background
id: labelRect
color: compositionRoot.aTrack >= 0 ? 'yellow' : 'lightgray'
opacity: 0.7
anchors.top: container.top
width: label.width + 2
height: label.height
Text {
id: label
text: clipName + (compositionRoot.aTrack >= 0 ? ' > ' + timeline.getTrackNameFromMltIndex(compositionRoot.aTrack) : '')
font.pixelSize: root.baseUnit
anchors {
top: labelRect.top
left: labelRect.left
topMargin: 1
leftMargin: 1
}
color: 'black'
}
}
KeyframeView {
id: effectRow
visible: compositionRoot.showKeyframes && keyframeModel
selected: compositionRoot.selected
inPoint: 0
outPoint: compositionRoot.clipDuration
}
}
/*Drag.active: mouseArea.drag.active
Drag.proposedAction: Qt.MoveAction*/
states: [
State {
name: 'normal'
when: !compositionRoot.selected
PropertyChanges {
target: compositionRoot
z: 0
}
},
State {
name: 'selected'
when: compositionRoot.selected
PropertyChanges {
target: compositionRoot
z: 1
color: 'mediumpurple'
}
}
]
MouseArea {
id: mouseArea
anchors.fill: parent
//anchors.fill: parent
acceptedButtons: Qt.RightButton
hoverEnabled: true
/*onPressed: {
......@@ -253,6 +187,77 @@ Item {
onWheel: zoomByWheel(wheel)
}
Rectangle {
id: displayRect
anchors.top: compositionRoot.top
anchors.right: compositionRoot.right
anchors.left: compositionRoot.left
anchors.topMargin: displayHeight
height: displayHeight
color: Qt.darker('mediumpurple')
border.color: selected? 'red' : borderColor
border.width: isGrabbed ? 8 : 1.5
opacity: dragProxyArea.drag.active && dragProxy.draggedItem == clipId ? 0.5 : 1.0
Item {
// clipping container
id: container
anchors.fill: displayRect
anchors.margins:1.5
clip: true
Rectangle {
// text background
id: labelRect
color: compositionRoot.aTrack >= 0 ? 'yellow' : 'lightgray'
opacity: 0.7
anchors.top: container.top
width: label.width + 2
height: label.height
Text {
id: label
text: clipName + (compositionRoot.aTrack >= 0 ? ' > ' + timeline.getTrackNameFromMltIndex(compositionRoot.aTrack) : '')
font.pixelSize: root.baseUnit
anchors {
top: labelRect.top
left: labelRect.left
topMargin: 1
leftMargin: 1
}
color: 'black'
}
}
KeyframeView {
id: effectRow
visible: compositionRoot.showKeyframes && compositionRoot.keyframeModel
selected: compositionRoot.selected
inPoint: 0
outPoint: compositionRoot.clipDuration
masterObject: compositionRoot
}
}
/*Drag.active: mouseArea.drag.active
Drag.proposedAction: Qt.MoveAction*/
states: [
State {
name: 'normal'
when: !compositionRoot.selected
PropertyChanges {
target: compositionRoot
z: 0
}
},
State {
name: 'selected'
when: compositionRoot.selected
PropertyChanges {
target: compositionRoot
z: 1
color: 'mediumpurple'
}
}
]
Rectangle {
id: trimIn
anchors.left: displayRect.left
......
......@@ -27,13 +27,14 @@ Rectangle
{
property alias kfrCount : keyframes.count
anchors.fill: parent
color: Qt.rgba(1,1,1, 0.6)
color: Qt.rgba(1,1,0.8, 0.3)
id: keyframeContainer
property int activeFrame
property int activeIndex
property int inPoint
property int outPoint
property bool selected
property var masterObject
onKfrCountChanged: {
keyframecanvas.requestPaint()
......@@ -155,7 +156,7 @@ Rectangle
root.stopScrolling = false
var newPos = frame == inPoint ? inPoint : Math.round((keyframe.x + parent.x + root.baseUnit / 2) / timeScale) + inPoint
if (newPos == frame && keyframe.value == keyframe.height - parent.y - root.baseUnit / 2) {
var pos = clipRoot.modelStart + frame - inPoint
var pos = masterObject.modelStart + frame - inPoint
if (timeline.position != pos) {
timeline.seekPosition = pos
timeline.position = timeline.seekPosition
......@@ -164,7 +165,7 @@ Rectangle
}
var newVal = (keyframeContainer.height - (parent.y + mouse.y)) / keyframeContainer.height
if (frame != inPoint && (newVal > 1.5 || newVal < -0.5)) {
timeline.removeClipEffectKeyframe(clipRoot.clipId, frame);
timeline.removeEffectKeyframe(masterObject.clipId, frame);
} else {
if (newVal < 0) {
newVal = 0;
......@@ -175,7 +176,7 @@ Rectangle
parent.y = - (root.baseUnit / 2)
keyframecanvas.requestPaint()
}
timeline.updateClipEffectKeyframe(clipRoot.clipId, frame, newPos, newVal)
timeline.updateEffectKeyframe(masterObject.clipId, frame, newPos, newVal)
}
}
onPositionChanged: {
......@@ -190,7 +191,7 @@ Rectangle
}
}
onDoubleClicked: {
timeline.removeClipEffectKeyframe(clipRoot.clipId, frame);
timeline.removeEffectKeyframe(masterObject.clipId, frame);
}
}
}
......
......@@ -1025,9 +1025,9 @@ Rectangle {
}
onDoubleClicked: {
if (dragProxy.masterObject.keyframeModel) {
var newVal = (dragProxy.masterObject.height - mouseY) / dragProxy.masterObject.height
var newVal = (dragProxy.height - mouseY) / dragProxy.height
var newPos = Math.round(mouseX / timeScale) + dragProxy.masterObject.inPoint
timeline.addClipEffectKeyframe(dragProxy.draggedItem, newPos, newVal)
timeline.addEffectKeyframe(dragProxy.draggedItem, newPos, newVal)
}
}
}
......
......@@ -29,6 +29,7 @@
#include "dialogs/spacerdialog.h"
#include "doc/kdenlivedoc.h"
#include "effects/effectstack/model/effectstackmodel.hpp"
#include "assets/keyframes/model/keyframemodellist.hpp"
#include "kdenlivesettings.h"
#include "previewmanager.h"
#include "project/projectmanager.h"
......@@ -2277,27 +2278,36 @@ void TimelineController::saveTimelineSelection(QDir targetDir)
TimelineFunctions::saveTimelineSelection(m_model, m_selection.selectedItems, targetDir);
}
void TimelineController::addClipEffectKeyframe(int cid, int frame, double val)
void TimelineController::addEffectKeyframe(int cid, int frame, double val)
{
if (m_model->isClip(cid)) {
std::shared_ptr<EffectStackModel> destStack = m_model->getClipEffectStackModel(cid);
destStack->addEffectKeyFrame(frame, val);
} else if (m_model->isComposition(cid)) {
std::shared_ptr<KeyframeModelList> listModel = m_model->m_allCompositions[cid]->getKeyframeModel();
listModel->addKeyframe(frame, val);
}
}
void TimelineController::removeClipEffectKeyframe(int cid, int frame)
void TimelineController::removeEffectKeyframe(int cid, int frame)
{
if (m_model->isClip(cid)) {
std::shared_ptr<EffectStackModel> destStack = m_model->getClipEffectStackModel(cid);
destStack->removeKeyFrame(frame);
} else if (m_model->isComposition(cid)) {
std::shared_ptr<KeyframeModelList> listModel = m_model->m_allCompositions[cid]->getKeyframeModel();
listModel->removeKeyframe(GenTime(frame, pCore->getCurrentFps()));
}
}
void TimelineController::updateClipEffectKeyframe(int cid, int oldFrame, int newFrame, double normalizedValue)
void TimelineController::updateEffectKeyframe(int cid, int oldFrame, int newFrame, double normalizedValue)
{
if (m_model->isClip(cid)) {
std::shared_ptr<EffectStackModel> destStack = m_model->getClipEffectStackModel(cid);
destStack->updateKeyFrame(oldFrame, newFrame, normalizedValue);
} else if (m_model->isComposition(cid)) {
std::shared_ptr<KeyframeModelList> listModel = m_model->m_allCompositions[cid]->getKeyframeModel();
listModel->updateKeyframe(GenTime(oldFrame, pCore->getCurrentFps()), GenTime(newFrame, pCore->getCurrentFps()), normalizedValue);
}
}
......@@ -305,9 +305,9 @@ public:
*/
Q_INVOKABLE void pasteEffects(int targetId = -1);
Q_INVOKABLE double fps() const;
Q_INVOKABLE void addClipEffectKeyframe(int cid, int frame, double val);
Q_INVOKABLE void removeClipEffectKeyframe(int cid, int frame);
Q_INVOKABLE void updateClipEffectKeyframe(int cid, int oldFrame, int newFrame, double normalizedValue);
Q_INVOKABLE void addEffectKeyframe(int cid, int frame, double val);
Q_INVOKABLE void removeEffectKeyframe(int cid, int frame);
Q_INVOKABLE void updateEffectKeyframe(int cid, int oldFrame, int newFrame, double normalizedValue);
void switchTrackLock(bool applyToAll = false);
void switchTargetTrack();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment