File indexing completed on 2024-05-05 04:52:43

0001 /*
0002 SPDX-FileCopyrightText: 2018 Jean-Baptiste Mardelle <jb@kdenlive.org>
0003 This file is part of Kdenlive. See www.kdenlive.org.
0004 
0005 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0006 */
0007 
0008 #include "keyframemonitorhelper.hpp"
0009 #include "assets/keyframes/model/keyframemodellist.hpp"
0010 #include "assets/model/assetparametermodel.hpp"
0011 #include "monitor/monitor.h"
0012 
0013 #include <core.h>
0014 #include <utility>
0015 KeyframeMonitorHelper::KeyframeMonitorHelper(Monitor *monitor, std::shared_ptr<AssetParameterModel> model, const QPersistentModelIndex &index, QObject *parent)
0016     : QObject(parent)
0017     , m_monitor(monitor)
0018     , m_model(std::move(model))
0019     , m_active(false)
0020 {
0021     m_indexes << index;
0022 }
0023 
0024 bool KeyframeMonitorHelper::connectMonitor(bool activate)
0025 {
0026     if (activate == m_active) {
0027         return true;
0028     }
0029     m_active = activate;
0030     if (activate) {
0031         connect(m_monitor, &Monitor::effectPointsChanged, this, &KeyframeMonitorHelper::slotUpdateFromMonitorData, Qt::UniqueConnection);
0032     } else {
0033         m_monitor->setEffectKeyframe(false);
0034         disconnect(m_monitor, &Monitor::effectPointsChanged, this, &KeyframeMonitorHelper::slotUpdateFromMonitorData);
0035     }
0036     return m_active;
0037 }
0038 
0039 void KeyframeMonitorHelper::addIndex(const QPersistentModelIndex &index)
0040 {
0041     m_indexes << index;
0042 }
0043 
0044 QList<QPersistentModelIndex> KeyframeMonitorHelper::getIndexes()
0045 {
0046     return m_indexes;
0047 }
0048 
0049 void KeyframeMonitorHelper::refreshParams(int /* pos */)
0050 {
0051     QVariantList points;
0052     QVariantList types;
0053     std::shared_ptr<KeyframeModelList> keyframes = m_model->getKeyframeModel();
0054     for (const auto &ix : qAsConst(m_indexes)) {
0055         auto type = m_model->data(ix, AssetParameterModel::TypeRole).value<ParamType>();
0056         if (type != ParamType::AnimatedRect) {
0057             continue;
0058         }
0059         KeyframeModel *kfr = keyframes->getKeyModel(ix);
0060         bool ok;
0061         Keyframe kf = kfr->getNextKeyframe(GenTime(-1), &ok);
0062         while (ok) {
0063             if (kf.second == KeyframeType::Curve) {
0064                 types << 1;
0065             } else {
0066                 types << 0;
0067             }
0068             QString rectData = kfr->getInterpolatedValue(kf.first).toString();
0069             QStringList data = rectData.split(QLatin1Char(' '));
0070             if (data.size() > 3) {
0071                 QRectF r(data.at(0).toInt(), data.at(1).toInt(), data.at(2).toInt(), data.at(3).toInt());
0072                 points.append(QVariant(r.center()));
0073             }
0074             kf = kfr->getNextKeyframe(kf.first, &ok);
0075         }
0076         break;
0077     }
0078     if (m_monitor) {
0079         m_monitor->setUpEffectGeometry(QRect(), points, types);
0080     }
0081 }
0082 
0083 void KeyframeMonitorHelper::slotUpdateFromMonitorData(const QVariantList &centers)
0084 {
0085     std::shared_ptr<KeyframeModelList> keyframes = m_model->getKeyframeModel();
0086     if (centers.count() != keyframes->count()) {
0087         qDebug() << "* * * *CENTER POINTS MISMATCH, aborting edit";
0088         return;
0089     }
0090     for (const auto &ix : qAsConst(m_indexes)) {
0091         auto type = m_model->data(ix, AssetParameterModel::TypeRole).value<ParamType>();
0092         if (type != ParamType::AnimatedRect) {
0093             continue;
0094         }
0095 
0096         KeyframeModel *kfr = keyframes->getKeyModel(ix);
0097         bool ok;
0098         Keyframe kf = kfr->getNextKeyframe(GenTime(-1), &ok);
0099         int i = 0;
0100         while (ok) {
0101             QString rectData = kfr->getInterpolatedValue(kf.first).toString();
0102             QStringList data = rectData.split(QLatin1Char(' '));
0103             if (data.size() > 3) {
0104                 QRectF r(data.at(0).toInt(), data.at(1).toInt(), data.at(2).toInt(), data.at(3).toInt());
0105                 QPointF pt(r.center());
0106                 QPointF expected = centers.at(i).toPointF();
0107                 if (pt != expected) {
0108                     // Center rect to new pos
0109                     QPointF offset = expected - pt;
0110                     r.translate(offset);
0111                     QString res = QString("%1 %2 %3 %4").arg(int(r.x())).arg(int(r.y())).arg(int(r.width())).arg(int(r.height()));
0112                     if (data.size() > 4) {
0113                         res.append(QString(" %1").arg(data.at(4)));
0114                     }
0115                     kfr->updateKeyframe(kf.first, res);
0116                 }
0117             }
0118             kf = kfr->getNextKeyframe(kf.first, &ok);
0119             i++;
0120         }
0121         break;
0122     }
0123 }