1 /*
2 SPDX-FileCopyrightText: 2016 Jean-Baptiste Mardelle <jb@kdenlive.org>
3 This file is part of Kdenlive. See www.kdenlive.org.
4
5 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
6 */
7
8 #include "qmlmanager.h"
9 #include "kdenlivesettings.h"
10
11 #include <QFontDatabase>
12 #include <QQmlContext>
13 #include <QQuickView>
14 #include <QQuickItem>
15
QmlManager(QQuickView * view)16 QmlManager::QmlManager(QQuickView *view)
17 : QObject(view)
18 , m_view(view)
19 , m_sceneType(MonitorSceneNone)
20 {
21 }
22
sceneType() const23 MonitorSceneType QmlManager::sceneType() const
24 {
25 return m_sceneType;
26 }
27
setProperty(const QString & name,const QVariant & value)28 void QmlManager::setProperty(const QString &name, const QVariant &value)
29 {
30 m_view->rootObject()->setProperty(name.toUtf8().constData(), value);
31 }
32
setScene(Kdenlive::MonitorId id,MonitorSceneType type,QSize profile,double profileStretch,QRect displayRect,double zoom,int duration)33 void QmlManager::setScene(Kdenlive::MonitorId id, MonitorSceneType type, QSize profile, double profileStretch, QRect displayRect, double zoom, int duration)
34 {
35 if (type == m_sceneType) {
36 // Scene type already active
37 return;
38 }
39 m_sceneType = type;
40 QQuickItem *root = nullptr;
41 m_view->rootContext()->setContextProperty("fixedFont", QFontDatabase::systemFont(QFontDatabase::FixedFont));
42 double scalex = double(displayRect.width()) / profile.width() * zoom;
43 double scaley = double(displayRect.height()) / profile.height() * zoom;
44 switch (type) {
45 case MonitorSceneGeometry:
46 m_view->setSource(QUrl(QStringLiteral("qrc:/qml/kdenlivemonitoreffectscene.qml")));
47 root = m_view->rootObject();
48 QObject::connect(root, SIGNAL(effectChanged()), this, SLOT(effectRectChanged()), Qt::UniqueConnection);
49 QObject::connect(root, SIGNAL(centersChanged()), this, SLOT(effectPolygonChanged()), Qt::UniqueConnection);
50 root->setProperty("profile", QPoint(profile.width(), profile.height()));
51 root->setProperty("framesize", QRect(0, 0, profile.width(), profile.height()));
52 root->setProperty("scalex", scalex);
53 root->setProperty("scaley", scaley);
54 root->setProperty("center", displayRect.center());
55 break;
56 case MonitorSceneCorners:
57 m_view->setSource(QUrl(QStringLiteral("qrc:/qml/kdenlivemonitorcornerscene.qml")));
58 root = m_view->rootObject();
59 QObject::connect(root, SIGNAL(effectPolygonChanged()), this, SLOT(effectPolygonChanged()), Qt::UniqueConnection);
60 root->setProperty("profile", QPoint(profile.width(), profile.height()));
61 root->setProperty("framesize", QRect(0, 0, profile.width(), profile.height()));
62 root->setProperty("scalex", scalex);
63 root->setProperty("scaley", scaley);
64 root->setProperty("stretch", profileStretch);
65 root->setProperty("center", displayRect.center());
66 break;
67 case MonitorSceneRoto:
68 m_view->setSource(QUrl(QStringLiteral("qrc:/qml/kdenlivemonitorrotoscene.qml")));
69 root = m_view->rootObject();
70 QObject::connect(root, SIGNAL(effectPolygonChanged(QVariant,QVariant)), this, SLOT(effectRotoChanged(QVariant,QVariant)), Qt::UniqueConnection);
71 root->setProperty("profile", QPoint(profile.width(), profile.height()));
72 root->setProperty("framesize", QRect(0, 0, profile.width(), profile.height()));
73 root->setProperty("scalex", scalex);
74 root->setProperty("scaley", scaley);
75 root->setProperty("stretch", profileStretch);
76 root->setProperty("center", displayRect.center());
77 break;
78 case MonitorSplitTrack:
79 m_view->setSource(QUrl(QStringLiteral("qrc:/qml/kdenlivemonitorsplittracks.qml")));
80 root = m_view->rootObject();
81 QObject::connect(root, SIGNAL(activateTrack(int)), this, SIGNAL(activateTrack(int)), Qt::UniqueConnection);
82 root->setProperty("profile", QPoint(profile.width(), profile.height()));
83 root->setProperty("framesize", QRect(0, 0, profile.width(), profile.height()));
84 root->setProperty("scalex", scalex);
85 root->setProperty("scaley", scaley);
86 root->setProperty("stretch", profileStretch);
87 root->setProperty("center", displayRect.center());
88 break;
89 case MonitorSceneSplit:
90 m_view->setSource(QUrl(QStringLiteral("qrc:/qml/kdenlivemonitorsplit.qml")));
91 root = m_view->rootObject();
92 root->setProperty("profile", QPoint(profile.width(), profile.height()));
93 root->setProperty("scalex", scalex);
94 root->setProperty("scaley", scaley);
95 break;
96 case MonitorSceneTrimming:
97 m_view->setSource(QUrl(QStringLiteral("qrc:/qml/kdenlivemonitortrimming.qml")));
98 root = m_view->rootObject();
99 break;
100 default:
101 m_view->setSource(
102 QUrl(id == Kdenlive::ClipMonitor ? QStringLiteral("qrc:/qml/kdenliveclipmonitor.qml") : QStringLiteral("qrc:/qml/kdenlivemonitor.qml")));
103 root = m_view->rootObject();
104 root->setProperty("profile", QPoint(profile.width(), profile.height()));
105 root->setProperty("scalex", scalex);
106 root->setProperty("scaley", scaley);
107 if (id == Kdenlive::ClipMonitor) {
108 // Apply the always show audio setting
109 root->setProperty("permanentAudiothumb", KdenliveSettings::alwaysShowMonitorAudio());
110 }
111 break;
112 }
113 if (root && duration > 0) {
114 root->setProperty("duration", duration);
115 }
116 }
117
effectRectChanged()118 void QmlManager::effectRectChanged()
119 {
120 if (!m_view->rootObject()) {
121 return;
122 }
123 const QRect rect = m_view->rootObject()->property("framesize").toRect();
124 emit effectChanged(rect);
125 }
126
effectPolygonChanged()127 void QmlManager::effectPolygonChanged()
128 {
129 if (!m_view->rootObject()) {
130 return;
131 }
132 QVariantList points = m_view->rootObject()->property("centerPoints").toList();
133 emit effectPointsChanged(points);
134 }
135
effectRotoChanged(QVariant pts,QVariant centers)136 void QmlManager::effectRotoChanged(QVariant pts, QVariant centers)
137 {
138 if (!m_view->rootObject()) {
139 return;
140 }
141 QVariantList points = pts.toList();
142 QVariantList controlPoints = centers.toList();
143 if (2 * points.size() != controlPoints.size()) {
144 // Mismatch, abort
145 return;
146 }
147 // rotoscoping effect needs a list of
148 QVariantList mix;
149 mix.reserve(points.count());
150 for (int i = 0; i < points.count(); i++) {
151 mix << controlPoints.at(2 * i);
152 mix << points.at(i);
153 mix << controlPoints.at(2 * i + 1);
154 }
155 emit effectPointsChanged(mix);
156 }
157