mirror of
https://gitlab.com/kelteseth/ScreenPlay.git
synced 2024-09-18 08:22:33 +02:00
Add live reloading to Widgets
This commit is contained in:
parent
ebfe616460
commit
a78a48bb2e
@ -22,20 +22,17 @@ Item {
|
|||||||
var newObject = Qt.createQmlObject(obj2.toString(), root, "err")
|
var newObject = Qt.createQmlObject(obj2.toString(), root, "err")
|
||||||
newObject.destroy(10000)
|
newObject.destroy(10000)
|
||||||
}
|
}
|
||||||
}
|
// Replace wallpaper with QML Scene
|
||||||
|
function onReloadQML(oldType) {
|
||||||
|
|
||||||
Action {
|
|
||||||
shortcut: "F5"
|
|
||||||
onTriggered: {
|
|
||||||
loader.sourceComponent = undefined
|
loader.sourceComponent = undefined
|
||||||
loader.source = ""
|
loader.source = ""
|
||||||
Widget.clearComponentCache()
|
Widget.clearComponentCache()
|
||||||
if (Widget.type === "qmlWidget") {
|
|
||||||
loader.source = Qt.resolvedUrl(Widget.sourcePath)
|
loader.source = Qt.resolvedUrl(Widget.projectSourceFileAbsolute)
|
||||||
} else if (Widget.type === "htmlWidget") {
|
|
||||||
loader.sourceComponent = webViewComponent
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OpacityAnimator {
|
OpacityAnimator {
|
||||||
|
@ -16,8 +16,8 @@ int main(int argc, char* argv[])
|
|||||||
// If we start with only one argument (path, appID, type),
|
// If we start with only one argument (path, appID, type),
|
||||||
// it means we want to test a single widget
|
// it means we want to test a single widget
|
||||||
if (argumentList.length() == 1) {
|
if (argumentList.length() == 1) {
|
||||||
//WidgetWindow spwmw("test", "appid", "qmlWidget", { 0, 0 });
|
//WidgetWindow spwmw("test", "appid", "qmlWidget", { 0, 0 }, true);
|
||||||
WidgetWindow spwmw("C:/Program Files (x86)/Steam/steamapps/workshop/content/672870/2136442401", "appid", "qmlWidget", { 0, 0 });
|
WidgetWindow spwmw("C:/Program Files (x86)/Steam/steamapps/workshop/content/672870/2136442401", "appid", "qmlWidget", { 0, 0 }, true);
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,11 +21,13 @@ WidgetWindow::WidgetWindow(
|
|||||||
const QString& projectPath,
|
const QString& projectPath,
|
||||||
const QString& appID,
|
const QString& appID,
|
||||||
const QString& type,
|
const QString& type,
|
||||||
const QPoint& position)
|
const QPoint& position,
|
||||||
|
const bool debugMode)
|
||||||
: QObject(nullptr)
|
: QObject(nullptr)
|
||||||
, m_appID { appID }
|
, m_appID { appID }
|
||||||
, m_position { position }
|
, m_position { position }
|
||||||
, m_sdk { std::make_unique<ScreenPlaySDK>(appID, type) }
|
, m_sdk { std::make_unique<ScreenPlaySDK>(appID, type) }
|
||||||
|
, m_debugMode { debugMode }
|
||||||
{
|
{
|
||||||
|
|
||||||
qRegisterMetaType<ScreenPlay::InstalledType::InstalledType>();
|
qRegisterMetaType<ScreenPlay::InstalledType::InstalledType>();
|
||||||
@ -56,14 +58,15 @@ WidgetWindow::WidgetWindow(
|
|||||||
setProjectSourceFileAbsolute({ "qrc:/test.qml" });
|
setProjectSourceFileAbsolute({ "qrc:/test.qml" });
|
||||||
setType(ScreenPlay::InstalledType::InstalledType::QMLWidget);
|
setType(ScreenPlay::InstalledType::InstalledType::QMLWidget);
|
||||||
} else {
|
} else {
|
||||||
auto projectOpt = ScreenPlayUtil::openJsonFileToObject(projectPath + "/project.json");
|
setProjectPath(projectPath);
|
||||||
|
auto projectOpt = ScreenPlayUtil::openJsonFileToObject(m_projectPath + "/project.json");
|
||||||
if (!projectOpt.has_value()) {
|
if (!projectOpt.has_value()) {
|
||||||
qWarning() << "Unable to parse project file!";
|
qWarning() << "Unable to parse project file!";
|
||||||
}
|
}
|
||||||
|
|
||||||
m_project = projectOpt.value();
|
m_project = projectOpt.value();
|
||||||
setProjectSourceFile(m_project.value("file").toString());
|
setProjectSourceFile(m_project.value("file").toString());
|
||||||
setProjectSourceFileAbsolute(QUrl::fromLocalFile(projectPath + "/" + projectSourceFile()));
|
setProjectSourceFileAbsolute(QUrl::fromLocalFile(m_projectPath + "/" + projectSourceFile()));
|
||||||
|
|
||||||
if (auto typeOpt = ScreenPlayUtil::getInstalledTypeFromString(m_project.value("type").toString())) {
|
if (auto typeOpt = ScreenPlayUtil::getInstalledTypeFromString(m_project.value("type").toString())) {
|
||||||
setType(typeOpt.value());
|
setType(typeOpt.value());
|
||||||
@ -79,26 +82,30 @@ WidgetWindow::WidgetWindow(
|
|||||||
m_window.show();
|
m_window.show();
|
||||||
|
|
||||||
// Do not trigger position changed save reuqest on startup
|
// Do not trigger position changed save reuqest on startup
|
||||||
sdk()->start();
|
if (!m_debugMode) {
|
||||||
QTimer::singleShot(1000, this, [=, this]() {
|
sdk()->start();
|
||||||
// We limit ourself to only update the position every 500ms!
|
QTimer::singleShot(1000, this, [=, this]() {
|
||||||
auto sendPositionUpdate = [this]() {
|
// We limit ourself to only update the position every 500ms!
|
||||||
m_positionMessageLimiter.stop();
|
auto sendPositionUpdate = [this]() {
|
||||||
if (!m_sdk->isConnected())
|
m_positionMessageLimiter.stop();
|
||||||
return;
|
if (!m_sdk->isConnected())
|
||||||
|
return;
|
||||||
|
|
||||||
QJsonObject obj;
|
QJsonObject obj;
|
||||||
obj.insert("messageType", "positionUpdate");
|
obj.insert("messageType", "positionUpdate");
|
||||||
obj.insert("positionX", m_window.x());
|
obj.insert("positionX", m_window.x());
|
||||||
obj.insert("positionY", m_window.y());
|
obj.insert("positionY", m_window.y());
|
||||||
m_sdk->sendMessage(obj);
|
m_sdk->sendMessage(obj);
|
||||||
};
|
};
|
||||||
m_positionMessageLimiter.setInterval(500);
|
m_positionMessageLimiter.setInterval(500);
|
||||||
|
|
||||||
QObject::connect(&m_positionMessageLimiter, &QTimer::timeout, this, sendPositionUpdate);
|
QObject::connect(&m_positionMessageLimiter, &QTimer::timeout, this, sendPositionUpdate);
|
||||||
QObject::connect(&m_window, &QWindow::xChanged, this, [this]() { m_positionMessageLimiter.start(); });
|
QObject::connect(&m_window, &QWindow::xChanged, this, [this]() { m_positionMessageLimiter.start(); });
|
||||||
QObject::connect(&m_window, &QWindow::yChanged, this, [this]() { m_positionMessageLimiter.start(); });
|
QObject::connect(&m_window, &QWindow::yChanged, this, [this]() { m_positionMessageLimiter.start(); });
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setupLiveReloading();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidgetWindow::setSize(QSize size)
|
void WidgetWindow::setSize(QSize size)
|
||||||
@ -133,11 +140,6 @@ void WidgetWindow::setWidgetSize(const int with, const int height)
|
|||||||
m_window.setHeight(height);
|
m_window.setHeight(height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidgetWindow::clearComponentCache()
|
|
||||||
{
|
|
||||||
m_window.engine()->clearComponentCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
void WidgetWindow::setWindowBlur(unsigned int style)
|
void WidgetWindow::setWindowBlur(unsigned int style)
|
||||||
{
|
{
|
||||||
@ -174,3 +176,34 @@ void WidgetWindow::setWindowBlur(unsigned int style)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Call the qml engine clearComponentCache. This function is used for
|
||||||
|
refreshing wallpaper when the content has changed. For example this
|
||||||
|
is needed for live editing when the content is chached.
|
||||||
|
*/
|
||||||
|
void WidgetWindow::clearComponentCache()
|
||||||
|
{
|
||||||
|
m_window.engine()->clearComponentCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief This public slot is for QML usage. We limit the change event updates
|
||||||
|
to every 50ms, because the filesystem can be very trigger happy
|
||||||
|
with multiple change events per second.
|
||||||
|
*/
|
||||||
|
void WidgetWindow::setupLiveReloading()
|
||||||
|
{
|
||||||
|
auto reloadQMLLambda = [this]() {
|
||||||
|
m_liveReloadLimiter.stop();
|
||||||
|
emit reloadQML(type());
|
||||||
|
};
|
||||||
|
auto timeoutLambda = [this]() {
|
||||||
|
m_liveReloadLimiter.start(50);
|
||||||
|
};
|
||||||
|
|
||||||
|
QObject::connect(&m_fileSystemWatcher, &QFileSystemWatcher::directoryChanged, this, timeoutLambda);
|
||||||
|
QObject::connect(&m_fileSystemWatcher, &QFileSystemWatcher::fileChanged, this, timeoutLambda);
|
||||||
|
QObject::connect(&m_liveReloadLimiter, &QTimer::timeout, this, reloadQMLLambda);
|
||||||
|
m_fileSystemWatcher.addPaths({ projectPath() });
|
||||||
|
}
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
#include <QtQuick/QQuickWindow>
|
#include <QtQuick/QQuickWindow>
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
#include <QFileSystemWatcher>
|
||||||
#include <qt_windows.h>
|
#include <qt_windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -67,7 +68,8 @@ public:
|
|||||||
const QString& projectPath,
|
const QString& projectPath,
|
||||||
const QString& appid,
|
const QString& appid,
|
||||||
const QString& type,
|
const QString& type,
|
||||||
const QPoint& position);
|
const QPoint& position,
|
||||||
|
const bool debugMode = false);
|
||||||
|
|
||||||
Q_PROPERTY(QString appID READ appID WRITE setAppID NOTIFY appIDChanged)
|
Q_PROPERTY(QString appID READ appID WRITE setAppID NOTIFY appIDChanged)
|
||||||
Q_PROPERTY(QString projectPath READ projectPath WRITE setProjectPath NOTIFY projectPathChanged)
|
Q_PROPERTY(QString projectPath READ projectPath WRITE setProjectPath NOTIFY projectPathChanged)
|
||||||
@ -76,6 +78,7 @@ public:
|
|||||||
Q_PROPERTY(QPoint position READ position WRITE setPosition NOTIFY positionChanged)
|
Q_PROPERTY(QPoint position READ position WRITE setPosition NOTIFY positionChanged)
|
||||||
Q_PROPERTY(ScreenPlay::InstalledType::InstalledType type READ type WRITE setType NOTIFY typeChanged)
|
Q_PROPERTY(ScreenPlay::InstalledType::InstalledType type READ type WRITE setType NOTIFY typeChanged)
|
||||||
Q_PROPERTY(ScreenPlaySDK* sdk READ sdk WRITE setSdk NOTIFY sdkChanged)
|
Q_PROPERTY(ScreenPlaySDK* sdk READ sdk WRITE setSdk NOTIFY sdkChanged)
|
||||||
|
Q_PROPERTY(bool debugMode READ debugMode WRITE setDebugMode NOTIFY debugModeChanged)
|
||||||
|
|
||||||
QString appID() const { return m_appID; }
|
QString appID() const { return m_appID; }
|
||||||
QPoint position() const { return m_position; }
|
QPoint position() const { return m_position; }
|
||||||
@ -84,10 +87,11 @@ public:
|
|||||||
const QString& projectSourceFile() const { return m_projectSourceFile; }
|
const QString& projectSourceFile() const { return m_projectSourceFile; }
|
||||||
const QUrl& projectSourceFileAbsolute() const { return m_projectSourceFileAbsolute; }
|
const QUrl& projectSourceFileAbsolute() const { return m_projectSourceFileAbsolute; }
|
||||||
ScreenPlaySDK* sdk() const { return m_sdk.get(); }
|
ScreenPlaySDK* sdk() const { return m_sdk.get(); }
|
||||||
|
bool debugMode() const { return m_debugMode; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void qmlExit();
|
void qmlExit();
|
||||||
|
void reloadQML(const ScreenPlay::InstalledType::InstalledType oldType);
|
||||||
void appIDChanged(QString appID);
|
void appIDChanged(QString appID);
|
||||||
void qmlSceneValueReceived(QString key, QString value);
|
void qmlSceneValueReceived(QString key, QString value);
|
||||||
void positionChanged(QPoint position);
|
void positionChanged(QPoint position);
|
||||||
@ -95,8 +99,8 @@ signals:
|
|||||||
void typeChanged(ScreenPlay::InstalledType::InstalledType);
|
void typeChanged(ScreenPlay::InstalledType::InstalledType);
|
||||||
void projectSourceFileChanged(const QString& projectSourceFile);
|
void projectSourceFileChanged(const QString& projectSourceFile);
|
||||||
void projectSourceFileAbsoluteChanged(const QUrl& projectSourceFileAbsolute);
|
void projectSourceFileAbsoluteChanged(const QUrl& projectSourceFileAbsolute);
|
||||||
|
void sdkChanged(ScreenPlaySDK* sdk);
|
||||||
void sdkChanged(ScreenPlaySDK*);
|
void debugModeChanged(bool debugMode);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setSize(QSize size);
|
void setSize(QSize size);
|
||||||
@ -171,9 +175,21 @@ public slots:
|
|||||||
emit sdkChanged(sdk);
|
emit sdkChanged(sdk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setDebugMode(bool debugMode)
|
||||||
|
{
|
||||||
|
if (m_debugMode == debugMode)
|
||||||
|
return;
|
||||||
|
m_debugMode = debugMode;
|
||||||
|
emit debugModeChanged(m_debugMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setupLiveReloading();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_appID;
|
QString m_appID;
|
||||||
QString m_projectPath;
|
QString m_projectPath;
|
||||||
|
QString m_projectSourceFile;
|
||||||
QJsonObject m_project;
|
QJsonObject m_project;
|
||||||
QPoint m_clickPos = { 0, 0 };
|
QPoint m_clickPos = { 0, 0 };
|
||||||
QPoint m_lastPos = { 0, 0 };
|
QPoint m_lastPos = { 0, 0 };
|
||||||
@ -182,10 +198,11 @@ private:
|
|||||||
std::unique_ptr<ScreenPlaySDK> m_sdk;
|
std::unique_ptr<ScreenPlaySDK> m_sdk;
|
||||||
QTimer m_positionMessageLimiter;
|
QTimer m_positionMessageLimiter;
|
||||||
ScreenPlay::InstalledType::InstalledType m_type;
|
ScreenPlay::InstalledType::InstalledType m_type;
|
||||||
|
QFileSystemWatcher m_fileSystemWatcher;
|
||||||
|
QTimer m_liveReloadLimiter;
|
||||||
|
QUrl m_projectSourceFileAbsolute;
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
HWND m_hwnd;
|
HWND m_hwnd;
|
||||||
#endif
|
#endif
|
||||||
QString m_projectSourceFile;
|
bool m_debugMode = false;
|
||||||
QUrl m_projectSourceFileAbsolute;
|
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user