Setup mini variant UI, move around more code to accomodate this
Signed-off-by: falkTX <falktx@falktx.com>
This commit is contained in:
parent
cf74324568
commit
a85679758c
12 changed files with 534 additions and 334 deletions
2
dpf
2
dpf
|
@ -1 +1 @@
|
||||||
Subproject commit 564f6519b4bbf1c6cc8791a9adbb377f6cfd4984
|
Subproject commit 79948069d581c64bd19bc454234550de88b459a2
|
|
@ -293,6 +293,10 @@ PLUGIN_FILES += Cardinal/src/ImGuiTextEditor.cpp
|
||||||
PLUGIN_FILES += Cardinal/src/SassyScope.cpp
|
PLUGIN_FILES += Cardinal/src/SassyScope.cpp
|
||||||
PLUGIN_FILES += Cardinal/src/DearImGui.cpp
|
PLUGIN_FILES += Cardinal/src/DearImGui.cpp
|
||||||
PLUGIN_FILES += Cardinal/src/DearImGuiColorTextEditor.cpp
|
PLUGIN_FILES += Cardinal/src/DearImGuiColorTextEditor.cpp
|
||||||
|
MINIPLUGIN_FILES += Cardinal/src/ImGuiWidget.cpp
|
||||||
|
MINIPLUGIN_FILES += Cardinal/src/ImGuiTextEditor.cpp
|
||||||
|
MINIPLUGIN_FILES += Cardinal/src/DearImGui.cpp
|
||||||
|
MINIPLUGIN_FILES += Cardinal/src/DearImGuiColorTextEditor.cpp
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(shell $(PKG_CONFIG) --exists fftw3f && echo true),true)
|
ifeq ($(shell $(PKG_CONFIG) --exists fftw3f && echo true),true)
|
||||||
|
@ -1290,7 +1294,7 @@ endif
|
||||||
ifeq ($(NOPLUGINS),true)
|
ifeq ($(NOPLUGINS),true)
|
||||||
TARGETS = noplugins$(TARGET_SUFFIX).a
|
TARGETS = noplugins$(TARGET_SUFFIX).a
|
||||||
else
|
else
|
||||||
TARGETS = plugins$(TARGET_SUFFIX).a plugins-mini-headless.a
|
TARGETS = plugins$(TARGET_SUFFIX).a plugins-mini.a
|
||||||
endif
|
endif
|
||||||
|
|
||||||
all: $(TARGETS)
|
all: $(TARGETS)
|
||||||
|
|
|
@ -189,6 +189,7 @@ void destroyStaticPlugins()
|
||||||
|
|
||||||
void updateStaticPluginsDarkMode()
|
void updateStaticPluginsDarkMode()
|
||||||
{
|
{
|
||||||
|
d_stdout("TODO");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include <settings.hpp>
|
#include <settings.hpp>
|
||||||
#include <string.hpp>
|
#include <string.hpp>
|
||||||
#include <system.hpp>
|
#include <system.hpp>
|
||||||
|
#include <app/Browser.hpp>
|
||||||
#include <app/Scene.hpp>
|
#include <app/Scene.hpp>
|
||||||
#include <window/Window.hpp>
|
#include <window/Window.hpp>
|
||||||
|
|
||||||
|
@ -65,6 +66,27 @@
|
||||||
# define HEADLESS
|
# define HEADLESS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CARDINAL_VARIANT_FX
|
||||||
|
# define CARDINAL_TEMPLATE_NAME "init/fx.vcv"
|
||||||
|
#elif CARDINAL_VARIANT_NATIVE
|
||||||
|
# define CARDINAL_TEMPLATE_NAME "init/native.vcv"
|
||||||
|
#elif CARDINAL_VARIANT_SYNTH
|
||||||
|
# define CARDINAL_TEMPLATE_NAME "init/synth.vcv"
|
||||||
|
#else
|
||||||
|
# define CARDINAL_TEMPLATE_NAME "init/main.vcv"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace rack {
|
||||||
|
namespace asset {
|
||||||
|
std::string patchesPath();
|
||||||
|
void destroy();
|
||||||
|
}
|
||||||
|
namespace plugin {
|
||||||
|
void initStaticPlugins();
|
||||||
|
void destroyStaticPlugins();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const std::string CARDINAL_VERSION = "22.12";
|
const std::string CARDINAL_VERSION = "22.12";
|
||||||
|
|
||||||
START_NAMESPACE_DISTRHO
|
START_NAMESPACE_DISTRHO
|
||||||
|
@ -172,6 +194,284 @@ void CardinalPluginContext::writeMidiMessage(const rack::midi::Message& message,
|
||||||
plugin->writeMidiEvent(event);
|
plugin->writeMidiEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifdef CARDINAL_INIT_OSC_THREAD
|
||||||
|
static void osc_error_handler(int num, const char* msg, const char* path)
|
||||||
|
{
|
||||||
|
d_stderr("Cardinal OSC Error: code: %i, msg: \"%s\", path: \"%s\")", num, msg, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int osc_fallback_handler(const char* const path, const char* const types, lo_arg**, int, lo_message, void*)
|
||||||
|
{
|
||||||
|
d_stderr("Cardinal OSC unhandled message \"%s\" with types \"%s\"", path, types);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int osc_hello_handler(const char*, const char*, lo_arg**, int, const lo_message m, void* const self)
|
||||||
|
{
|
||||||
|
d_stdout("osc_hello_handler()");
|
||||||
|
const lo_address source = lo_message_get_source(m);
|
||||||
|
lo_send_from(source, static_cast<Initializer*>(self)->oscServer, LO_TT_IMMEDIATE, "/resp", "ss", "hello", "ok");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int osc_load_handler(const char*, const char* types, lo_arg** argv, int argc, const lo_message m, void* const self)
|
||||||
|
{
|
||||||
|
d_stdout("osc_load_handler()");
|
||||||
|
DISTRHO_SAFE_ASSERT_RETURN(argc == 1, 0);
|
||||||
|
DISTRHO_SAFE_ASSERT_RETURN(types != nullptr && types[0] == 'b', 0);
|
||||||
|
|
||||||
|
const int32_t size = argv[0]->blob.size;
|
||||||
|
DISTRHO_SAFE_ASSERT_RETURN(size > 4, 0);
|
||||||
|
|
||||||
|
const uint8_t* const blob = (uint8_t*)(&argv[0]->blob.data);
|
||||||
|
DISTRHO_SAFE_ASSERT_RETURN(blob != nullptr, 0);
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
|
||||||
|
if (CardinalBasePlugin* const plugin = static_cast<Initializer*>(self)->oscPlugin)
|
||||||
|
{
|
||||||
|
CardinalPluginContext* const context = plugin->context;
|
||||||
|
std::vector<uint8_t> data(size);
|
||||||
|
std::memcpy(data.data(), blob, size);
|
||||||
|
|
||||||
|
rack::contextSet(context);
|
||||||
|
rack::system::removeRecursively(context->patch->autosavePath);
|
||||||
|
rack::system::createDirectories(context->patch->autosavePath);
|
||||||
|
try {
|
||||||
|
rack::system::unarchiveToDirectory(data, context->patch->autosavePath);
|
||||||
|
context->patch->loadAutosave();
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
catch (rack::Exception& e) {
|
||||||
|
WARN("%s", e.what());
|
||||||
|
}
|
||||||
|
rack::contextSet(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
const lo_address source = lo_message_get_source(m);
|
||||||
|
lo_send_from(source, static_cast<Initializer*>(self)->oscServer,
|
||||||
|
LO_TT_IMMEDIATE, "/resp", "ss", "load", ok ? "ok" : "fail");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int osc_screenshot_handler(const char*, const char* types, lo_arg** argv, int argc, const lo_message m, void* const self)
|
||||||
|
{
|
||||||
|
d_stdout("osc_screenshot_handler()");
|
||||||
|
DISTRHO_SAFE_ASSERT_RETURN(argc == 1, 0);
|
||||||
|
DISTRHO_SAFE_ASSERT_RETURN(types != nullptr && types[0] == 'b', 0);
|
||||||
|
|
||||||
|
const int32_t size = argv[0]->blob.size;
|
||||||
|
DISTRHO_SAFE_ASSERT_RETURN(size > 4, 0);
|
||||||
|
|
||||||
|
const uint8_t* const blob = (uint8_t*)(&argv[0]->blob.data);
|
||||||
|
DISTRHO_SAFE_ASSERT_RETURN(blob != nullptr, 0);
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
|
||||||
|
if (CardinalBasePlugin* const plugin = static_cast<Initializer*>(self)->oscPlugin)
|
||||||
|
ok = plugin->updateStateValue("screenshot", String::asBase64(blob, size).buffer());
|
||||||
|
|
||||||
|
const lo_address source = lo_message_get_source(m);
|
||||||
|
lo_send_from(source, static_cast<Initializer*>(self)->oscServer,
|
||||||
|
LO_TT_IMMEDIATE, "/resp", "ss", "screenshot", ok ? "ok" : "fail");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Initializer::Initializer(const CardinalBasePlugin* const plugin, const CardinalBaseUI* const ui)
|
||||||
|
{
|
||||||
|
using namespace rack;
|
||||||
|
|
||||||
|
#ifdef DISTRHO_OS_WASM
|
||||||
|
settings::allowCursorLock = true;
|
||||||
|
#else
|
||||||
|
settings::allowCursorLock = false;
|
||||||
|
#endif
|
||||||
|
settings::autoCheckUpdates = false;
|
||||||
|
settings::autosaveInterval = 0;
|
||||||
|
settings::devMode = true;
|
||||||
|
settings::isPlugin = true;
|
||||||
|
settings::skipLoadOnLaunch = true;
|
||||||
|
settings::showTipsOnLaunch = false;
|
||||||
|
settings::windowPos = math::Vec(0, 0);
|
||||||
|
#ifdef HEADLESS
|
||||||
|
settings::headless = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// copied from https://community.vcvrack.com/t/16-colour-cable-palette/15951
|
||||||
|
settings::cableColors = {
|
||||||
|
color::fromHexString("#ff5252"),
|
||||||
|
color::fromHexString("#ff9352"),
|
||||||
|
color::fromHexString("#ffd452"),
|
||||||
|
color::fromHexString("#e8ff52"),
|
||||||
|
color::fromHexString("#a8ff52"),
|
||||||
|
color::fromHexString("#67ff52"),
|
||||||
|
color::fromHexString("#52ff7d"),
|
||||||
|
color::fromHexString("#52ffbe"),
|
||||||
|
color::fromHexString("#52ffff"),
|
||||||
|
color::fromHexString("#52beff"),
|
||||||
|
color::fromHexString("#527dff"),
|
||||||
|
color::fromHexString("#6752ff"),
|
||||||
|
color::fromHexString("#a852ff"),
|
||||||
|
color::fromHexString("#e952ff"),
|
||||||
|
color::fromHexString("#ff52d4"),
|
||||||
|
color::fromHexString("#ff5293"),
|
||||||
|
};
|
||||||
|
|
||||||
|
system::init();
|
||||||
|
logger::init();
|
||||||
|
random::init();
|
||||||
|
ui::init();
|
||||||
|
|
||||||
|
if (asset::systemDir.empty())
|
||||||
|
{
|
||||||
|
if (const char* const bundlePath = (plugin != nullptr ? plugin->getBundlePath() :
|
||||||
|
ui != nullptr ? ui->getBundlePath() : nullptr))
|
||||||
|
{
|
||||||
|
if (const char* const resourcePath = getResourcePath(bundlePath))
|
||||||
|
{
|
||||||
|
asset::systemDir = resourcePath;
|
||||||
|
asset::bundlePath = system::join(asset::systemDir, "PluginManifests");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (asset::systemDir.empty() || ! system::exists(asset::systemDir) || ! system::exists(asset::bundlePath))
|
||||||
|
{
|
||||||
|
#ifdef CARDINAL_PLUGIN_SOURCE_DIR
|
||||||
|
// Make system dir point to source code location as fallback
|
||||||
|
asset::systemDir = CARDINAL_PLUGIN_SOURCE_DIR DISTRHO_OS_SEP_STR "Rack";
|
||||||
|
asset::bundlePath.clear();
|
||||||
|
|
||||||
|
// If source code dir does not exist use install target prefix as system dir
|
||||||
|
if (!system::exists(system::join(asset::systemDir, "res")))
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if defined(DISTRHO_OS_WASM)
|
||||||
|
asset::systemDir = "/resources";
|
||||||
|
#elif defined(ARCH_MAC)
|
||||||
|
asset::systemDir = "/Library/Application Support/Cardinal";
|
||||||
|
#elif defined(ARCH_WIN)
|
||||||
|
const std::string commonprogfiles = getSpecialPath(kSpecialPathCommonProgramFiles);
|
||||||
|
if (! commonprogfiles.empty())
|
||||||
|
asset::systemDir = system::join(commonprogfiles, "Cardinal");
|
||||||
|
#else
|
||||||
|
asset::systemDir = CARDINAL_PLUGIN_PREFIX "/share/cardinal";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
asset::bundlePath = system::join(asset::systemDir, "PluginManifests");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
asset::userDir = asset::systemDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string patchesPath = asset::patchesPath();
|
||||||
|
#ifdef DISTRHO_OS_WASM
|
||||||
|
templatePath = system::join(patchesPath, CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME);
|
||||||
|
#else
|
||||||
|
templatePath = system::join(patchesPath, CARDINAL_TEMPLATE_NAME);
|
||||||
|
#endif
|
||||||
|
factoryTemplatePath = system::join(patchesPath, CARDINAL_TEMPLATE_NAME);
|
||||||
|
|
||||||
|
// Log environment
|
||||||
|
INFO("%s %s %s, compatible with Rack version %s", APP_NAME.c_str(), APP_EDITION.c_str(), CARDINAL_VERSION.c_str(), APP_VERSION.c_str());
|
||||||
|
INFO("%s", system::getOperatingSystemInfo().c_str());
|
||||||
|
INFO("Binary filename: %s", getBinaryFilename());
|
||||||
|
if (plugin != nullptr) {
|
||||||
|
INFO("Bundle path: %s", plugin->getBundlePath());
|
||||||
|
} else if (ui != nullptr) {
|
||||||
|
INFO("Bundle path: %s", ui->getBundlePath());
|
||||||
|
}
|
||||||
|
INFO("System directory: %s", asset::systemDir.c_str());
|
||||||
|
INFO("User directory: %s", asset::userDir.c_str());
|
||||||
|
INFO("Template patch: %s", templatePath.c_str());
|
||||||
|
INFO("System template patch: %s", factoryTemplatePath.c_str());
|
||||||
|
|
||||||
|
// Report to user if something is wrong with the installation
|
||||||
|
if (asset::systemDir.empty())
|
||||||
|
{
|
||||||
|
d_stderr2("Failed to locate Cardinal plugin bundle.\n"
|
||||||
|
"Install Cardinal with its bundle folder intact and try again.");
|
||||||
|
}
|
||||||
|
else if (! system::exists(asset::systemDir))
|
||||||
|
{
|
||||||
|
d_stderr2("System directory \"%s\" does not exist.\n"
|
||||||
|
"Make sure Cardinal was downloaded and installed correctly.", asset::systemDir.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
INFO("Initializing plugins");
|
||||||
|
plugin::initStaticPlugins();
|
||||||
|
|
||||||
|
INFO("Initializing plugin browser DB");
|
||||||
|
app::browserInit();
|
||||||
|
|
||||||
|
#ifdef CARDINAL_INIT_OSC_THREAD
|
||||||
|
INFO("Initializing OSC Remote control");
|
||||||
|
oscServer = lo_server_new_with_proto(REMOTE_HOST_PORT, LO_UDP, osc_error_handler);
|
||||||
|
DISTRHO_SAFE_ASSERT_RETURN(oscServer != nullptr,);
|
||||||
|
|
||||||
|
lo_server_add_method(oscServer, "/hello", "", osc_hello_handler, this);
|
||||||
|
lo_server_add_method(oscServer, "/load", "b", osc_load_handler, this);
|
||||||
|
lo_server_add_method(oscServer, "/screenshot", "b", osc_screenshot_handler, this);
|
||||||
|
lo_server_add_method(oscServer, nullptr, nullptr, osc_fallback_handler, nullptr);
|
||||||
|
|
||||||
|
startThread();
|
||||||
|
#else
|
||||||
|
INFO("OSC Remote control is not enabled in this build");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
Initializer::~Initializer()
|
||||||
|
{
|
||||||
|
using namespace rack;
|
||||||
|
|
||||||
|
#ifdef CARDINAL_INIT_OSC_THREAD
|
||||||
|
if (oscServer != nullptr)
|
||||||
|
{
|
||||||
|
stopThread(5000);
|
||||||
|
lo_server_del_method(oscServer, nullptr, nullptr);
|
||||||
|
lo_server_free(oscServer);
|
||||||
|
oscServer = nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
INFO("Clearing asset paths");
|
||||||
|
asset::bundlePath.clear();
|
||||||
|
asset::systemDir.clear();
|
||||||
|
asset::userDir.clear();
|
||||||
|
|
||||||
|
INFO("Destroying plugins");
|
||||||
|
plugin::destroyStaticPlugins();
|
||||||
|
|
||||||
|
INFO("Destroying colourized assets");
|
||||||
|
asset::destroy();
|
||||||
|
|
||||||
|
INFO("Destroying settings");
|
||||||
|
settings::destroy();
|
||||||
|
|
||||||
|
INFO("Destroying logger");
|
||||||
|
logger::destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CARDINAL_INIT_OSC_THREAD
|
||||||
|
void Initializer::run()
|
||||||
|
{
|
||||||
|
INFO("OSC Thread Listening for remote commands");
|
||||||
|
|
||||||
|
while (! shouldThreadExit())
|
||||||
|
{
|
||||||
|
d_msleep(200);
|
||||||
|
while (lo_server_recv_noblock(oscServer, 0) != 0) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
INFO("OSC Thread Closed");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
END_NAMESPACE_DISTRHO
|
END_NAMESPACE_DISTRHO
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -15,14 +15,17 @@
|
||||||
* For a full copy of the GNU General Public License see the LICENSE file.
|
* For a full copy of the GNU General Public License see the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "DistrhoUtils.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#ifdef HAVE_LIBLO
|
#ifdef HAVE_LIBLO
|
||||||
// # define REMOTE_HOST "localhost"
|
// # define REMOTE_HOST "localhost"
|
||||||
# define REMOTE_HOST "192.168.51.1"
|
# define REMOTE_HOST "192.168.51.1"
|
||||||
# define REMOTE_HOST_PORT "2228"
|
# define REMOTE_HOST_PORT "2228"
|
||||||
|
# include "extra/Thread.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DISTRHO_OS_WASM
|
#ifdef DISTRHO_OS_WASM
|
||||||
|
@ -35,6 +38,8 @@
|
||||||
|
|
||||||
extern const std::string CARDINAL_VERSION;
|
extern const std::string CARDINAL_VERSION;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
namespace rack {
|
namespace rack {
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
|
@ -65,6 +70,8 @@ extern char* patchStorageSlug;
|
||||||
|
|
||||||
} // namespace rack
|
} // namespace rack
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
namespace patchUtils {
|
namespace patchUtils {
|
||||||
|
|
||||||
void loadDialog();
|
void loadDialog();
|
||||||
|
@ -86,3 +93,37 @@ void deployToRemote();
|
||||||
void sendScreenshotToRemote(const char* screenshot);
|
void sendScreenshotToRemote(const char* screenshot);
|
||||||
|
|
||||||
} // namespace patchUtils
|
} // namespace patchUtils
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if defined(HAVE_LIBLO) && defined(HEADLESS) && DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||||
|
# define CARDINAL_INIT_OSC_THREAD
|
||||||
|
#endif
|
||||||
|
|
||||||
|
START_NAMESPACE_DISTRHO
|
||||||
|
|
||||||
|
class CardinalBasePlugin;
|
||||||
|
class CardinalBaseUI;
|
||||||
|
|
||||||
|
struct Initializer
|
||||||
|
#ifdef CARDINAL_INIT_OSC_THREAD
|
||||||
|
: public Thread
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#ifdef CARDINAL_INIT_OSC_THREAD
|
||||||
|
lo_server oscServer = nullptr;
|
||||||
|
CardinalBasePlugin* oscPlugin = nullptr;
|
||||||
|
#endif
|
||||||
|
std::string templatePath;
|
||||||
|
std::string factoryTemplatePath;
|
||||||
|
|
||||||
|
Initializer(const CardinalBasePlugin* plugin, const CardinalBaseUI* ui);
|
||||||
|
~Initializer();
|
||||||
|
#ifdef CARDINAL_INIT_OSC_THREAD
|
||||||
|
void run() override;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
END_NAMESPACE_DISTRHO
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -31,8 +31,8 @@
|
||||||
#define DISTRHO_PLUGIN_URI "https://distrho.kx.studio/plugins/cardinal#mini"
|
#define DISTRHO_PLUGIN_URI "https://distrho.kx.studio/plugins/cardinal#mini"
|
||||||
#define DISTRHO_PLUGIN_CLAP_ID "studio.kx.distrho.cardinal#mini"
|
#define DISTRHO_PLUGIN_CLAP_ID "studio.kx.distrho.cardinal#mini"
|
||||||
|
|
||||||
#define DISTRHO_PLUGIN_NAME "Cardinal FX"
|
#define DISTRHO_PLUGIN_NAME "Cardinal Mini"
|
||||||
#define DISTRHO_PLUGIN_LABEL "CardinalFX"
|
#define DISTRHO_PLUGIN_LABEL "CardinalMini"
|
||||||
|
|
||||||
#define DISTRHO_PLUGIN_HAS_UI 1
|
#define DISTRHO_PLUGIN_HAS_UI 1
|
||||||
#define DISTRHO_PLUGIN_WANT_DIRECT_ACCESS 0
|
#define DISTRHO_PLUGIN_WANT_DIRECT_ACCESS 0
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
* For a full copy of the GNU General Public License see the LICENSE file.
|
* For a full copy of the GNU General Public License see the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <asset.hpp>
|
|
||||||
#include <library.hpp>
|
#include <library.hpp>
|
||||||
#include <midi.hpp>
|
#include <midi.hpp>
|
||||||
#include <patch.hpp>
|
#include <patch.hpp>
|
||||||
|
@ -24,7 +23,6 @@
|
||||||
#include <settings.hpp>
|
#include <settings.hpp>
|
||||||
#include <system.hpp>
|
#include <system.hpp>
|
||||||
|
|
||||||
#include <app/Browser.hpp>
|
|
||||||
#include <app/Scene.hpp>
|
#include <app/Scene.hpp>
|
||||||
#include <engine/Engine.hpp>
|
#include <engine/Engine.hpp>
|
||||||
#include <ui/common.hpp>
|
#include <ui/common.hpp>
|
||||||
|
@ -52,16 +50,6 @@
|
||||||
# include "extra/SharedResourcePointer.hpp"
|
# include "extra/SharedResourcePointer.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CARDINAL_VARIANT_FX
|
|
||||||
# define CARDINAL_TEMPLATE_NAME "init/fx.vcv"
|
|
||||||
#elif CARDINAL_VARIANT_NATIVE
|
|
||||||
# define CARDINAL_TEMPLATE_NAME "init/native.vcv"
|
|
||||||
#elif CARDINAL_VARIANT_SYNTH
|
|
||||||
# define CARDINAL_TEMPLATE_NAME "init/synth.vcv"
|
|
||||||
#else
|
|
||||||
# define CARDINAL_TEMPLATE_NAME "init/main.vcv"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const constexpr uint kCardinalStateBaseCount = 3; // patch, screenshot, comment
|
static const constexpr uint kCardinalStateBaseCount = 3; // patch, screenshot, comment
|
||||||
|
|
||||||
#ifndef HEADLESS
|
#ifndef HEADLESS
|
||||||
|
@ -76,17 +64,9 @@ static const constexpr uint kCardinalStateCount = kCardinalStateBaseCount;
|
||||||
extern const std::string CARDINAL_VERSION;
|
extern const std::string CARDINAL_VERSION;
|
||||||
|
|
||||||
namespace rack {
|
namespace rack {
|
||||||
namespace asset {
|
|
||||||
std::string patchesPath();
|
|
||||||
void destroy();
|
|
||||||
}
|
|
||||||
namespace engine {
|
namespace engine {
|
||||||
void Engine_setAboutToClose(Engine*);
|
void Engine_setAboutToClose(Engine*);
|
||||||
}
|
}
|
||||||
namespace plugin {
|
|
||||||
void initStaticPlugins();
|
|
||||||
void destroyStaticPlugins();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
START_NAMESPACE_DISTRHO
|
START_NAMESPACE_DISTRHO
|
||||||
|
@ -98,6 +78,10 @@ bool d_isDiffHigherThanLimit(const T& v1, const T& v2, const T& limit)
|
||||||
return v1 != v2 ? (v1 > v2 ? v1 - v2 : v2 - v1) > limit : false;
|
return v1 != v2 ? (v1 > v2 ? v1 - v2 : v2 - v1) > limit : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||||
|
const char* UI::getBundlePath() const noexcept { return nullptr; }
|
||||||
|
#endif
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifdef DISTRHO_OS_WASM
|
#ifdef DISTRHO_OS_WASM
|
||||||
|
@ -143,288 +127,6 @@ static char* getPatchStorageSlug() {
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
struct Initializer
|
|
||||||
#if defined(HAVE_LIBLO) && defined(HEADLESS)
|
|
||||||
: public Thread
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if defined(HAVE_LIBLO) && defined(HEADLESS)
|
|
||||||
lo_server oscServer = nullptr;
|
|
||||||
CardinalBasePlugin* oscPlugin = nullptr;
|
|
||||||
#endif
|
|
||||||
std::string templatePath;
|
|
||||||
std::string factoryTemplatePath;
|
|
||||||
|
|
||||||
Initializer(const CardinalBasePlugin* const plugin)
|
|
||||||
{
|
|
||||||
using namespace rack;
|
|
||||||
|
|
||||||
#ifdef DISTRHO_OS_WASM
|
|
||||||
settings::allowCursorLock = true;
|
|
||||||
#else
|
|
||||||
settings::allowCursorLock = false;
|
|
||||||
#endif
|
|
||||||
settings::autoCheckUpdates = false;
|
|
||||||
settings::autosaveInterval = 0;
|
|
||||||
settings::devMode = true;
|
|
||||||
settings::isPlugin = true;
|
|
||||||
settings::skipLoadOnLaunch = true;
|
|
||||||
settings::showTipsOnLaunch = false;
|
|
||||||
settings::windowPos = math::Vec(0, 0);
|
|
||||||
#ifdef HEADLESS
|
|
||||||
settings::headless = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// copied from https://community.vcvrack.com/t/16-colour-cable-palette/15951
|
|
||||||
settings::cableColors = {
|
|
||||||
color::fromHexString("#ff5252"),
|
|
||||||
color::fromHexString("#ff9352"),
|
|
||||||
color::fromHexString("#ffd452"),
|
|
||||||
color::fromHexString("#e8ff52"),
|
|
||||||
color::fromHexString("#a8ff52"),
|
|
||||||
color::fromHexString("#67ff52"),
|
|
||||||
color::fromHexString("#52ff7d"),
|
|
||||||
color::fromHexString("#52ffbe"),
|
|
||||||
color::fromHexString("#52ffff"),
|
|
||||||
color::fromHexString("#52beff"),
|
|
||||||
color::fromHexString("#527dff"),
|
|
||||||
color::fromHexString("#6752ff"),
|
|
||||||
color::fromHexString("#a852ff"),
|
|
||||||
color::fromHexString("#e952ff"),
|
|
||||||
color::fromHexString("#ff52d4"),
|
|
||||||
color::fromHexString("#ff5293"),
|
|
||||||
};
|
|
||||||
|
|
||||||
system::init();
|
|
||||||
logger::init();
|
|
||||||
random::init();
|
|
||||||
ui::init();
|
|
||||||
|
|
||||||
if (asset::systemDir.empty())
|
|
||||||
{
|
|
||||||
if (const char* const bundlePath = plugin->getBundlePath())
|
|
||||||
{
|
|
||||||
if (const char* const resourcePath = getResourcePath(bundlePath))
|
|
||||||
{
|
|
||||||
asset::systemDir = resourcePath;
|
|
||||||
asset::bundlePath = system::join(asset::systemDir, "PluginManifests");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (asset::systemDir.empty() || ! system::exists(asset::systemDir) || ! system::exists(asset::bundlePath))
|
|
||||||
{
|
|
||||||
#ifdef CARDINAL_PLUGIN_SOURCE_DIR
|
|
||||||
// Make system dir point to source code location as fallback
|
|
||||||
asset::systemDir = CARDINAL_PLUGIN_SOURCE_DIR DISTRHO_OS_SEP_STR "Rack";
|
|
||||||
asset::bundlePath.clear();
|
|
||||||
|
|
||||||
// If source code dir does not exist use install target prefix as system dir
|
|
||||||
if (!system::exists(system::join(asset::systemDir, "res")))
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if defined(DISTRHO_OS_WASM)
|
|
||||||
asset::systemDir = "/resources";
|
|
||||||
#elif defined(ARCH_MAC)
|
|
||||||
asset::systemDir = "/Library/Application Support/Cardinal";
|
|
||||||
#elif defined(ARCH_WIN)
|
|
||||||
const std::string commonprogfiles = getSpecialPath(kSpecialPathCommonProgramFiles);
|
|
||||||
if (! commonprogfiles.empty())
|
|
||||||
asset::systemDir = system::join(commonprogfiles, "Cardinal");
|
|
||||||
#else
|
|
||||||
asset::systemDir = CARDINAL_PLUGIN_PREFIX "/share/cardinal";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
asset::bundlePath = system::join(asset::systemDir, "PluginManifests");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
asset::userDir = asset::systemDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string patchesPath = asset::patchesPath();
|
|
||||||
#ifdef DISTRHO_OS_WASM
|
|
||||||
templatePath = system::join(patchesPath, CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME);
|
|
||||||
#else
|
|
||||||
templatePath = system::join(patchesPath, CARDINAL_TEMPLATE_NAME);
|
|
||||||
#endif
|
|
||||||
factoryTemplatePath = system::join(patchesPath, CARDINAL_TEMPLATE_NAME);
|
|
||||||
|
|
||||||
// Log environment
|
|
||||||
INFO("%s %s %s, compatible with Rack version %s", APP_NAME.c_str(), APP_EDITION.c_str(), CARDINAL_VERSION.c_str(), APP_VERSION.c_str());
|
|
||||||
INFO("%s", system::getOperatingSystemInfo().c_str());
|
|
||||||
INFO("Binary filename: %s", getBinaryFilename());
|
|
||||||
INFO("Bundle path: %s", plugin->getBundlePath());
|
|
||||||
INFO("System directory: %s", asset::systemDir.c_str());
|
|
||||||
INFO("User directory: %s", asset::userDir.c_str());
|
|
||||||
INFO("Template patch: %s", templatePath.c_str());
|
|
||||||
INFO("System template patch: %s", factoryTemplatePath.c_str());
|
|
||||||
|
|
||||||
// Report to user if something is wrong with the installation
|
|
||||||
if (asset::systemDir.empty())
|
|
||||||
{
|
|
||||||
d_stderr2("Failed to locate Cardinal plugin bundle.\n"
|
|
||||||
"Install Cardinal with its bundle folder intact and try again.");
|
|
||||||
}
|
|
||||||
else if (! system::exists(asset::systemDir))
|
|
||||||
{
|
|
||||||
d_stderr2("System directory \"%s\" does not exist.\n"
|
|
||||||
"Make sure Cardinal was downloaded and installed correctly.", asset::systemDir.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
INFO("Initializing plugins");
|
|
||||||
plugin::initStaticPlugins();
|
|
||||||
|
|
||||||
INFO("Initializing plugin browser DB");
|
|
||||||
app::browserInit();
|
|
||||||
|
|
||||||
#if defined(HAVE_LIBLO) && defined(HEADLESS)
|
|
||||||
INFO("Initializing OSC Remote control");
|
|
||||||
oscServer = lo_server_new_with_proto(REMOTE_HOST_PORT, LO_UDP, osc_error_handler);
|
|
||||||
DISTRHO_SAFE_ASSERT_RETURN(oscServer != nullptr,);
|
|
||||||
|
|
||||||
lo_server_add_method(oscServer, "/hello", "", osc_hello_handler, this);
|
|
||||||
lo_server_add_method(oscServer, "/load", "b", osc_load_handler, this);
|
|
||||||
lo_server_add_method(oscServer, "/screenshot", "b", osc_screenshot_handler, this);
|
|
||||||
lo_server_add_method(oscServer, nullptr, nullptr, osc_fallback_handler, nullptr);
|
|
||||||
|
|
||||||
startThread();
|
|
||||||
#elif defined(HEADLESS)
|
|
||||||
INFO("OSC Remote control is not enabled in this build");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
~Initializer()
|
|
||||||
{
|
|
||||||
using namespace rack;
|
|
||||||
|
|
||||||
#if defined(HAVE_LIBLO) && defined(HEADLESS)
|
|
||||||
if (oscServer != nullptr)
|
|
||||||
{
|
|
||||||
stopThread(5000);
|
|
||||||
lo_server_del_method(oscServer, nullptr, nullptr);
|
|
||||||
lo_server_free(oscServer);
|
|
||||||
oscServer = nullptr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
INFO("Clearing asset paths");
|
|
||||||
asset::bundlePath.clear();
|
|
||||||
asset::systemDir.clear();
|
|
||||||
asset::userDir.clear();
|
|
||||||
|
|
||||||
INFO("Destroying plugins");
|
|
||||||
plugin::destroyStaticPlugins();
|
|
||||||
|
|
||||||
INFO("Destroying colourized assets");
|
|
||||||
asset::destroy();
|
|
||||||
|
|
||||||
INFO("Destroying settings");
|
|
||||||
settings::destroy();
|
|
||||||
|
|
||||||
INFO("Destroying logger");
|
|
||||||
logger::destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(HAVE_LIBLO) && defined(HEADLESS)
|
|
||||||
void run() override
|
|
||||||
{
|
|
||||||
INFO("OSC Thread Listening for remote commands");
|
|
||||||
|
|
||||||
while (! shouldThreadExit())
|
|
||||||
{
|
|
||||||
d_msleep(200);
|
|
||||||
while (lo_server_recv_noblock(oscServer, 0) != 0) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
INFO("OSC Thread Closed");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void osc_error_handler(int num, const char* msg, const char* path)
|
|
||||||
{
|
|
||||||
d_stderr("Cardinal OSC Error: code: %i, msg: \"%s\", path: \"%s\")", num, msg, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int osc_fallback_handler(const char* const path, const char* const types, lo_arg**, int, lo_message, void*)
|
|
||||||
{
|
|
||||||
d_stderr("Cardinal OSC unhandled message \"%s\" with types \"%s\"", path, types);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int osc_hello_handler(const char*, const char*, lo_arg**, int, const lo_message m, void* const self)
|
|
||||||
{
|
|
||||||
d_stdout("osc_hello_handler()");
|
|
||||||
const lo_address source = lo_message_get_source(m);
|
|
||||||
lo_send_from(source, static_cast<Initializer*>(self)->oscServer, LO_TT_IMMEDIATE, "/resp", "ss", "hello", "ok");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int osc_load_handler(const char*, const char* types, lo_arg** argv, int argc, const lo_message m, void* const self)
|
|
||||||
{
|
|
||||||
d_stdout("osc_load_handler()");
|
|
||||||
DISTRHO_SAFE_ASSERT_RETURN(argc == 1, 0);
|
|
||||||
DISTRHO_SAFE_ASSERT_RETURN(types != nullptr && types[0] == 'b', 0);
|
|
||||||
|
|
||||||
const int32_t size = argv[0]->blob.size;
|
|
||||||
DISTRHO_SAFE_ASSERT_RETURN(size > 4, 0);
|
|
||||||
|
|
||||||
const uint8_t* const blob = (uint8_t*)(&argv[0]->blob.data);
|
|
||||||
DISTRHO_SAFE_ASSERT_RETURN(blob != nullptr, 0);
|
|
||||||
|
|
||||||
bool ok = false;
|
|
||||||
|
|
||||||
if (CardinalBasePlugin* const plugin = static_cast<Initializer*>(self)->oscPlugin)
|
|
||||||
{
|
|
||||||
CardinalPluginContext* const context = plugin->context;
|
|
||||||
std::vector<uint8_t> data(size);
|
|
||||||
std::memcpy(data.data(), blob, size);
|
|
||||||
|
|
||||||
rack::contextSet(context);
|
|
||||||
rack::system::removeRecursively(context->patch->autosavePath);
|
|
||||||
rack::system::createDirectories(context->patch->autosavePath);
|
|
||||||
try {
|
|
||||||
rack::system::unarchiveToDirectory(data, context->patch->autosavePath);
|
|
||||||
context->patch->loadAutosave();
|
|
||||||
ok = true;
|
|
||||||
}
|
|
||||||
catch (rack::Exception& e) {
|
|
||||||
WARN("%s", e.what());
|
|
||||||
}
|
|
||||||
rack::contextSet(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
const lo_address source = lo_message_get_source(m);
|
|
||||||
lo_send_from(source, static_cast<Initializer*>(self)->oscServer,
|
|
||||||
LO_TT_IMMEDIATE, "/resp", "ss", "load", ok ? "ok" : "fail");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int osc_screenshot_handler(const char*, const char* types, lo_arg** argv, int argc, const lo_message m, void* const self)
|
|
||||||
{
|
|
||||||
d_stdout("osc_screenshot_handler()");
|
|
||||||
DISTRHO_SAFE_ASSERT_RETURN(argc == 1, 0);
|
|
||||||
DISTRHO_SAFE_ASSERT_RETURN(types != nullptr && types[0] == 'b', 0);
|
|
||||||
|
|
||||||
const int32_t size = argv[0]->blob.size;
|
|
||||||
DISTRHO_SAFE_ASSERT_RETURN(size > 4, 0);
|
|
||||||
|
|
||||||
const uint8_t* const blob = (uint8_t*)(&argv[0]->blob.data);
|
|
||||||
DISTRHO_SAFE_ASSERT_RETURN(blob != nullptr, 0);
|
|
||||||
|
|
||||||
bool ok = false;
|
|
||||||
|
|
||||||
if (CardinalBasePlugin* const plugin = static_cast<Initializer*>(self)->oscPlugin)
|
|
||||||
ok = plugin->updateStateValue("screenshot", String::asBase64(blob, size).buffer());
|
|
||||||
|
|
||||||
const lo_address source = lo_message_get_source(m);
|
|
||||||
lo_send_from(source, static_cast<Initializer*>(self)->oscServer,
|
|
||||||
LO_TT_IMMEDIATE, "/resp", "ss", "screenshot", ok ? "ok" : "fail");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
struct ScopedContext {
|
struct ScopedContext {
|
||||||
ScopedContext(const CardinalBasePlugin* const plugin)
|
ScopedContext(const CardinalBasePlugin* const plugin)
|
||||||
{
|
{
|
||||||
|
@ -479,9 +181,9 @@ public:
|
||||||
CardinalPlugin()
|
CardinalPlugin()
|
||||||
: CardinalBasePlugin(kModuleParameters + kWindowParameterCount + 1, 0, kCardinalStateCount),
|
: CardinalBasePlugin(kModuleParameters + kWindowParameterCount + 1, 0, kCardinalStateCount),
|
||||||
#ifdef DISTRHO_OS_WASM
|
#ifdef DISTRHO_OS_WASM
|
||||||
fInitializer(new Initializer(this)),
|
fInitializer(new Initializer(this, static_cast<const CardinalBaseUI*>(nullptr))),
|
||||||
#else
|
#else
|
||||||
fInitializer(this),
|
fInitializer(this, static_cast<const CardinalBaseUI*>(nullptr)),
|
||||||
#endif
|
#endif
|
||||||
#if DISTRHO_PLUGIN_NUM_INPUTS != 0
|
#if DISTRHO_PLUGIN_NUM_INPUTS != 0
|
||||||
fAudioBufferCopy(nullptr),
|
fAudioBufferCopy(nullptr),
|
||||||
|
@ -571,14 +273,14 @@ public:
|
||||||
context->patch->templatePath = context->patch->factoryTemplatePath;
|
context->patch->templatePath = context->patch->factoryTemplatePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_LIBLO) && defined(HEADLESS)
|
#ifdef CARDINAL_INIT_OSC_THREAD
|
||||||
fInitializer->oscPlugin = this;
|
fInitializer->oscPlugin = this;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
~CardinalPlugin() override
|
~CardinalPlugin() override
|
||||||
{
|
{
|
||||||
#if defined(HAVE_LIBLO) && defined(HEADLESS)
|
#ifdef CARDINAL_INIT_OSC_THREAD
|
||||||
fInitializer->oscPlugin = nullptr;
|
fInitializer->oscPlugin = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
# include <ui/Label.hpp>
|
# include <ui/Label.hpp>
|
||||||
# include <ui/MenuOverlay.hpp>
|
# include <ui/MenuOverlay.hpp>
|
||||||
# include <ui/SequentialLayout.hpp>
|
# include <ui/SequentialLayout.hpp>
|
||||||
# include "CardinalCommon.hpp"
|
|
||||||
# include <emscripten/emscripten.h>
|
# include <emscripten/emscripten.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -47,15 +46,27 @@
|
||||||
# undef DEBUG
|
# undef DEBUG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <Application.hpp>
|
#include "Application.hpp"
|
||||||
#include "AsyncDialog.hpp"
|
#include "AsyncDialog.hpp"
|
||||||
|
#include "CardinalCommon.hpp"
|
||||||
#include "PluginContext.hpp"
|
#include "PluginContext.hpp"
|
||||||
#include "WindowParameters.hpp"
|
#include "WindowParameters.hpp"
|
||||||
|
|
||||||
|
#ifndef DISTRHO_OS_WASM
|
||||||
|
# include "extra/SharedResourcePointer.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HEADLESS
|
||||||
|
# include "extra/ScopedValueSetter.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace rack {
|
namespace rack {
|
||||||
namespace app {
|
namespace app {
|
||||||
widget::Widget* createMenuBar(bool isStandalone);
|
widget::Widget* createMenuBar(bool isStandalone);
|
||||||
}
|
}
|
||||||
|
namespace engine {
|
||||||
|
void Engine_setAboutToClose(Engine*);
|
||||||
|
}
|
||||||
namespace window {
|
namespace window {
|
||||||
void WindowSetPluginUI(Window* window, DISTRHO_NAMESPACE::UI* ui);
|
void WindowSetPluginUI(Window* window, DISTRHO_NAMESPACE::UI* ui);
|
||||||
void WindowSetMods(Window* window, int mods);
|
void WindowSetMods(Window* window, int mods);
|
||||||
|
@ -65,7 +76,14 @@ namespace window {
|
||||||
|
|
||||||
START_NAMESPACE_DISTRHO
|
START_NAMESPACE_DISTRHO
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||||
|
const char* Plugin::getBundlePath() const noexcept { return nullptr; }
|
||||||
|
bool Plugin::writeMidiEvent(const MidiEvent&) noexcept { return false; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifdef DISTRHO_OS_WASM
|
#ifdef DISTRHO_OS_WASM
|
||||||
struct WasmWelcomeDialog : rack::widget::OpaqueWidget
|
struct WasmWelcomeDialog : rack::widget::OpaqueWidget
|
||||||
|
@ -268,6 +286,15 @@ static void downloadRemotePatchSucceeded(const char* const filename)
|
||||||
class CardinalUI : public CardinalBaseUI,
|
class CardinalUI : public CardinalBaseUI,
|
||||||
public WindowParametersCallback
|
public WindowParametersCallback
|
||||||
{
|
{
|
||||||
|
#if ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||||
|
#ifdef DISTRHO_OS_WASM
|
||||||
|
ScopedPointer<Initializer> fInitializer;
|
||||||
|
#else
|
||||||
|
SharedResourcePointer<Initializer> fInitializer;
|
||||||
|
#endif
|
||||||
|
std::string fAutosavePath;
|
||||||
|
#endif
|
||||||
|
|
||||||
rack::math::Vec lastMousePos;
|
rack::math::Vec lastMousePos;
|
||||||
WindowParameters windowParameters;
|
WindowParameters windowParameters;
|
||||||
int rateLimitStep = 0;
|
int rateLimitStep = 0;
|
||||||
|
@ -305,8 +332,65 @@ class CardinalUI : public CardinalBaseUI,
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CardinalUI()
|
CardinalUI()
|
||||||
: CardinalBaseUI(DISTRHO_UI_DEFAULT_WIDTH, DISTRHO_UI_DEFAULT_HEIGHT)
|
: CardinalBaseUI(DISTRHO_UI_DEFAULT_WIDTH, DISTRHO_UI_DEFAULT_HEIGHT),
|
||||||
|
#if ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||||
|
#ifdef DISTRHO_OS_WASM
|
||||||
|
fInitializer(new Initializer(static_cast<const CardinalBasePlugin*>(nullptr), this)),
|
||||||
|
#else
|
||||||
|
fInitializer(static_cast<const CardinalBasePlugin*>(nullptr), this),
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
lastMousePos()
|
||||||
{
|
{
|
||||||
|
rack::contextSet(context);
|
||||||
|
|
||||||
|
#if ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||||
|
// create unique temporary path for this instance
|
||||||
|
try {
|
||||||
|
char uidBuf[24];
|
||||||
|
const std::string tmp = rack::system::getTempDirectory();
|
||||||
|
|
||||||
|
for (int i=1;; ++i)
|
||||||
|
{
|
||||||
|
std::snprintf(uidBuf, sizeof(uidBuf), "Cardinal.%04d", i);
|
||||||
|
const std::string trypath = rack::system::join(tmp, uidBuf);
|
||||||
|
|
||||||
|
if (! rack::system::exists(trypath))
|
||||||
|
{
|
||||||
|
if (rack::system::createDirectories(trypath))
|
||||||
|
fAutosavePath = trypath;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} DISTRHO_SAFE_EXCEPTION("create unique temporary path");
|
||||||
|
|
||||||
|
const float sampleRate = getSampleRate();
|
||||||
|
rack::settings::sampleRate = sampleRate;
|
||||||
|
|
||||||
|
context->bufferSize = 128;
|
||||||
|
context->sampleRate = sampleRate;
|
||||||
|
|
||||||
|
context->engine = new rack::engine::Engine;
|
||||||
|
context->engine->setSampleRate(sampleRate);
|
||||||
|
|
||||||
|
context->history = new rack::history::State;
|
||||||
|
context->patch = new rack::patch::Manager;
|
||||||
|
context->patch->autosavePath = fAutosavePath;
|
||||||
|
context->patch->templatePath = fInitializer->templatePath;
|
||||||
|
context->patch->factoryTemplatePath = fInitializer->factoryTemplatePath;
|
||||||
|
|
||||||
|
context->event = new rack::widget::EventState;
|
||||||
|
context->scene = new rack::app::Scene;
|
||||||
|
context->event->rootWidget = context->scene;
|
||||||
|
|
||||||
|
context->window = new rack::window::Window;
|
||||||
|
|
||||||
|
context->patch->loadTemplate();
|
||||||
|
context->scene->rackScroll->reset();
|
||||||
|
// swap to factory template after first load
|
||||||
|
context->patch->templatePath = context->patch->factoryTemplatePath;
|
||||||
|
#endif
|
||||||
|
|
||||||
Window& window(getWindow());
|
Window& window(getWindow());
|
||||||
|
|
||||||
window.setIgnoringKeyRepeat(true);
|
window.setIgnoringKeyRepeat(true);
|
||||||
|
@ -319,8 +403,6 @@ public:
|
||||||
if (scaleFactor != 1.0)
|
if (scaleFactor != 1.0)
|
||||||
setSize(DISTRHO_UI_DEFAULT_WIDTH * scaleFactor, DISTRHO_UI_DEFAULT_HEIGHT * scaleFactor);
|
setSize(DISTRHO_UI_DEFAULT_WIDTH * scaleFactor, DISTRHO_UI_DEFAULT_HEIGHT * scaleFactor);
|
||||||
|
|
||||||
rack::contextSet(context);
|
|
||||||
|
|
||||||
rack::window::WindowSetPluginUI(context->window, this);
|
rack::window::WindowSetPluginUI(context->window, this);
|
||||||
|
|
||||||
if (rack::widget::Widget* const menuBar = context->scene->menuBar)
|
if (rack::widget::Widget* const menuBar = context->scene->menuBar)
|
||||||
|
@ -408,6 +490,23 @@ public:
|
||||||
|
|
||||||
rack::window::WindowSetPluginUI(context->window, nullptr);
|
rack::window::WindowSetPluginUI(context->window, nullptr);
|
||||||
|
|
||||||
|
#if ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||||
|
{
|
||||||
|
const ScopedContext sc(this);
|
||||||
|
context->patch->clear();
|
||||||
|
|
||||||
|
// do a little dance to prevent context scene deletion from saving to temp dir
|
||||||
|
#ifndef HEADLESS
|
||||||
|
const ScopedValueSetter<bool> svs(rack::settings::headless, true);
|
||||||
|
#endif
|
||||||
|
Engine_setAboutToClose(context->engine);
|
||||||
|
delete context;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! fAutosavePath.empty())
|
||||||
|
rack::system::removeRecursively(fAutosavePath);
|
||||||
|
#endif
|
||||||
|
|
||||||
rack::contextSet(nullptr);
|
rack::contextSet(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -201,8 +201,10 @@ endif
|
||||||
# --------------------------------------------------------------
|
# --------------------------------------------------------------
|
||||||
# Setup resources
|
# Setup resources
|
||||||
|
|
||||||
CORE_RESOURCES = patches
|
CORE_RESOURCES = $(subst ../Rack/res/,,$(wildcard ../Rack/res/ComponentLibrary/*.svg ../Rack/res/fonts/*.ttf))
|
||||||
CORE_RESOURCES += $(subst ../Rack/res/,,$(wildcard ../Rack/res/ComponentLibrary/*.svg ../Rack/res/fonts/*.ttf))
|
# ifneq ($(CARDINAL_VARIANT),mini)
|
||||||
|
CORE_RESOURCES += patches
|
||||||
|
# endif
|
||||||
|
|
||||||
LV2_RESOURCES = $(CORE_RESOURCES:%=$(TARGET_DIR)/$(NAME).lv2/resources/%)
|
LV2_RESOURCES = $(CORE_RESOURCES:%=$(TARGET_DIR)/$(NAME).lv2/resources/%)
|
||||||
VST3_RESOURCES = $(CORE_RESOURCES:%=$(TARGET_DIR)/$(NAME).vst3/Contents/Resources/%)
|
VST3_RESOURCES = $(CORE_RESOURCES:%=$(TARGET_DIR)/$(NAME).vst3/Contents/Resources/%)
|
||||||
|
@ -243,15 +245,19 @@ endif
|
||||||
# --------------------------------------------------------------
|
# --------------------------------------------------------------
|
||||||
# mini variant UI
|
# mini variant UI
|
||||||
|
|
||||||
# ifeq ($(CARDINAL_VARIANT),mini)
|
ifeq ($(CARDINAL_VARIANT),mini)
|
||||||
# ifneq ($(HEADLESS)$(MOD_BUILD),true)
|
ifneq ($(HEADLESS)$(MOD_BUILD),true)
|
||||||
# FILES_UI = CardinalUI.cpp
|
FILES_UI = CardinalUI.cpp
|
||||||
# FILES_UI += glfw.cpp
|
FILES_UI += CardinalCommon.cpp
|
||||||
# FILES_UI += Window.cpp
|
FILES_UI += common.cpp
|
||||||
# EXTRA_UI_DEPENDENCIES = $(subst -headless,,$(EXTRA_DSP_DEPENDENCIES))
|
FILES_UI += glfw.cpp
|
||||||
# EXTRA_UI_LIBS = $(subst -headless,,$(EXTRA_DSP_LIBS))
|
FILES_UI += Window.cpp
|
||||||
# endif
|
EXTRA_UI_DEPENDENCIES = $(subst -headless,,$(EXTRA_DSP_DEPENDENCIES))
|
||||||
# endif
|
EXTRA_UI_LIBS = -Wl,--start-group
|
||||||
|
EXTRA_UI_LIBS += $(subst -headless,,$(EXTRA_DSP_LIBS))
|
||||||
|
EXTRA_UI_LIBS += -Wl,--end-group
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
# --------------------------------------------------------------
|
# --------------------------------------------------------------
|
||||||
# Do some magic
|
# Do some magic
|
||||||
|
@ -467,6 +473,7 @@ endif
|
||||||
|
|
||||||
all: $(TARGETS)
|
all: $(TARGETS)
|
||||||
lv2: $(LV2_RESOURCES)
|
lv2: $(LV2_RESOURCES)
|
||||||
|
lv2_sep: $(LV2_RESOURCES)
|
||||||
vst2: $(VST2_RESOURCES)
|
vst2: $(VST2_RESOURCES)
|
||||||
vst3: $(VST3_RESOURCES)
|
vst3: $(VST3_RESOURCES)
|
||||||
clap: $(CLAP_RESOURCES)
|
clap: $(CLAP_RESOURCES)
|
||||||
|
|
|
@ -189,9 +189,6 @@ public:
|
||||||
|
|
||||||
context->tlw = nullptr;
|
context->tlw = nullptr;
|
||||||
context->ui = nullptr;
|
context->ui = nullptr;
|
||||||
#if !DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
|
||||||
delete context;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -107,6 +107,13 @@ public:
|
||||||
initialise_variant<T>(variant);
|
initialise_variant<T>(variant);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T1, class T2>
|
||||||
|
SharedResourcePointer(const T1* const v1, const T2* const v2)
|
||||||
|
: sharedObject(nullptr)
|
||||||
|
{
|
||||||
|
initialise_variant2<T1, T2>(v1, v2);
|
||||||
|
}
|
||||||
|
|
||||||
SharedResourcePointer (const SharedResourcePointer&)
|
SharedResourcePointer (const SharedResourcePointer&)
|
||||||
: sharedObject(nullptr)
|
: sharedObject(nullptr)
|
||||||
{
|
{
|
||||||
|
@ -179,6 +186,18 @@ private:
|
||||||
sharedObject = holder.sharedInstance;
|
sharedObject = holder.sharedInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T1, class T2>
|
||||||
|
void initialise_variant2(const T1* const v1, const T2* const v2)
|
||||||
|
{
|
||||||
|
SharedObjectHolder& holder = getSharedObjectHolder();
|
||||||
|
const SpinLock::ScopedLockType sl (holder.lock);
|
||||||
|
|
||||||
|
if (++(holder.refCount) == 1)
|
||||||
|
holder.sharedInstance = new SharedObjectType(v1, v2);
|
||||||
|
|
||||||
|
sharedObject = holder.sharedInstance;
|
||||||
|
}
|
||||||
|
|
||||||
// There's no need to assign to a SharedResourcePointer because every
|
// There's no need to assign to a SharedResourcePointer because every
|
||||||
// instance of the class is exactly the same!
|
// instance of the class is exactly the same!
|
||||||
SharedResourcePointer& operator= (const SharedResourcePointer&) = delete;
|
SharedResourcePointer& operator= (const SharedResourcePointer&) = delete;
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
#include "Application.hpp"
|
#include "Application.hpp"
|
||||||
#include "extra/String.hpp"
|
#include "extra/String.hpp"
|
||||||
#include "../CardinalCommon.hpp"
|
#include "../CardinalCommon.hpp"
|
||||||
|
#include "../PluginContext.hpp"
|
||||||
#include "../WindowParameters.hpp"
|
#include "../WindowParameters.hpp"
|
||||||
|
|
||||||
#ifndef DGL_NO_SHARED_RESOURCES
|
#ifndef DGL_NO_SHARED_RESOURCES
|
||||||
|
@ -148,12 +149,14 @@ struct Window::Internal {
|
||||||
DGL_NAMESPACE::NanoTopLevelWidget* tlw = nullptr;
|
DGL_NAMESPACE::NanoTopLevelWidget* tlw = nullptr;
|
||||||
DISTRHO_NAMESPACE::WindowParameters params;
|
DISTRHO_NAMESPACE::WindowParameters params;
|
||||||
DISTRHO_NAMESPACE::WindowParametersCallback* callback = nullptr;
|
DISTRHO_NAMESPACE::WindowParametersCallback* callback = nullptr;
|
||||||
|
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||||
DGL_NAMESPACE::Application hiddenApp;
|
DGL_NAMESPACE::Application hiddenApp;
|
||||||
DGL_NAMESPACE::Window hiddenWindow;
|
DGL_NAMESPACE::Window hiddenWindow;
|
||||||
NVGcontext* r_vg = nullptr;
|
NVGcontext* r_vg = nullptr;
|
||||||
NVGcontext* r_fbVg = nullptr;
|
NVGcontext* r_fbVg = nullptr;
|
||||||
NVGcontext* o_vg = nullptr;
|
NVGcontext* o_vg = nullptr;
|
||||||
NVGcontext* o_fbVg = nullptr;
|
NVGcontext* o_fbVg = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
math::Vec size = WINDOW_SIZE_MIN;
|
math::Vec size = WINDOW_SIZE_MIN;
|
||||||
|
|
||||||
|
@ -176,12 +179,16 @@ struct Window::Internal {
|
||||||
int fbCount = 0;
|
int fbCount = 0;
|
||||||
|
|
||||||
Internal()
|
Internal()
|
||||||
|
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||||
: hiddenApp(false),
|
: hiddenApp(false),
|
||||||
hiddenWindow(hiddenApp)
|
hiddenWindow(hiddenApp)
|
||||||
{
|
{
|
||||||
hiddenWindow.setIgnoringKeyRepeat(true);
|
hiddenWindow.setIgnoringKeyRepeat(true);
|
||||||
hiddenApp.idle();
|
hiddenApp.idle();
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
{}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -203,12 +210,17 @@ static int loadFallbackFont(NVGcontext* const vg)
|
||||||
Window::Window() {
|
Window::Window() {
|
||||||
internal = new Internal;
|
internal = new Internal;
|
||||||
|
|
||||||
DGL_NAMESPACE::Window::ScopedGraphicsContext sgc(internal->hiddenWindow);
|
|
||||||
|
|
||||||
// Set up NanoVG
|
// Set up NanoVG
|
||||||
const int nvgFlags = NVG_ANTIALIAS;
|
const int nvgFlags = NVG_ANTIALIAS;
|
||||||
|
|
||||||
|
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||||
|
DGL_NAMESPACE::Window::ScopedGraphicsContext sgc(internal->hiddenWindow);
|
||||||
vg = nvgCreateGL(nvgFlags);
|
vg = nvgCreateGL(nvgFlags);
|
||||||
|
#else
|
||||||
|
vg = static_cast<CardinalPluginContext*>(APP)->tlw->getContext();
|
||||||
|
#endif
|
||||||
DISTRHO_SAFE_ASSERT_RETURN(vg != nullptr,);
|
DISTRHO_SAFE_ASSERT_RETURN(vg != nullptr,);
|
||||||
|
|
||||||
#ifdef NANOVG_GLES2
|
#ifdef NANOVG_GLES2
|
||||||
fbVg = nvgCreateSharedGLES2(vg, nvgFlags);
|
fbVg = nvgCreateSharedGLES2(vg, nvgFlags);
|
||||||
#else
|
#else
|
||||||
|
@ -268,6 +280,7 @@ void WindowSetPluginRemote(Window* const window, NanoTopLevelWidget* const tlw)
|
||||||
window->internal->tlw = tlw;
|
window->internal->tlw = tlw;
|
||||||
window->internal->size = rack::math::Vec(tlw->getWidth(), tlw->getHeight());
|
window->internal->size = rack::math::Vec(tlw->getWidth(), tlw->getHeight());
|
||||||
|
|
||||||
|
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||||
// Set up NanoVG
|
// Set up NanoVG
|
||||||
window->internal->r_vg = tlw->getContext();
|
window->internal->r_vg = tlw->getContext();
|
||||||
#ifdef NANOVG_GLES2
|
#ifdef NANOVG_GLES2
|
||||||
|
@ -299,6 +312,7 @@ void WindowSetPluginRemote(Window* const window, NanoTopLevelWidget* const tlw)
|
||||||
image.second->handle = nvgCreateImage(window->vg, image.second->ofilename.c_str(),
|
image.second->handle = nvgCreateImage(window->vg, image.second->ofilename.c_str(),
|
||||||
NVG_IMAGE_REPEATX | NVG_IMAGE_REPEATY);
|
NVG_IMAGE_REPEATX | NVG_IMAGE_REPEATY);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Init settings
|
// Init settings
|
||||||
WindowParametersRestore(window);
|
WindowParametersRestore(window);
|
||||||
|
@ -311,6 +325,7 @@ void WindowSetPluginRemote(Window* const window, NanoTopLevelWidget* const tlw)
|
||||||
widget::Widget::ContextDestroyEvent e;
|
widget::Widget::ContextDestroyEvent e;
|
||||||
APP->scene->onContextDestroy(e);
|
APP->scene->onContextDestroy(e);
|
||||||
|
|
||||||
|
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||||
// swap contexts
|
// swap contexts
|
||||||
window->uiFont->vg = window->internal->o_vg;
|
window->uiFont->vg = window->internal->o_vg;
|
||||||
window->vg = window->internal->o_vg;
|
window->vg = window->internal->o_vg;
|
||||||
|
@ -338,6 +353,7 @@ void WindowSetPluginRemote(Window* const window, NanoTopLevelWidget* const tlw)
|
||||||
nvgDeleteGLES2(window->internal->r_fbVg);
|
nvgDeleteGLES2(window->internal->r_fbVg);
|
||||||
#else
|
#else
|
||||||
nvgDeleteGL2(window->internal->r_fbVg);
|
nvgDeleteGL2(window->internal->r_fbVg);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
window->internal->tlw = nullptr;
|
window->internal->tlw = nullptr;
|
||||||
|
@ -375,6 +391,7 @@ void WindowSetPluginUI(Window* const window, DISTRHO_NAMESPACE::UI* const ui)
|
||||||
window->internal->ui = ui;
|
window->internal->ui = ui;
|
||||||
window->internal->size = rack::math::Vec(ui->getWidth(), ui->getHeight());
|
window->internal->size = rack::math::Vec(ui->getWidth(), ui->getHeight());
|
||||||
|
|
||||||
|
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||||
// Set up NanoVG
|
// Set up NanoVG
|
||||||
window->internal->r_vg = ui->getContext();
|
window->internal->r_vg = ui->getContext();
|
||||||
#ifdef NANOVG_GLES2
|
#ifdef NANOVG_GLES2
|
||||||
|
@ -406,6 +423,7 @@ void WindowSetPluginUI(Window* const window, DISTRHO_NAMESPACE::UI* const ui)
|
||||||
image.second->handle = nvgCreateImage(window->vg, image.second->ofilename.c_str(),
|
image.second->handle = nvgCreateImage(window->vg, image.second->ofilename.c_str(),
|
||||||
NVG_IMAGE_REPEATX | NVG_IMAGE_REPEATY);
|
NVG_IMAGE_REPEATX | NVG_IMAGE_REPEATY);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Init settings
|
// Init settings
|
||||||
WindowParametersRestore(window);
|
WindowParametersRestore(window);
|
||||||
|
@ -418,6 +436,7 @@ void WindowSetPluginUI(Window* const window, DISTRHO_NAMESPACE::UI* const ui)
|
||||||
widget::Widget::ContextDestroyEvent e;
|
widget::Widget::ContextDestroyEvent e;
|
||||||
APP->scene->onContextDestroy(e);
|
APP->scene->onContextDestroy(e);
|
||||||
|
|
||||||
|
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||||
// swap contexts
|
// swap contexts
|
||||||
window->uiFont->vg = window->internal->o_vg;
|
window->uiFont->vg = window->internal->o_vg;
|
||||||
window->vg = window->internal->o_vg;
|
window->vg = window->internal->o_vg;
|
||||||
|
@ -445,6 +464,7 @@ void WindowSetPluginUI(Window* const window, DISTRHO_NAMESPACE::UI* const ui)
|
||||||
nvgDeleteGLES2(window->internal->r_fbVg);
|
nvgDeleteGLES2(window->internal->r_fbVg);
|
||||||
#else
|
#else
|
||||||
nvgDeleteGL2(window->internal->r_fbVg);
|
nvgDeleteGL2(window->internal->r_fbVg);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
window->internal->tlw = nullptr;
|
window->internal->tlw = nullptr;
|
||||||
|
@ -460,9 +480,11 @@ void WindowSetMods(Window* const window, const int mods)
|
||||||
|
|
||||||
Window::~Window() {
|
Window::~Window() {
|
||||||
{
|
{
|
||||||
|
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||||
DGL_NAMESPACE::Window::ScopedGraphicsContext sgc(internal->hiddenWindow);
|
DGL_NAMESPACE::Window::ScopedGraphicsContext sgc(internal->hiddenWindow);
|
||||||
internal->hiddenWindow.close();
|
internal->hiddenWindow.close();
|
||||||
internal->hiddenApp.idle();
|
internal->hiddenApp.idle();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Fonts and Images in the cache must be deleted before the NanoVG context is deleted
|
// Fonts and Images in the cache must be deleted before the NanoVG context is deleted
|
||||||
internal->fontCache.clear();
|
internal->fontCache.clear();
|
||||||
|
@ -470,12 +492,20 @@ Window::~Window() {
|
||||||
|
|
||||||
if (vg != nullptr)
|
if (vg != nullptr)
|
||||||
{
|
{
|
||||||
|
#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
|
||||||
#if defined NANOVG_GLES2
|
#if defined NANOVG_GLES2
|
||||||
nvgDeleteGLES2(internal->o_fbVg != nullptr ? internal->o_fbVg : fbVg);
|
nvgDeleteGLES2(internal->o_fbVg != nullptr ? internal->o_fbVg : fbVg);
|
||||||
nvgDeleteGLES2(internal->o_vg != nullptr ? internal->o_vg : vg);
|
nvgDeleteGLES2(internal->o_vg != nullptr ? internal->o_vg : vg);
|
||||||
#else
|
#else
|
||||||
nvgDeleteGL2(internal->o_fbVg != nullptr ? internal->o_fbVg : fbVg);
|
nvgDeleteGL2(internal->o_fbVg != nullptr ? internal->o_fbVg : fbVg);
|
||||||
nvgDeleteGL2(internal->o_vg != nullptr ? internal->o_vg : vg);
|
nvgDeleteGL2(internal->o_vg != nullptr ? internal->o_vg : vg);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if defined NANOVG_GLES2
|
||||||
|
nvgDeleteGLES2(fbVg);
|
||||||
|
#else
|
||||||
|
nvgDeleteGL2(fbVg);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue