Signed-off-by: falkTX <falktx@falktx.com>tags/23.07
@@ -1 +1 @@ | |||
Subproject commit b4460beb094502c868dda5991e356623b13ce658 | |||
Subproject commit 802e4460844b75b4c2a96c5a9f9baa791209f74e |
@@ -892,8 +892,8 @@ struct AidaWidget : ModuleWidgetWithSideScrews<23> { | |||
heightPedal, | |||
cornerRadius, | |||
cornerRadius, | |||
nvgRGBA(0,0,0,1.f), | |||
nvgRGBA(0,0,0,0.f))); | |||
nvgRGBAf(0,0,0,1.f), | |||
nvgRGBAf(0,0,0,0.f))); | |||
nvgFill(args.vg); | |||
// .rt-neural .grid | |||
@@ -916,7 +916,7 @@ struct AidaWidget : ModuleWidgetWithSideScrews<23> { | |||
nvgFill(args.vg); | |||
// extra | |||
nvgStrokeColor(args.vg, nvgRGBA(150, 150, 150, 0.25f)); | |||
nvgStrokeColor(args.vg, nvgRGBA(150, 150, 150, 60)); | |||
nvgStroke(args.vg); | |||
drawOutputJacksArea(args.vg); | |||
@@ -471,10 +471,10 @@ struct AudioFileListWidget : ImGuiWidget { | |||
selectedFile = (size_t)-1; | |||
static constexpr const char* const supportedExtensions[] = { | |||
#ifdef HAVE_SNDFILE | |||
#ifdef HAVE_SNDFILE | |||
".aif",".aifc",".aiff",".au",".bwf",".flac",".htk",".iff",".mat4",".mat5",".oga",".ogg",".opus", | |||
".paf",".pvf",".pvf5",".sd2",".sf",".snd",".svx",".vcc",".w64",".wav",".xi", | |||
#endif | |||
#endif | |||
".mp3" | |||
}; | |||
@@ -89,9 +89,9 @@ | |||
#ifdef DISTRHO_OS_WASM | |||
# if CARDINAL_VARIANT_MINI | |||
# define CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME "welcome-wasm-mini.vcv" | |||
# define CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME "welcome-wasm-mini" | |||
# else | |||
# define CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME "welcome-wasm.vcv" | |||
# define CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME "welcome-wasm" | |||
# endif | |||
#endif | |||
@@ -374,6 +374,17 @@ static int osc_screenshot_handler(const char*, const char* types, lo_arg** argv, | |||
} | |||
#endif | |||
// ----------------------------------------------------------------------------------------------------------- | |||
#ifdef DISTRHO_OS_WASM | |||
static void WebBrowserDataLoaded(void* const data) | |||
{ | |||
static_cast<Initializer*>(data)->loadSettings(true); | |||
} | |||
#endif | |||
// ----------------------------------------------------------------------------------------------------------- | |||
Initializer::Initializer(const CardinalBasePlugin* const plugin, const CardinalBaseUI* const ui) | |||
{ | |||
using namespace rack; | |||
@@ -490,7 +501,17 @@ Initializer::Initializer(const CardinalBasePlugin* const plugin, const CardinalB | |||
#endif | |||
if (isRealInstance) | |||
{ | |||
#ifdef DISTRHO_OS_WASM | |||
EM_ASM({ | |||
Module.FS.mkdir('/userfiles'); | |||
Module.FS.mount(Module.IDBFS, {}, '/userfiles'); | |||
Module.FS.syncfs(true, function(err) { if (!err) { dynCall('vi', $0, [$1]) } }); | |||
}, WebBrowserDataLoaded, this); | |||
#else | |||
system::createDirectory(asset::userDir); | |||
#endif | |||
} | |||
} | |||
#ifndef CARDINAL_COMMON_DSP_ONLY | |||
@@ -513,13 +534,11 @@ Initializer::Initializer(const CardinalBasePlugin* const plugin, const CardinalB | |||
if (settings::settingsPath.empty()) | |||
settings::settingsPath = asset::config(CARDINAL_VARIANT_NAME ".json"); | |||
const std::string patchesPath = asset::patchesPath(); | |||
templatePath = asset::user("templates/" CARDINAL_VARIANT_NAME ".vcv"); | |||
#ifdef DISTRHO_OS_WASM | |||
templatePath = system::join(patchesPath, CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME ".vcv"); | |||
factoryTemplatePath = system::join(patchesPath, "templates/" CARDINAL_VARIANT_NAME ".vcv"); | |||
factoryTemplatePath = system::join(asset::patchesPath(), CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME ".vcv"); | |||
#else | |||
templatePath = asset::user("templates/" CARDINAL_VARIANT_NAME ".vcv"); | |||
factoryTemplatePath = system::join(patchesPath, "templates/" CARDINAL_VARIANT_NAME ".vcv"); | |||
factoryTemplatePath = system::join(asset::patchesPath(), "templates/" CARDINAL_VARIANT_NAME ".vcv"); | |||
#endif | |||
// Log environment | |||
@@ -672,7 +691,8 @@ bool isMini() | |||
bool isStandalone() | |||
{ | |||
return std::strstr(getPluginFormatName(), "Standalone") != nullptr; | |||
static const bool standalone = std::strstr(getPluginFormatName(), "Standalone") != nullptr; | |||
return standalone; | |||
} | |||
#ifdef ARCH_WIN | |||
@@ -712,6 +732,15 @@ std::string getSpecialPath(const SpecialPath type) | |||
char* patchFromURL = nullptr; | |||
char* patchRemoteURL = nullptr; | |||
char* patchStorageSlug = nullptr; | |||
void syncfs() | |||
{ | |||
settings::save(); | |||
EM_ASM({ | |||
Module.FS.syncfs(false, function(){} ); | |||
}); | |||
} | |||
#endif | |||
std::string homeDir() | |||
@@ -783,6 +812,10 @@ void loadPathDialog(const std::string& path, const bool asTemplate) | |||
APP->history->setSaved(); | |||
} | |||
#ifdef DISTRHO_OS_WASM | |||
syncfs(); | |||
#endif | |||
if (remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote()) | |||
if (remoteDetails->autoDeploy) | |||
remoteUtils::sendFullPatchToRemote(remoteDetails); | |||
@@ -812,6 +845,10 @@ void loadSelectionDialog() | |||
std::free(pathC); | |||
#ifdef DISTRHO_OS_WASM | |||
syncfs(); | |||
#endif | |||
if (remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote()) | |||
if (remoteDetails->autoDeploy) | |||
remoteUtils::sendFullPatchToRemote(remoteDetails); | |||
@@ -839,6 +876,10 @@ void loadTemplate(const bool factory) | |||
APP->patch->path.clear(); | |||
APP->history->setSaved(); | |||
#ifdef DISTRHO_OS_WASM | |||
syncfs(); | |||
#endif | |||
if (remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote()) | |||
if (remoteDetails->autoDeploy) | |||
remoteUtils::sendFullPatchToRemote(remoteDetails); | |||
@@ -862,6 +903,10 @@ void revertDialog() | |||
promptClear("Revert patch to the last saved state?", []{ | |||
APP->patch->loadAction(APP->patch->path); | |||
#ifdef DISTRHO_OS_WASM | |||
syncfs(); | |||
#endif | |||
if (remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote()) | |||
if (remoteDetails->autoDeploy) | |||
remoteUtils::sendFullPatchToRemote(remoteDetails); | |||
@@ -886,6 +931,14 @@ void saveDialog(const std::string& path) | |||
asyncDialog::create(string::f("Could not save patch: %s", e.what()).c_str()); | |||
return; | |||
} | |||
APP->patch->pushRecentPath(path); | |||
#ifdef DISTRHO_OS_WASM | |||
syncfs(); | |||
#else | |||
rack::settings::save(); | |||
#endif | |||
#endif | |||
} | |||
@@ -944,7 +997,11 @@ void saveTemplateDialog() | |||
catch (Exception& e) { | |||
asyncDialog::create(string::f("Could not save template patch: %s", e.what()).c_str()); | |||
return; | |||
} | |||
} | |||
#ifdef DISTRHO_OS_WASM | |||
syncfs(); | |||
#endif | |||
}); | |||
} | |||
@@ -53,6 +53,7 @@ std::string getSpecialPath(SpecialPath type); | |||
extern char* patchFromURL; | |||
extern char* patchRemoteURL; | |||
extern char* patchStorageSlug; | |||
void syncfs(); | |||
#endif | |||
std::string homeDir(); | |||
@@ -66,6 +66,11 @@ namespace app { | |||
rack::widget::Widget* createMenuBar() { return new rack::widget::Widget; } | |||
} | |||
#endif | |||
#ifdef DISTRHO_OS_WASM | |||
namespace asset { | |||
std::string patchesPath(); | |||
} | |||
#endif | |||
namespace engine { | |||
void Engine_setAboutToClose(Engine*); | |||
} | |||
@@ -312,6 +317,15 @@ public: | |||
context->scene->rackScroll->reset(); | |||
} | |||
#ifdef DISTRHO_OS_WASM | |||
// switch factory template to regular one after first load | |||
#if CARDINAL_VARIANT_MINI | |||
context->patch->factoryTemplatePath = rack::system::join(rack::asset::patchesPath(), "templates/mini.vcv"); | |||
#else | |||
context->patch->factoryTemplatePath = rack::system::join(rack::asset::patchesPath(), "templates/main.vcv"); | |||
#endif | |||
#endif | |||
#ifdef CARDINAL_INIT_OSC_THREAD | |||
fInitializer->remotePluginInstance = this; | |||
#endif | |||
@@ -62,6 +62,11 @@ | |||
#endif | |||
namespace rack { | |||
#ifdef DISTRHO_OS_WASM | |||
namespace asset { | |||
std::string patchesPath(); | |||
} | |||
#endif | |||
namespace engine { | |||
void Engine_setAboutToClose(Engine*); | |||
void Engine_setRemoteDetails(Engine*, remoteUtils::RemoteDetails*); | |||
@@ -246,7 +251,7 @@ static void downloadRemotePatchFailed(const char* const filename) | |||
} | |||
using namespace rack; | |||
context->patch->templatePath = system::join(asset::systemDir, "init/wasm.vcv"); // FIXME | |||
context->patch->templatePath = rack::system::join(asset::patchesPath(), "templates/main.vcv"); | |||
context->patch->loadTemplate(); | |||
context->scene->rackScroll->reset(); | |||
} | |||
@@ -1228,7 +1233,11 @@ protected: | |||
context->patch->pushRecentPath(sfilename); | |||
context->history->setSaved(); | |||
#ifdef DISTRHO_OS_WASM | |||
rack::syncfs(); | |||
#else | |||
rack::settings::save(); | |||
#endif | |||
} | |||
#if 0 | |||
@@ -283,6 +283,7 @@ LINK_FLAGS += -O3 | |||
LINK_FLAGS += -sALLOW_MEMORY_GROWTH | |||
LINK_FLAGS += -sINITIAL_MEMORY=64Mb | |||
LINK_FLAGS += -sLZ4=1 | |||
LINK_FLAGS += -lidbfs.js | |||
ifeq ($(CARDINAL_VARIANT),mini) | |||
LINK_FLAGS += --preload-file=../../bin/CardinalMini.lv2/resources@/resources | |||
@@ -56,6 +56,11 @@ | |||
#include "DistrhoPlugin.hpp" | |||
#include "DistrhoStandaloneUtils.hpp" | |||
#ifdef DISTRHO_OS_WASM | |||
# include <emscripten/emscripten.h> | |||
# undef HAVE_LIBLO | |||
#endif | |||
#ifdef HAVE_LIBLO | |||
# include <lo/lo.h> | |||
#endif | |||
@@ -98,6 +103,28 @@ struct FileButton : MenuButton { | |||
const bool isStandalone; | |||
std::vector<std::string> demoPatches; | |||
#ifdef DISTRHO_OS_WASM | |||
static void WebBrowserDataSaved(const int err) | |||
{ | |||
err ? async_dialog_message("Error, could not save web browser data!") | |||
: async_dialog_message("Web browser data saved!"); | |||
} | |||
static void wasmSaveAs() | |||
{ | |||
async_dialog_text_input("Filename", nullptr, [](char* const filename) { | |||
if (filename == nullptr) | |||
return; | |||
APP->patch->path = "/userfiles/"; | |||
APP->patch->path += filename; | |||
if (rack::system::getExtension(filename) != ".vcv") | |||
APP->patch->path += ".vcv"; | |||
patchUtils::saveDialog(APP->patch->path); | |||
std::free(filename); | |||
}); | |||
} | |||
#endif | |||
FileButton(const bool standalone) | |||
: MenuButton(), isStandalone(standalone) | |||
{ | |||
@@ -131,7 +158,6 @@ struct FileButton : MenuButton { | |||
})); | |||
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS | |||
#ifndef DISTRHO_OS_WASM | |||
menu->addChild(createMenuItem("New (factory template)", "", []() { | |||
patchUtils::loadTemplateDialog(true); | |||
})); | |||
@@ -149,6 +175,11 @@ struct FileButton : MenuButton { | |||
} | |||
}, settings::recentPatchPaths.empty())); | |||
menu->addChild(createMenuItem("Import selection...", "", [=]() { | |||
patchUtils::loadSelectionDialog(); | |||
}, false, true)); | |||
#ifndef DISTRHO_OS_WASM | |||
menu->addChild(createMenuItem("Save", RACK_MOD_CTRL_NAME "+S", []() { | |||
// NOTE: will do nothing if path is empty, intentionally | |||
patchUtils::saveDialog(APP->patch->path); | |||
@@ -158,13 +189,16 @@ struct FileButton : MenuButton { | |||
patchUtils::saveAsDialog(); | |||
})); | |||
#else | |||
menu->addChild(createMenuItem("Import patch...", RACK_MOD_CTRL_NAME "+O", []() { | |||
patchUtils::loadDialog(); | |||
menu->addChild(createMenuItem("Save", "", []() { | |||
if (APP->patch->path.empty()) | |||
wasmSaveAs(); | |||
else | |||
patchUtils::saveDialog(APP->patch->path); | |||
})); | |||
menu->addChild(createMenuItem("Import selection...", "", [=]() { | |||
patchUtils::loadSelectionDialog(); | |||
}, false, true)); | |||
menu->addChild(createMenuItem("Save as", "", []() { | |||
wasmSaveAs(); | |||
})); | |||
menu->addChild(createMenuItem("Save and download compressed", RACK_MOD_CTRL_NAME "+Shift+S", []() { | |||
patchUtils::saveAsDialog(); | |||
@@ -184,6 +218,17 @@ struct FileButton : MenuButton { | |||
patchUtils::saveTemplateDialog(); | |||
})); | |||
#ifdef DISTRHO_OS_WASM | |||
menu->addChild(new ui::MenuSeparator); | |||
menu->addChild(createMenuItem("Save persistent browser data", "", []() { | |||
settings::save(); | |||
EM_ASM({ | |||
Module.FS.syncfs(false, function(err){ dynCall('vi', $0, [!!err]) }); | |||
}, WebBrowserDataSaved); | |||
})); | |||
#endif | |||
#if defined(HAVE_LIBLO) || ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS | |||
#ifdef __MOD_DEVICES__ | |||
#define REMOTE_NAME "MOD" | |||
@@ -213,21 +258,6 @@ struct FileButton : MenuButton { | |||
} | |||
#endif | |||
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS | |||
#ifndef DISTRHO_OS_WASM | |||
menu->addChild(new ui::MenuSeparator); | |||
// Load selection | |||
menu->addChild(createMenuItem("Import selection...", "", [=]() { | |||
patchUtils::loadSelectionDialog(); | |||
}, false, true)); | |||
menu->addChild(createMenuItem("Export uncompressed json...", "", []() { | |||
patchUtils::saveAsDialogUncompressed(); | |||
})); | |||
#endif | |||
#endif | |||
if (!demoPatches.empty()) | |||
{ | |||
menu->addChild(new ui::MenuSeparator); | |||
@@ -276,13 +276,11 @@ void Scene::onHoverKey(const HoverKeyEvent& e) { | |||
patchUtils::revertDialog(); | |||
e.consume(this); | |||
} | |||
#ifndef DISTRHO_OS_WASM | |||
if (e.keyName == "s" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||
// NOTE: will do nothing if path is empty, intentionally | |||
patchUtils::saveDialog(APP->patch->path); | |||
e.consume(this); | |||
} | |||
#endif | |||
if (e.keyName == "s" && (e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) { | |||
patchUtils::saveAsDialog(); | |||
e.consume(this); | |||