commit b63db742200341b91358c14a7290104cb97d5613
parent c2938c02994988bd5dde4c4cbba9951709789ee8
Author: falkTX <falktx@falktx.com>
Date: Wed, 6 Jul 2022 14:31:17 +0100
wasm file browser details, add WASM_EXCEPTIONS build option
Signed-off-by: falkTX <falktx@falktx.com>
Diffstat:
3 files changed, 89 insertions(+), 34 deletions(-)
diff --git a/Makefile.base.mk b/Makefile.base.mk
@@ -267,6 +267,10 @@ ifeq ($(MACOS_OLD),true)
BUILD_CXX_FLAGS = $(BASE_FLAGS) $(CXXFLAGS) -DHAVE_CPP11_SUPPORT=0
endif
+ifeq ($(WASM_EXCEPTIONS),true)
+BUILD_CXX_FLAGS += -fexceptions
+endif
+
ifeq ($(WINDOWS),true)
# Always build statically on windows
LINK_FLAGS += -static -static-libgcc -static-libstdc++
diff --git a/distrho/extra/FileBrowserDialogImpl.cpp b/distrho/extra/FileBrowserDialogImpl.cpp
@@ -81,38 +81,63 @@ static constexpr int toHexChar(const char c) noexcept
# define DISTRHO_WASM_NAMESPACE(NS) DISTRHO_WASM_NAMESPACE_HELPER(NS)
// FIXME use world class name as prefix
EM_JS(bool, DISTRHO_WASM_NAMESPACE_MACRO(FILE_BROWSER_DIALOG_NAMESPACE, openWebBrowserFileDialog), (const char* funcname, void* handle), {
- var canvasFileElem = document.getElementById('canvas_file_open');
+ var canvasFileOpenElem = document.getElementById('canvas_file_open');
var jsfuncname = UTF8ToString(funcname);
- if (canvasFileElem) {
- canvasFileElem.onchange = function(e) {
- if (!!canvasFileElem.files) {
- var file = canvasFileElem.files[0];
- var filename = '/' + file.name;
- var reader = new FileReader();
- reader.onloadend = function(e) {
- var content = new Uint8Array(reader.result);
- Module.FS.writeFile(filename, content);
- Module.ccall(jsfuncname, 'null', ['number', 'string'], [handle, filename]);
- };
- reader.readAsArrayBuffer(file);
- }
- };
- canvasFileElem.click();
- return true;
+ var jsfunc = Module.cwrap(jsfuncname, 'null', ['number', 'string']);
+
+ if (!canvasFileOpenElem) {
+ jsfunc(handle, "");
+ return false;
}
- return false;
+
+ canvasFileOpenElem.onchange = function(e) {
+ if (!canvasFileOpenElem.files) {
+ jsfunc(handle, "");
+ return;
+ }
+
+ var file = canvasFileOpenElem.files[0];
+ var filename = '/' + file.name;
+ var reader = new FileReader();
+
+ reader.onloadend = function(e) {
+ var content = new Uint8Array(reader.result);
+ Module.FS.writeFile(filename, content);
+ jsfunc(handle, filename);
+ };
+
+ reader.readAsArrayBuffer(file);
+ };
+
+ canvasFileOpenElem.click();
+ return true;
});
-EM_JS(bool, DISTRHO_WASM_NAMESPACE_MACRO(FILE_BROWSER_DIALOG_NAMESPACE, downloadWebBrowserFile), (), {
- var canvasFileElem = document.getElementById('canvas_file_save');
- if (canvasFileElem) {
- // FIXME filename shouldn't change
- var content = Module.FS.readFile('/download.vcv');
- canvasFileElem.download = 'download.vcv';
- canvasFileElem.href = URL.createObjectURL(new Blob([content]));
- canvasFileElem.click();
- return true;
+EM_JS(bool, DISTRHO_WASM_NAMESPACE_MACRO(FILE_BROWSER_DIALOG_NAMESPACE, downloadWebBrowserFile), (const char* nameprefix, const char* filename), {
+ var canvasFileObjName = UTF8ToString(nameprefix) + "_file_save";
+ var jsfilename = UTF8ToString(filename);
+
+ var canvasFileSaveElem = document.getElementById(canvasFileObjName);
+ if (canvasFileSaveElem) {
+ // only 1 file save allowed at once
+ console.warn("One file save operation already in progress, refusing to open another");
+ return false;
}
- return false;
+
+ canvasFileSaveElem = document.createElement('a');
+ canvasFileSaveElem.download = jsfilename;
+ canvasFileSaveElem.id = canvasFileObjName;
+ canvasFileSaveElem.style.display = 'none';
+ document.body.appendChild(canvasFileSaveElem);
+
+ var content = Module.FS.readFile('/' + jsfilename);
+ canvasFileSaveElem.href = URL.createObjectURL(new Blob([content]));
+ canvasFileSaveElem.click();
+
+ setTimeout(function() {
+ URL.revokeObjectURL(canvasFileSaveElem.href);
+ document.body.removeChild(canvasFileSaveElem);
+ }, 2000);
+ return true;
});
# define openWebBrowserFileDialogNamespaced DISTRHO_WASM_NAMESPACE_MACRO(FILE_BROWSER_DIALOG_NAMESPACE, openWebBrowserFileDialog)
# define downloadWebBrowserFileNamespaced DISTRHO_WASM_NAMESPACE_MACRO(FILE_BROWSER_DIALOG_NAMESPACE, downloadWebBrowserFile)
@@ -134,6 +159,11 @@ struct FileBrowserData {
Display* x11display;
#endif
+#ifdef DISTRHO_OS_WASM
+ char* defaultName;
+ bool saving;
+#endif
+
#ifdef DISTRHO_OS_WINDOWS
OPENFILENAMEW ofn;
volatile bool threadCancelled;
@@ -270,11 +300,11 @@ struct FileBrowserData {
return 0;
}
#else // DISTRHO_OS_WINDOWS
- FileBrowserData(const bool saving)
+ FileBrowserData(const bool save)
: selectedFile(nullptr)
{
#ifdef DISTRHO_OS_MAC
- if (saving)
+ if (save)
{
nsOpenPanel = nullptr;
nsBasePanel = [[NSSavePanel savePanel]retain];
@@ -285,6 +315,10 @@ struct FileBrowserData {
nsBasePanel = nsOpenPanel;
}
#endif
+#ifdef DISTRHO_OS_WASM
+ defaultName = nullptr;
+ saving = save;
+#endif
#ifdef HAVE_DBUS
if ((dbuscon = dbus_bus_get(DBUS_BUS_SESSION, nullptr)) != nullptr)
dbus_connection_set_exit_on_disconnect(dbuscon, false);
@@ -294,7 +328,7 @@ struct FileBrowserData {
#endif
// maybe unused
- return; (void)saving;
+ return; (void)save;
}
~FileBrowserData()
@@ -302,6 +336,9 @@ struct FileBrowserData {
#ifdef DISTRHO_OS_MAC
[nsBasePanel release];
#endif
+#ifdef DISTRHO_OS_WASM
+ std::free(defaultName);
+#endif
#ifdef HAVE_DBUS
if (dbuscon != nullptr)
dbus_connection_unref(dbuscon);
@@ -342,6 +379,8 @@ void fileBrowserSetPathNamespaced(FileBrowserHandle handle, const char* filename
if (filename != nullptr && filename[0] != '\0')
handle->selectedFile = strdup(filename);
+ else
+ handle->selectedFile = kSelectedFileCancelled;
}
}
#endif
@@ -436,7 +475,15 @@ FileBrowserHandle fileBrowserCreate(const bool isEmbed,
#ifdef DISTRHO_OS_WASM
if (options.saving)
{
- handle->selectedFile = strdup("/download");
+ const size_t len = options.defaultName != nullptr ? strlen(options.defaultName) : 0;
+ DISTRHO_SAFE_ASSERT_RETURN(len != 0, nullptr);
+
+ char* const filename = static_cast<char*>(malloc(len + 2));
+ filename[0] = '/';
+ std::memcpy(filename + 1, options.defaultName, len + 1);
+
+ handle->defaultName = strdup(options.defaultName);
+ handle->selectedFile = filename;
return handle.release();
}
@@ -734,8 +781,8 @@ bool fileBrowserIdle(const FileBrowserHandle handle)
void fileBrowserClose(const FileBrowserHandle handle)
{
#ifdef DISTRHO_OS_WASM
- if (fileBrowserGetPath(handle) != nullptr)
- downloadWebBrowserFileNamespaced();
+ if (handle->saving && fileBrowserGetPath(handle) != nullptr)
+ downloadWebBrowserFileNamespaced(DISTRHO_WASM_NAMESPACE(FILE_BROWSER_DIALOG_NAMESPACE), handle->defaultName);
#endif
#ifdef HAVE_X11
diff --git a/distrho/extra/FileBrowserDialogImpl.hpp b/distrho/extra/FileBrowserDialogImpl.hpp
@@ -34,6 +34,9 @@ struct FileBrowserOptions {
/** Whether we are saving, opening files otherwise (default) */
bool saving;
+ /** Default filename when saving, required in some platforms (basename without path separators) */
+ const char* defaultName;
+
/** Start directory, uses current working directory if null */
const char* startDir;
@@ -74,6 +77,7 @@ struct FileBrowserOptions {
/** Constructor for default values */
FileBrowserOptions()
: saving(false),
+ defaultName(nullptr),
startDir(nullptr),
title(nullptr),
buttons() {}