diff --git a/cicd/gitlab/gitlab-ci.yml b/cicd/gitlab/gitlab-ci.yml index 7b9aee05a9ec980b15fb68ea17749a7ae907e3dd..8e1c8dd62e200688ac9c21638b04c5a03df1c646 100644 --- a/cicd/gitlab/gitlab-ci.yml +++ b/cicd/gitlab/gitlab-ci.yml @@ -3,7 +3,7 @@ variables: QDS_CI_QT_VERSION: - value: "643" + value: "652" options: - "643" - "652" diff --git a/design-viewer/src/dv_wasm.cpp b/design-viewer/src/dv_wasm.cpp index ca06b9acbe6212bd0086fc74a68dace7404a1db5..925ac70e3e644749952544d47dab2e3ce2699359 100644 --- a/design-viewer/src/dv_wasm.cpp +++ b/design-viewer/src/dv_wasm.cpp @@ -26,64 +26,23 @@ #include "dv_wasm.h" #if defined(Q_OS_WASM) +#include <emscripten/val.h> + #include <emscripten.h> #include <functional> #include <QFile> - -std::function<void(char *, size_t, char *)> g_setFileDataCallback; -extern "C" EMSCRIPTEN_KEEPALIVE void qt_callSetFileData(char *content, - size_t contentSize, - char *fileName) -{ - if (g_setFileDataCallback == nullptr) - return; - - g_setFileDataCallback(content, contentSize, fileName); - g_setFileDataCallback = nullptr; -} +#include <QTimer> void DvWasm::fetchProject(QByteArray *data, QString *fileName) { - // Call qt_callSetFileData to make sure the emscripten linker does not - // optimize it away, which may happen if the function is called from JavaScript - // only. Set g_setFileDataCallback to null to make it a no-op. - ::g_setFileDataCallback = nullptr; - ::qt_callSetFileData(nullptr, 0, nullptr); - - auto setFileDataCallback = - [data, fileName](char *content, size_t contentSize, char *projectFilename) { - data->setRawData(content, contentSize); - *fileName = QString::fromUtf8(projectFilename); - }; - g_setFileDataCallback = setFileDataCallback; - - EM_ASM_({ - // Copy the file file content to the C++ heap. - // Note: this could be simplified by passing the content as an - // "array" type to ccall and then let it copy to C++ memory. - // However, this built-in solution does not handle files larger - // than ~15M (Chrome). Instead, allocate memory manually and - // pass a pointer to the C++ side (which will free() it when done). + // Access global variables set by index.html + emscripten::val jsData = emscripten::val::global("contentArray"); + emscripten::val jsFileName = emscripten::val::global("projectfileName"); - // TODO: consider slice()ing the file to read it picewise and - // then assembling it in a QByteArray on the C++ side. - - const contentSize = contentArray.byteLength; - const heapPointer = _malloc(contentSize); - const heapBytes = new Uint8Array(Module.HEAPU8.buffer, heapPointer, contentSize); - heapBytes.set(contentArray); - - // Null out the first data copy to enable GC - reader = null; - contentArray = null; - - // Call the C++ file data ready callback - ccall("qt_callSetFileData", - null, - ["number", "number", "string"], - [heapPointer, contentSize, projectfileName]); - }); + // Copy project data to the C++ heap and convert string + *data = QByteArray::fromEcmaUint8Array(jsData); + *fileName = QString::fromStdString(jsFileName.as<std::string>()); } void DvWasm::printLog(const QString &message) @@ -96,22 +55,41 @@ void DvWasm::printWarn(const QString &message) QString escaped = message; escaped.replace("'", "\'"); escaped.replace("\n", "\\n"); - emscripten_run_script("alert('" + escaped.toUtf8() + "');"); + emscripten::val::global("window").call<void>("alert", escaped.toStdString()); } void DvWasm::printError(const QString &message, const QString &fileName, int line) { printWarn(message); - emscripten_run_script("location.hash = ''; location.reload();"); + emscripten::val location = emscripten::val::global("window")["location"]; + location.set("hash", std::string()); + location.call<void>("reload"); } void DvWasm::showAppWindow() { printLog("Resizing the QML app window"); const QSize size; - const QString command - = QString::fromLatin1("setScreenSize(%1, %2);").arg(size.width()).arg(size.height()); - emscripten_run_script(command.toUtf8()); + emscripten::val qtContainer = emscripten::val::global("container"); // global from index.html + emscripten::val qtContainerStyle = qtContainer["style"]; + + if (size.isEmpty()) { + qtContainerStyle.set("width", std::string("100%")); + qtContainerStyle.set("height", + std::string( + "100%")); // ### FIXME: 100% height gives 0px height for some reason + } else { + qtContainerStyle.set("width", QString("%1px").arg(size.width()).toStdString()); + qtContainerStyle.set("height", QString("%1px").arg(size.height()).toStdString()); + } + + // Make Qt pick up the new container size by calling the resizeCanvasElement() + // qtloader API. This needs to be done on delay after initial setup to make + // sure qtloader is initialized. + QTimer::singleShot(0, [qtContainer]() { + emscripten::val qtLoader = emscripten::val::global("qtLoader"); + qtLoader.call<void>("resizeCanvasElement", qtContainer); + }); printLog("Showing the QML app window"); m_quickWindow->show(); } diff --git a/design-viewer/www/index.html b/design-viewer/www/index.html index 84c97da720f70e511c9d73f7211cff87cb89396c..3129e299b46ffeb10ec0c52847e09052e54e8dbf 100644 --- a/design-viewer/www/index.html +++ b/design-viewer/www/index.html @@ -118,11 +118,7 @@ </div> </div> - <canvas - id="qtcanvas" - oncontextmenu="event.preventDefault()" - contenteditable="true" - ></canvas> + <div id="qtcontainer"></div> <div id="footer"> <div id="alertBox" class="alert"> <span