Commit d29a962a authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Keyframe fixes: fix keyframe view not updated on clip resize and timeline...

Keyframe fixes: fix keyframe view not updated on clip resize and timeline position in keyframe view not updated on clip move
Related to #926
parent 58d2b03f
Pipeline #148232 passed with stage
in 6 minutes and 31 seconds
......@@ -15,6 +15,7 @@
#include "transitions/transitionsrepository.hpp"
#include "transitions/view/mixstackview.hpp"
#include "transitions/view/transitionstackview.hpp"
#include "monitor/monitor.h"
#include "view/assetparameterview.hpp"
......@@ -525,3 +526,18 @@ void AssetPanel::slotPreviousKeyframe()
emit m_mixWidget->previousKeyframe();
}
}
void AssetPanel::updateAssetPosition(int itemId)
{
if (m_effectStackWidget->isVisible()) {
ObjectId id = {ObjectType::TimelineClip, itemId};
if (m_effectStackWidget->stackOwner() == id) {
emit pCore->getMonitor(Kdenlive::ProjectMonitor)->seekPosition(pCore->getTimelinePosition());
}
} else if (m_transitionWidget->isVisible()) {
ObjectId id = {ObjectType::TimelineComposition, itemId};
if (m_transitionWidget->stackOwner() == id) {
emit pCore->getMonitor(Kdenlive::ProjectMonitor)->seekPosition(pCore->getTimelinePosition());
}
}
}
......@@ -70,6 +70,8 @@ public slots:
void slotAddRemoveKeyframe();
void slotNextKeyframe();
void slotPreviousKeyframe();
/** @brief Update timelinbe position in keyframe views */
void updateAssetPosition(int itemId);
protected:
/** @brief Return the stylesheet used to display the panel (based on current palette). */
......
......@@ -231,7 +231,7 @@ void AssetParameterView::refresh(const QModelIndex &topLeft, const QModelIndex &
}
Q_ASSERT(max < m_widgets.size());
for (auto i = size_t(topLeft.row()); i <= max; ++i) {
m_widgets[i]->slotRefresh();
m_widgets.at(i)->slotRefresh();
}
}
......
......@@ -465,18 +465,20 @@ void KeyframeWidget::slotRefresh()
int in = m_model->data(m_index, AssetParameterModel::InRole).toInt(&ok);
int out = in + duration;
// m_model->dataChanged(QModelIndex(), QModelIndex());
//->getKeyframeModel()->getKeyModel(m_index)->dataChanged(QModelIndex(), QModelIndex());
m_keyframeview->setDuration(duration, in);
m_time->setRange(0, duration - 1);
m_time->setOffset(in);
int pos = m_time->getValue();
bool isInRange = pos >= in && pos < out;
connectMonitor(isInRange && m_model->isActive());
m_addDeleteAction->setEnabled(isInRange && pos > in);
int framePos = qBound(in, pos, out) - in;
if (isInRange && framePos != m_time->getValue()) {
slotSetPosition(framePos, false);
if (m_model->monitorId == Kdenlive::ProjectMonitor) {
monitorSeek(pCore->getTimelinePosition());
} else {
int pos = m_time->getValue();
bool isInRange = pos >= in && pos < out;
connectMonitor(isInRange && m_model->isActive());
m_addDeleteAction->setEnabled(isInRange && pos > in);
int framePos = qBound(in, pos, out) - in;
if (isInRange && framePos != m_time->getValue()) {
slotSetPosition(framePos, false);
}
}
slotRefreshParams();
}
......
......@@ -665,7 +665,7 @@ bool EffectStackModel::adjustStackLength(bool adjustFromEnd, int oldIn, int oldD
keyframes->resizeKeyframes(oldIn, oldIn + oldDuration, newIn, out - 1, offset, adjustFromEnd, undo, redo);
QModelIndex index = getIndexFromItem(effect);
Fun refresh = [effect, index]() {
emit effect->dataChanged(index, index, QVector<int>());
emit effect->dataChanged(index, QModelIndex(), QVector<int>());
return true;
};
refresh();
......
......@@ -406,6 +406,9 @@ void MainWindow::init(const QString &mltPath)
connect(m_timelineTabs, &TimelineTabs::showItemEffectStack, this, [&] () {
m_effectStackDock->raise();
});
connect(m_timelineTabs, &TimelineTabs::updateAssetPosition, m_assetPanel, &AssetPanel::updateAssetPosition);
connect(m_timelineTabs, &TimelineTabs::showSubtitle, this, [&, subtitlesDock] (int id) {
if (id > -1) {
......
......@@ -224,32 +224,9 @@ bool ClipModel::requestResize(int size, bool right, Fun &undo, Fun &redo, bool l
} else {
roles.push_back(TimelineModel::OutPointRole);
}
Fun operation = [this, inPoint, outPoint, roles, oldIn, oldOut, right, logUndo, track_operation]() {
Fun operation = [this, inPoint, outPoint, roles, logUndo, track_operation]() {
if (track_operation()) {
setInOut(inPoint, outPoint);
if (m_currentTrackId > -1) {
if (auto ptr = m_parent.lock()) {
QModelIndex ix = ptr->makeClipIndexFromID(m_id);
ptr->notifyChange(ix, ix, roles);
// invalidate timeline preview
if (logUndo && !ptr->getTrackById_const(m_currentTrackId)->isAudioTrack()) {
if (right) {
int newOut = m_position + getOut() - getIn();
if (oldOut < newOut) {
emit ptr->invalidateZone(oldOut, newOut);
} else {
emit ptr->invalidateZone(newOut, oldOut);
}
} else {
if (oldIn < m_position) {
emit ptr->invalidateZone(oldIn, m_position);
} else {
emit ptr->invalidateZone(m_position, oldIn);
}
}
}
}
}
if (logUndo && !m_endlessResize) {
emit pCore->clipInstanceResized(m_binClipId);
}
......@@ -257,8 +234,33 @@ bool ClipModel::requestResize(int size, bool right, Fun &undo, Fun &redo, bool l
}
return false;
};
Fun postProcess = [this, roles, oldIn, oldOut, right, logUndo]() {
if (m_currentTrackId > -1) {
if (auto ptr = m_parent.lock()) {
QModelIndex ix = ptr->makeClipIndexFromID(m_id);
ptr->notifyChange(ix, ix, roles);
// invalidate timeline preview
if (logUndo && !ptr->getTrackById_const(m_currentTrackId)->isAudioTrack()) {
if (right) {
int newOut = m_position + getOut() - getIn();
if (oldOut < newOut) {
emit ptr->invalidateZone(oldOut, newOut);
} else {
emit ptr->invalidateZone(newOut, oldOut);
}
} else {
if (oldIn < m_position) {
emit ptr->invalidateZone(oldIn, m_position);
} else {
emit ptr->invalidateZone(m_position, oldIn);
}
}
}
}
}
return true;
};
if (operation()) {
Fun reverse = []() { return true; };
// Now, we are in the state in which the timeline should be when we try to revert current action. So we can build the reverse action from here
if (m_currentTrackId != -1) {
if (auto ptr = m_parent.lock()) {
......@@ -273,31 +275,9 @@ bool ClipModel::requestResize(int size, bool right, Fun &undo, Fun &redo, bool l
track_reverse = ptr->getTrackById(m_currentTrackId)->requestClipResize_lambda(m_id, old_in, old_out, right, hasMix);
}
}
reverse = [this, old_in, old_out, track_reverse, logUndo, oldIn, oldOut, right, roles]() {
Fun reverse = [this, old_in, old_out, track_reverse, logUndo, oldIn, oldOut, right, roles]() {
if (track_reverse()) {
setInOut(old_in, old_out);
if (m_currentTrackId > -1) {
if (auto ptr = m_parent.lock()) {
QModelIndex ix = ptr->makeClipIndexFromID(m_id);
ptr->notifyChange(ix, ix, roles);
if (logUndo && !ptr->getTrackById_const(m_currentTrackId)->isAudioTrack()) {
if (right) {
int newOut = m_position + getOut() - getIn();
if (oldOut < newOut) {
emit ptr->invalidateZone(oldOut, newOut);
} else {
emit ptr->invalidateZone(newOut, oldOut);
}
} else {
if (oldIn < m_position) {
emit ptr->invalidateZone(oldIn, m_position);
} else {
emit ptr->invalidateZone(m_position, oldIn);
}
}
}
}
}
if (logUndo && !m_endlessResize) {
emit pCore->clipInstanceResized(m_binClipId);
}
......@@ -306,6 +286,31 @@ bool ClipModel::requestResize(int size, bool right, Fun &undo, Fun &redo, bool l
qDebug()<<"============\n+++++++++++++++++\nREVRSE TRACK OP FAILED\n\n++++++++++++++++";
return false;
};
Fun preProcess = [this, roles, oldIn, oldOut, newIn = m_position, newOut = m_position + getOut() - getIn(), right, logUndo]() {
if (m_currentTrackId > -1) {
if (auto ptr = m_parent.lock()) {
QModelIndex ix = ptr->makeClipIndexFromID(m_id);
ptr->notifyChange(ix, ix, roles);
// invalidate timeline preview
if (logUndo && !ptr->getTrackById_const(m_currentTrackId)->isAudioTrack()) {
if (right) {
if (oldOut < newOut) {
emit ptr->invalidateZone(oldOut, newOut);
} else {
emit ptr->invalidateZone(newOut, oldOut);
}
} else {
if (oldIn < newIn) {
emit ptr->invalidateZone(oldIn, newIn);
} else {
emit ptr->invalidateZone(newIn, oldIn);
}
}
}
}
}
return true;
};
if (logUndo) {
qDebug() << "----------\n-----------\n// ADJUSTING EFFECT LENGTH, LOGUNDO " << logUndo << ", " << old_in << "/" << inPoint << "-"
<<outPoint<<", "<< m_producer->get_playtime();
......@@ -318,6 +323,9 @@ bool ClipModel::requestResize(int size, bool right, Fun &undo, Fun &redo, bool l
}
adjustEffectLength(right, old_in, inPoint, old_out - old_in, m_producer->get_playtime(), offset, reverse, operation, logUndo);
}
postProcess();
PUSH_LAMBDA(postProcess, operation);
PUSH_LAMBDA(preProcess, reverse);
UPDATE_UNDO_REDO(operation, reverse, undo, redo);
return true;
}
......@@ -757,7 +765,6 @@ bool ClipModel::adjustEffectLength(bool adjustFromEnd, int oldIn, int newIn, int
bool ClipModel::adjustEffectLength(const QString &effectName, int duration, int originalDuration, Fun &undo, Fun &redo)
{
QWriteLocker locker(&m_lock);
qDebug() << ".... ADJUSTING FADE LENGTH: " << duration << " / " << effectName;
Fun operation = [this, duration, effectName, originalDuration]() {
return m_effectStack->adjustFadeLength(duration, effectName.startsWith(QLatin1String("fadein")) || effectName.startsWith(QLatin1String("fade_to_")), audioEnabled(),
!isAudioOnly(), originalDuration > 0);
......
......@@ -127,6 +127,7 @@ void TimelineController::setModel(std::shared_ptr<TimelineItemModel> model)
connect(m_model.get(), &TimelineModel::selectionChanged, this, &TimelineController::selectionChanged);
connect(m_model.get(), &TimelineModel::selectedMixChanged, this, &TimelineController::showMixModel);
connect(m_model.get(), &TimelineModel::selectedMixChanged, this, &TimelineController::selectedMixChanged);
connect(m_model.get(), &TimelineModel::dataChanged, this, &TimelineController::checkClipPosition);
connect(m_model.get(), &TimelineModel::checkTrackDeletion, this, &TimelineController::checkTrackDeletion, Qt::DirectConnection);
}
......@@ -5022,3 +5023,13 @@ void TimelineController::setMulticamIn(int pos)
m_model->addSnap(multicamIn);
emit multicamInChanged();
}
void TimelineController::checkClipPosition(const QModelIndex &topLeft, const QModelIndex &, const QVector<int> &roles)
{
if (roles.contains(TimelineModel::StartRole)) {
int id = int(topLeft.internalId());
if (m_model->isComposition(id) || m_model->isClip(id)) {
emit updateAssetPosition(id);
}
}
}
......@@ -694,6 +694,8 @@ public slots:
Q_INVOKABLE void updateZone(const QPoint oldZone, const QPoint newZone, bool withUndo = true);
Q_INVOKABLE void updateEffectZone(const QPoint oldZone, const QPoint newZone, bool withUndo = true);
void updateTrimmingMode();
/** @brief When a clip or composition is moved, inform asset panel to update cursor position in keyframe views. */
void checkClipPosition(const QModelIndex &topLeft, const QModelIndex &, const QVector<int> &roles);
private slots:
void updateClipActions();
......@@ -809,6 +811,7 @@ signals:
void masterZonesChanged();
Q_INVOKABLE void ungrabHack();
void regainFocus();
void updateAssetPosition(int itemId);
};
#endif
......@@ -71,6 +71,7 @@ void TimelineTabs::connectTimeline(TimelineWidget *timeline)
connect(timeline->controller(), &TimelineController::updateZoom, this, [&](double value) { emit updateZoom(getCurrentTimeline()->zoomForScale(value)); });
connect(timeline->controller(), &TimelineController::showItemEffectStack, this, &TimelineTabs::showItemEffectStack);
connect(timeline->controller(), &TimelineController::showSubtitle, this, &TimelineTabs::showSubtitle);
connect(timeline->controller(), &TimelineController::updateAssetPosition, this, &TimelineTabs::updateAssetPosition);
connect(timeline->controller(), &TimelineController::centerView, timeline, &TimelineWidget::slotCenterView);
}
......@@ -86,5 +87,6 @@ void TimelineTabs::disconnectTimeline(TimelineWidget *timeline)
disconnect(timeline->controller(), &TimelineController::showMixModel, this, &TimelineTabs::showMixModel);
disconnect(timeline->controller(), &TimelineController::showItemEffectStack, this, &TimelineTabs::showItemEffectStack);
disconnect(timeline->controller(), &TimelineController::showSubtitle, this, &TimelineTabs::showSubtitle);
disconnect(timeline->controller(), &TimelineController::updateAssetPosition, this, &TimelineTabs::updateAssetPosition);
delete timeline;
}
......@@ -73,6 +73,7 @@ signals:
/** @brief Requests that a given effectstack model is displayed in the asset panel */
void showItemEffectStack(const QString &clipName, std::shared_ptr<EffectStackModel>, QSize, bool);
void showSubtitle(int itemId);
void updateAssetPosition(int itemId);
/** @brief Zoom level changed in timeline, update slider
*/
void updateZoom(int);
......
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