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

Fix keyframes with master effects having a zone

parent 7a489580
......@@ -390,6 +390,25 @@ KeyframeModel *KeyframeModelList::getKeyModel(const QPersistentModelIndex &index
return nullptr;
}
void KeyframeModelList::moveKeyframes(int oldIn, int oldOut, int in, int out, Fun &undo, Fun &redo)
{
// Get list of keyframes positions
QList<GenTime> positions = m_parameters.begin()->second->getKeyframePos();
GenTime offset(in - oldIn, pCore->getCurrentFps());
if (in > oldIn) {
// Moving to the right, process in reverse order to prevent collisions
std::sort(positions.begin(), positions.end(), std::greater<>());
} else {
std::sort(positions.begin(), positions.end());
}
for (const auto &param : m_parameters) {
for (auto frame : qAsConst(positions)) {
param.second->moveKeyframe(frame, frame + offset, QVariant(), undo, redo);
}
}
}
void KeyframeModelList::resizeKeyframes(int oldIn, int oldOut, int in, int out, int offset, bool adjustFromEnd, Fun &undo, Fun &redo)
{
bool ok;
......
......@@ -147,6 +147,9 @@ public:
/** @brief Parent item size change, update keyframes*/
void resizeKeyframes(int oldIn, int oldOut, int in, int out, int offset, bool adjustFromEnd, Fun &undo, Fun &redo);
/** @brief Parent item size change, update keyframes*/
void moveKeyframes(int oldIn, int oldOut, int in, int out, Fun &undo, Fun &redo);
/** @brief Return position of the nth keyframe (ix = nth)*/
GenTime getPosAtIndex(int ix);
QModelIndex getIndexAtRow(int row);
......
......@@ -31,10 +31,11 @@
#include <QFontDatabase>
#include <utility>
KeyframeView::KeyframeView(std::shared_ptr<KeyframeModelList> model, int duration, QWidget *parent)
KeyframeView::KeyframeView(std::shared_ptr<KeyframeModelList> model, int duration, int inPoint, QWidget *parent)
: QWidget(parent)
, m_model(std::move(model))
, m_duration(duration)
, m_inPoint(inPoint)
, m_position(0)
, m_currentKeyframe(-1)
, m_currentKeyframeOriginal(-1)
......@@ -182,9 +183,10 @@ void KeyframeView::slotRemoveKeyframe(QVector<int> positions)
pCore->pushUndo(undo, redo, i18np("Remove keyframe", "Remove keyframes", positions.size()));
}
void KeyframeView::setDuration(int dur)
void KeyframeView::setDuration(int dur, int inPoint)
{
m_duration = dur;
m_inPoint = inPoint;
int offset = pCore->getItemIn(m_model->getOwnerId());
emit atKeyframe(m_model->hasKeyframe(m_position + offset), m_model->singleKeyframe());
update();
......@@ -202,10 +204,10 @@ void KeyframeView::slotGoToNext()
auto next = m_model->getNextKeyframe(GenTime(m_position + offset, pCore->getCurrentFps()), &ok);
if (ok) {
emit seekToPos(qMin(int(next.first.frames(pCore->getCurrentFps())) - offset, m_duration - 1));
emit seekToPos(qMin(int(next.first.frames(pCore->getCurrentFps())) - offset, m_duration - 1) + m_inPoint);
} else {
// no keyframe after current position
emit seekToPos(m_duration - 1);
emit seekToPos(m_duration - 1 + m_inPoint);
}
}
......@@ -221,10 +223,10 @@ void KeyframeView::slotGoToPrev()
auto prev = m_model->getPrevKeyframe(GenTime(m_position + offset, pCore->getCurrentFps()), &ok);
if (ok) {
emit seekToPos(qMax(0, int(prev.first.frames(pCore->getCurrentFps())) - offset));
emit seekToPos(qMax(0, int(prev.first.frames(pCore->getCurrentFps())) - offset) + m_inPoint);
} else {
// no keyframe after current position
emit seekToPos(m_duration - 1);
emit seekToPos(m_duration - 1 + m_inPoint);
}
}
......@@ -308,7 +310,7 @@ void KeyframeView::mousePressEvent(QMouseEvent *event)
if (m_currentKeyframeOriginal > -1) {
m_moveKeyframeMode = true;
if (KdenliveSettings::keyframeseek()) {
emit seekToPos(m_currentKeyframeOriginal);
emit seekToPos(m_currentKeyframeOriginal + m_inPoint);
} else {
update();
}
......@@ -342,7 +344,7 @@ void KeyframeView::mousePressEvent(QMouseEvent *event)
return;
}
}
emit seekToPos(pos);
emit seekToPos(pos + m_inPoint);
update();
}
......@@ -447,7 +449,7 @@ void KeyframeView::mouseMoveEvent(QMouseEvent *event)
}
if (!m_moveKeyframeMode || KdenliveSettings::keyframeseek()) {
emit seekToPos(pos);
emit seekToPos(pos + m_inPoint);
}
return;
}
......@@ -627,7 +629,7 @@ void KeyframeView::wheelEvent(QWheelEvent *event)
}
int change = event->angleDelta().y() > 0 ? -1 : 1;
int pos = qBound(0, m_position + change, m_duration - 1);
emit seekToPos(pos);
emit seekToPos(pos + m_inPoint);
}
void KeyframeView::paintEvent(QPaintEvent *event)
......
......@@ -32,8 +32,8 @@ class KeyframeView : public QWidget
Q_OBJECT
public:
explicit KeyframeView(std::shared_ptr<KeyframeModelList> model, int duration, QWidget *parent = nullptr);
void setDuration(int dur);
explicit KeyframeView(std::shared_ptr<KeyframeModelList> model, int duration, int inPoint, QWidget *parent = nullptr);
void setDuration(int dur, int inPoint);
const QString getAssetId();
/** @brief Copy a keyframe parameter to selected keyframes. */
void copyCurrentValue(QModelIndex ix, const QString paramName);
......@@ -76,6 +76,7 @@ protected:
private:
std::shared_ptr<KeyframeModelList> m_model;
int m_duration;
int m_inPoint;
int m_position;
int m_currentKeyframe;
int m_currentKeyframeOriginal;
......
......@@ -434,6 +434,10 @@ QVariant AssetParameterModel::data(const QModelIndex &index, int role) const
case ParentInRole:
return pCore->getItemIn(m_ownerId);
case ParentDurationRole:
if (m_asset->get_int("kdenlive:force_in_out") == 1) {
// Zone effect, return effect length
return m_asset->get_int("out") - m_asset->get_int("in");
}
return pCore->getItemDuration(m_ownerId);
case ParentPositionRole:
return pCore->getItemPosition(m_ownerId);
......
......@@ -63,9 +63,10 @@ KeyframeWidget::KeyframeWidget(std::shared_ptr<AssetParameterModel> model, QMode
bool ok = false;
int duration = m_model->data(m_index, AssetParameterModel::ParentDurationRole).toInt(&ok);
Q_ASSERT(ok);
int in = m_model->data(m_index, AssetParameterModel::InRole).toInt(&ok);
m_model->prepareKeyframes();
m_keyframes = m_model->getKeyframeModel();
m_keyframeview = new KeyframeView(m_keyframes, duration, this);
m_keyframeview = new KeyframeView(m_keyframes, duration, in, this);
m_buttonAddDelete = new QToolButton(this);
m_buttonAddDelete->setAutoRaise(true);
......@@ -127,6 +128,7 @@ KeyframeWidget::KeyframeWidget(std::shared_ptr<AssetParameterModel> model, QMode
connect(monitor, &Monitor::seekPosition, this, &KeyframeWidget::monitorSeek, Qt::UniqueConnection);
m_time = new TimecodeDisplay(pCore->timecode(), this);
m_time->setRange(0, duration - 1);
m_time->setOffset(in);
m_toolbar->addWidget(m_buttonPrevious);
m_toolbar->addWidget(m_buttonAddDelete);
......@@ -312,8 +314,19 @@ KeyframeWidget::~KeyframeWidget()
void KeyframeWidget::monitorSeek(int pos)
{
int in = pCore->getItemPosition(m_model->getOwnerId());
int out = in + pCore->getItemDuration(m_model->getOwnerId());
int in = 0;
int out = 0;
bool canHaveZone = m_model->getOwnerId().first == ObjectType::Master || m_model->getOwnerId().first == ObjectType::TimelineTrack;
if (canHaveZone) {
bool ok = false;
in = m_model->data(m_index, AssetParameterModel::InRole).toInt(&ok);
out = m_model->data(m_index, AssetParameterModel::OutRole).toInt(&ok);
Q_ASSERT(ok);
}
if (in == 0 && out == 0) {
in = pCore->getItemPosition(m_model->getOwnerId());
out = in + pCore->getItemDuration(m_model->getOwnerId());
}
bool isInRange = pos >= in && pos < out;
connectMonitor(isInRange && m_model->isActive());
m_buttonAddDelete->setEnabled(isInRange && pos > in);
......@@ -387,14 +400,6 @@ int KeyframeWidget::getPosition() const
return m_time->getValue() + pCore->getItemIn(m_model->getOwnerId());
}
void KeyframeWidget::addKeyframe(int pos)
{
blockSignals(true);
m_keyframeview->slotAddKeyframe(pos);
blockSignals(false);
setEnabled(true);
}
void KeyframeWidget::updateTimecodeFormat()
{
m_time->slotUpdateTimeCodeFormat();
......@@ -423,10 +428,12 @@ void KeyframeWidget::slotRefresh()
bool ok = false;
int duration = m_model->data(m_index, AssetParameterModel::ParentDurationRole).toInt(&ok);
Q_ASSERT(ok);
int in = m_model->data(m_index, AssetParameterModel::InRole).toInt(&ok);
// m_model->dataChanged(QModelIndex(), QModelIndex());
//->getKeyframeModel()->getKeyModel(m_index)->dataChanged(QModelIndex(), QModelIndex());
m_keyframeview->setDuration(duration);
m_keyframeview->setDuration(duration, in);
m_time->setRange(0, duration - 1);
m_time->setOffset(in);
slotRefreshParams();
}
......@@ -436,11 +443,13 @@ void KeyframeWidget::resetKeyframes()
bool ok = false;
int duration = m_model->data(m_index, AssetParameterModel::ParentDurationRole).toInt(&ok);
Q_ASSERT(ok);
int in = m_model->data(m_index, AssetParameterModel::InRole).toInt(&ok);
// reset keyframes
m_keyframes->refresh();
// m_model->dataChanged(QModelIndex(), QModelIndex());
m_keyframeview->setDuration(duration);
m_keyframeview->setDuration(duration, in);
m_time->setRange(0, duration - 1);
m_time->setOffset(in);
slotRefreshParams();
}
......
......@@ -49,7 +49,6 @@ public:
/** @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);
/** @brief Returns the monitor scene required for this asset
*/
MonitorSceneType requiredScene() const;
......
......@@ -269,6 +269,19 @@ void EffectItemModel::setInOut(const QString &effectName, QPair<int, int>bounds,
emit showEffectZone(m_ownerId, bounds, enabled);
return true;
};
std::shared_ptr<KeyframeModelList> keyframes = getKeyframeModel();
if (keyframes != nullptr) {
// Effect has keyframes, update these
const QModelIndex start = AssetParameterModel::index(0, 0);
const QModelIndex end = AssetParameterModel::index(rowCount() - 1, 0);
Fun refresh = [this, start, end]() {
emit dataChanged(start, end, QVector<int>());
return true;
};
refresh();
PUSH_LAMBDA(refresh, redo);
PUSH_LAMBDA(refresh, undo);
}
redo();
if (withUndo) {
pCore->pushUndo(undo, redo, i18n("Update zone for %1", effectName));
......
......@@ -576,6 +576,7 @@ bool EffectStackModel::adjustStackLength(bool adjustFromEnd, int oldIn, int oldD
}
std::shared_ptr<EffectItemModel> effect = std::static_pointer_cast<EffectItemModel>(leaf);
if (fadeInDuration > 0 && m_fadeIns.count(leaf->getId()) > 0) {
// Adjust fade in
int oldEffectIn = qMax(0, effect->filter().get_in());
int oldEffectOut = effect->filter().get_out();
qDebug() << "--previous effect: " << oldEffectIn << "-" << oldEffectOut;
......@@ -625,6 +626,7 @@ bool EffectStackModel::adjustStackLength(bool adjustFromEnd, int oldIn, int oldD
}
}
} else if (fadeOutDuration > 0 && m_fadeOuts.count(leaf->getId()) > 0) {
// Adjust fade out
int effectDuration = qMin(fadeOutDuration, duration);
int newFadeIn = out - effectDuration;
int oldFadeIn = effect->filter().get_int("in");
......@@ -655,6 +657,7 @@ bool EffectStackModel::adjustStackLength(bool adjustFromEnd, int oldIn, int oldD
}
} else {
// Not a fade effect, check for keyframes
bool hasZone = effect->filter().get_int("kdenlive:force_in_out") == 1;
std::shared_ptr<KeyframeModelList> keyframes = effect->getKeyframeModel();
if (keyframes != nullptr) {
// Effect has keyframes, update these
......@@ -670,7 +673,7 @@ bool EffectStackModel::adjustStackLength(bool adjustFromEnd, int oldIn, int oldD
} else {
qDebug() << "// NULL Keyframes---------";
}
if (m_ownerId.first == ObjectType::TimelineTrack && effect->filter().get_int("kdenlive:force_in_out") == 0) {
if (m_ownerId.first == ObjectType::TimelineTrack && !hasZone) {
int oldEffectOut = effect->filter().get_out();
Fun operation = [effect, out, logUndo]() {
effect->setParameter(QStringLiteral("out"), out, logUndo);
......
......@@ -3822,6 +3822,7 @@ void TimelineModel::updateDuration()
// update black track length
m_blackClip->set("out", duration + TimelineModel::seekDuration);
emit durationUpdated();
m_masterStack->dataChanged(QModelIndex(), QModelIndex(), {});
}
}
......
......@@ -71,17 +71,22 @@ Rectangle {
resizeActive = true
}
onExited: {
resizeActive = false
if (!pressed) {
resizeActive = false
}
}
onReleased: {
console.log("========\n\nZONE MOVE MOUSE RELEASED!!!!!!!!\n\n===============")
updateZone(startZone, Qt.point(frameIn, frameOut), true)
resizeActive = false
anchors.left= parent.left
}
onPositionChanged: {
console.log("MOUSE MOVE EVENT...")
if (mouse.buttons === Qt.LeftButton) {
resizeActive = true
var offset = Math.round(mouseX/ timeline.scaleFactor)
console.log("MOUSE MOVE OFFSET: ", offset)
if (offset != 0) {
var newPos = Math.max(0, controller.suggestSnapPoint(frameIn + offset,mouse.modifiers & Qt.ShiftModifier ? -1 : root.snapping))
if (newPos == frameIn + offset) {
......
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