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 ¢ers) 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 }