File indexing completed on 2024-04-21 04:51:51

0001 /*
0002     SPDX-FileCopyrightText: 2016 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 "qmlmanager.h"
0009 #include "kdenlivesettings.h"
0010 
0011 #include <QFontDatabase>
0012 #include <QQmlContext>
0013 #include <QQuickItem>
0014 #include <QQuickWidget>
0015 
0016 QmlManager::QmlManager(QQuickWidget *view)
0017     : QObject(view)
0018     , m_view(view)
0019     , m_sceneType(MonitorSceneNone)
0020 {
0021 }
0022 
0023 MonitorSceneType QmlManager::sceneType() const
0024 {
0025     return m_sceneType;
0026 }
0027 
0028 void QmlManager::setProperty(const QString &name, const QVariant &value)
0029 {
0030     m_view->rootObject()->setProperty(name.toUtf8().constData(), value);
0031 }
0032 
0033 void QmlManager::setScene(Kdenlive::MonitorId id, MonitorSceneType type, QSize profile, double profileStretch, QRect displayRect, double zoom, int duration)
0034 {
0035     if (type == m_sceneType) {
0036         // Scene type already active
0037         return;
0038     }
0039     m_sceneType = type;
0040     QQuickItem *root = nullptr;
0041     m_view->rootContext()->setContextProperty("fixedFont", QFontDatabase::systemFont(QFontDatabase::FixedFont));
0042     double scalex = double(displayRect.width()) / profile.width() * zoom;
0043     double scaley = double(displayRect.height()) / profile.height() * zoom;
0044     switch (type) {
0045     case MonitorSceneGeometry:
0046         m_view->setSource(QUrl(QStringLiteral("qrc:/qml/kdenlivemonitoreffectscene.qml")));
0047         root = m_view->rootObject();
0048         QObject::connect(root, SIGNAL(effectChanged()), this, SLOT(effectRectChanged()), Qt::UniqueConnection);
0049         QObject::connect(root, SIGNAL(centersChanged()), this, SLOT(effectPolygonChanged()), Qt::UniqueConnection);
0050         root->setProperty("profile", QPoint(profile.width(), profile.height()));
0051         root->setProperty("framesize", QRect(0, 0, profile.width(), profile.height()));
0052         root->setProperty("scalex", scalex);
0053         root->setProperty("scaley", scaley);
0054         root->setProperty("center", displayRect.center());
0055         break;
0056     case MonitorSceneCorners:
0057         m_view->setSource(QUrl(QStringLiteral("qrc:/qml/kdenlivemonitorcornerscene.qml")));
0058         root = m_view->rootObject();
0059         QObject::connect(root, SIGNAL(effectPolygonChanged()), this, SLOT(effectPolygonChanged()), Qt::UniqueConnection);
0060         root->setProperty("profile", QPoint(profile.width(), profile.height()));
0061         root->setProperty("framesize", QRect(0, 0, profile.width(), profile.height()));
0062         root->setProperty("scalex", scalex);
0063         root->setProperty("scaley", scaley);
0064         root->setProperty("stretch", profileStretch);
0065         root->setProperty("center", displayRect.center());
0066         break;
0067     case MonitorSceneRoto:
0068         m_view->setSource(QUrl(QStringLiteral("qrc:/qml/kdenlivemonitorrotoscene.qml")));
0069         root = m_view->rootObject();
0070         QObject::connect(root, SIGNAL(effectPolygonChanged(QVariant, QVariant)), this, SLOT(effectRotoChanged(QVariant, QVariant)), Qt::UniqueConnection);
0071         root->setProperty("profile", QPoint(profile.width(), profile.height()));
0072         root->setProperty("framesize", QRect(0, 0, profile.width(), profile.height()));
0073         root->setProperty("scalex", scalex);
0074         root->setProperty("scaley", scaley);
0075         root->setProperty("stretch", profileStretch);
0076         root->setProperty("center", displayRect.center());
0077         break;
0078     case MonitorSplitTrack:
0079         m_view->setSource(QUrl(QStringLiteral("qrc:/qml/kdenlivemonitorsplittracks.qml")));
0080         root = m_view->rootObject();
0081         QObject::connect(root, SIGNAL(activateTrack(int)), this, SIGNAL(activateTrack(int)), Qt::UniqueConnection);
0082         root->setProperty("profile", QPoint(profile.width(), profile.height()));
0083         root->setProperty("framesize", QRect(0, 0, profile.width(), profile.height()));
0084         root->setProperty("scalex", scalex);
0085         root->setProperty("scaley", scaley);
0086         root->setProperty("stretch", profileStretch);
0087         root->setProperty("center", displayRect.center());
0088         break;
0089     case MonitorSceneSplit:
0090         m_view->setSource(QUrl(QStringLiteral("qrc:/qml/kdenlivemonitorsplit.qml")));
0091         root = m_view->rootObject();
0092         root->setProperty("profile", QPoint(profile.width(), profile.height()));
0093         root->setProperty("scalex", scalex);
0094         root->setProperty("scaley", scaley);
0095         root->setProperty("center", displayRect.center());
0096         break;
0097     case MonitorSceneTrimming:
0098         m_view->setSource(QUrl(QStringLiteral("qrc:/qml/kdenlivemonitortrimming.qml")));
0099         root = m_view->rootObject();
0100         break;
0101     default:
0102         m_view->setSource(
0103             QUrl(id == Kdenlive::ClipMonitor ? QStringLiteral("qrc:/qml/kdenliveclipmonitor.qml") : QStringLiteral("qrc:/qml/kdenlivemonitor.qml")));
0104         root = m_view->rootObject();
0105         root->setProperty("profile", QPoint(profile.width(), profile.height()));
0106         root->setProperty("scalex", scalex);
0107         root->setProperty("scaley", scaley);
0108         root->setProperty("center", displayRect.center());
0109         if (id == Kdenlive::ClipMonitor) {
0110             // Apply the always show audio setting
0111             root->setProperty("permanentAudiothumb", KdenliveSettings::alwaysShowMonitorAudio());
0112         }
0113         break;
0114     }
0115     if (root && duration > 0) {
0116         root->setProperty("duration", duration);
0117     }
0118 }
0119 
0120 void QmlManager::effectRectChanged()
0121 {
0122     if (!m_view->rootObject()) {
0123         return;
0124     }
0125     const QRect rect = m_view->rootObject()->property("framesize").toRect();
0126     Q_EMIT effectChanged(rect);
0127 }
0128 
0129 void QmlManager::effectPolygonChanged()
0130 {
0131     if (!m_view->rootObject()) {
0132         return;
0133     }
0134     QVariantList points = m_view->rootObject()->property("centerPoints").toList();
0135     Q_EMIT effectPointsChanged(points);
0136 }
0137 
0138 void QmlManager::effectRotoChanged(const QVariant &pts, const QVariant &centers)
0139 {
0140     if (!m_view->rootObject()) {
0141         return;
0142     }
0143     QVariantList points = pts.toList();
0144     QVariantList controlPoints = centers.toList();
0145     if (2 * points.size() != controlPoints.size()) {
0146         // Mismatch, abort
0147         return;
0148     }
0149     // rotoscoping effect needs a list of
0150     QVariantList mix;
0151     mix.reserve(points.count());
0152     for (int i = 0; i < points.count(); i++) {
0153         mix << controlPoints.at(2 * i);
0154         mix << points.at(i);
0155         mix << controlPoints.at(2 * i + 1);
0156     }
0157     Q_EMIT effectPointsChanged(mix);
0158 }