From 058ad891d2e3795b61d18a82323ae19ff6b5567d Mon Sep 17 00:00:00 2001 From: falkTX Date: Sat, 24 Dec 2022 21:59:04 +0000 Subject: [PATCH] Move some code around to help remote tool later Signed-off-by: falkTX --- plugins/Cardinal/src/plugincontext.hpp | 7 + src/CardinalCommon.cpp | 113 +++++++++ src/CardinalPlugin.cpp | 71 +----- src/CardinalRemote/Makefile | 147 ++++++++++-- src/CardinalRemote/RemoteUI.cpp | 313 +++++++++++++++++++++---- src/CardinalRemote/RemoteUI.hpp | 11 +- src/CardinalRemote/main.cpp | 80 ++++++- src/CardinalUI.cpp | 34 --- src/PluginContext.hpp | 8 +- src/custom/glfw.cpp | 16 +- src/override/Window.cpp | 131 ++++++++++- 11 files changed, 740 insertions(+), 191 deletions(-) diff --git a/plugins/Cardinal/src/plugincontext.hpp b/plugins/Cardinal/src/plugincontext.hpp index f48b2a8..e087784 100644 --- a/plugins/Cardinal/src/plugincontext.hpp +++ b/plugins/Cardinal/src/plugincontext.hpp @@ -29,6 +29,12 @@ // ----------------------------------------------------------------------------------------------------------- // from PluginContext.hpp +#ifndef HEADLESS +START_NAMESPACE_DGL +class NanoTopLevelWidget; +END_NAMESPACE_DGL +#endif + START_NAMESPACE_DISTRHO static constexpr const uint32_t kModuleParameters = 24; @@ -68,6 +74,7 @@ struct CardinalPluginContext : rack::Context { uint32_t midiEventCount; Plugin* const plugin; #ifndef HEADLESS + DGL_NAMESPACE::NanoTopLevelWidget* tlw; UI* ui; #endif CardinalPluginContext(Plugin* const p); diff --git a/src/CardinalCommon.cpp b/src/CardinalCommon.cpp index ff93cc7..4de8100 100644 --- a/src/CardinalCommon.cpp +++ b/src/CardinalCommon.cpp @@ -59,6 +59,115 @@ const std::string CARDINAL_VERSION = "22.12"; +START_NAMESPACE_DISTRHO + +// ----------------------------------------------------------------------------------------------------------- + +void handleHostParameterDrag(const CardinalPluginContext* pcontext, uint index, bool started) +{ + DISTRHO_SAFE_ASSERT_RETURN(pcontext->ui != nullptr,); + + if (started) + { + pcontext->ui->editParameter(index, true); + pcontext->ui->setParameterValue(index, pcontext->parameters[index]); + } + else + { + pcontext->ui->editParameter(index, false); + } +} + +// -------------------------------------------------------------------------------------------------------------------- + +bool CardinalPluginContext::addIdleCallback(IdleCallback* const cb) const +{ + if (ui == nullptr) + return false; + + ui->addIdleCallback(cb); + return true; +} + +void CardinalPluginContext::removeIdleCallback(IdleCallback* const cb) const +{ + if (ui == nullptr) + return; + + ui->removeIdleCallback(cb); +} + +void CardinalPluginContext::writeMidiMessage(const rack::midi::Message& message, const uint8_t channel) +{ + if (bypassed) + return; + + const size_t size = message.bytes.size(); + DISTRHO_SAFE_ASSERT_RETURN(size > 0,); + DISTRHO_SAFE_ASSERT_RETURN(message.frame >= 0,); + + MidiEvent event; + event.frame = message.frame; + + switch (message.bytes[0] & 0xF0) + { + case 0x80: + case 0x90: + case 0xA0: + case 0xB0: + case 0xE0: + event.size = 3; + break; + case 0xC0: + case 0xD0: + event.size = 2; + break; + case 0xF0: + switch (message.bytes[0] & 0x0F) + { + case 0x0: + case 0x4: + case 0x5: + case 0x7: + case 0x9: + case 0xD: + // unsupported + return; + case 0x1: + case 0x2: + case 0x3: + case 0xE: + event.size = 3; + break; + case 0x6: + case 0x8: + case 0xA: + case 0xB: + case 0xC: + case 0xF: + event.size = 1; + break; + } + break; + default: + // invalid + return; + } + + DISTRHO_SAFE_ASSERT_RETURN(size >= event.size,); + + std::memcpy(event.data, message.bytes.data(), event.size); + + if (channel != 0 && event.data[0] < 0xF0) + event.data[0] |= channel & 0x0F; + + plugin->writeMidiEvent(event); +} + +END_NAMESPACE_DISTRHO + +// -------------------------------------------------------------------------------------------------------------------- + namespace rack { bool isStandalone() @@ -118,6 +227,8 @@ std::string homeDir() } // namespace rack +// -------------------------------------------------------------------------------------------------------------------- + namespace patchUtils { @@ -289,6 +400,8 @@ void openBrowser(const std::string& url) } +// -------------------------------------------------------------------------------------------------------------------- + void async_dialog_filebrowser(const bool saving, const char* const defaultName, const char* const startDir, diff --git a/src/CardinalPlugin.cpp b/src/CardinalPlugin.cpp index 8d93932..de654ea 100644 --- a/src/CardinalPlugin.cpp +++ b/src/CardinalPlugin.cpp @@ -430,75 +430,6 @@ struct Initializer // ----------------------------------------------------------------------------------------------------------- -void CardinalPluginContext::writeMidiMessage(const rack::midi::Message& message, const uint8_t channel) -{ - if (bypassed) - return; - - const size_t size = message.bytes.size(); - DISTRHO_SAFE_ASSERT_RETURN(size > 0,); - DISTRHO_SAFE_ASSERT_RETURN(message.frame >= 0,); - - MidiEvent event; - event.frame = message.frame; - - switch (message.bytes[0] & 0xF0) - { - case 0x80: - case 0x90: - case 0xA0: - case 0xB0: - case 0xE0: - event.size = 3; - break; - case 0xC0: - case 0xD0: - event.size = 2; - break; - case 0xF0: - switch (message.bytes[0] & 0x0F) - { - case 0x0: - case 0x4: - case 0x5: - case 0x7: - case 0x9: - case 0xD: - // unsupported - return; - case 0x1: - case 0x2: - case 0x3: - case 0xE: - event.size = 3; - break; - case 0x6: - case 0x8: - case 0xA: - case 0xB: - case 0xC: - case 0xF: - event.size = 1; - break; - } - break; - default: - // invalid - return; - } - - DISTRHO_SAFE_ASSERT_RETURN(size >= event.size,); - - std::memcpy(event.data, message.bytes.data(), event.size); - - if (channel != 0 && event.data[0] < 0xF0) - event.data[0] |= channel & 0x0F; - - plugin->writeMidiEvent(event); -} - -// ----------------------------------------------------------------------------------------------------------- - struct ScopedContext { ScopedContext(const CardinalBasePlugin* const plugin) { @@ -1393,6 +1324,6 @@ Plugin* createPlugin() return new CardinalPlugin(); } -// ----------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- END_NAMESPACE_DISTRHO diff --git a/src/CardinalRemote/Makefile b/src/CardinalRemote/Makefile index 8c0666f..61dadd0 100644 --- a/src/CardinalRemote/Makefile +++ b/src/CardinalRemote/Makefile @@ -7,8 +7,11 @@ # -------------------------------------------------------------- # Carla stuff -CWD = ../../carla/source +ifneq ($(STATIC_BUILD),true) + STATIC_PLUGIN_TARGET = true + +CWD = ../../carla/source include $(CWD)/Makefile.deps.mk CARLA_BUILD_DIR = ../../carla/build @@ -23,7 +26,9 @@ CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/carla_engine_ CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/carla_plugin.a CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/native-plugins.a CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/audio_decoder.a +ifneq ($(WASM),true) CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/jackbridge.min.a +endif CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/lilv.a CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/rtmempool.a CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/sfzero.a @@ -31,10 +36,17 @@ CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/water.a CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/ysfx.a CARLA_EXTRA_LIBS += $(CARLA_BUILD_DIR)/modules/$(CARLA_BUILD_TYPE)/zita-resampler.a +endif # STATIC_BUILD + # -------------------------------------------------------------- # Import base definitions +DISTRHO_NAMESPACE = CardinalDISTRHO +DGL_NAMESPACE = CardinalDGL +NVG_DISABLE_SKIPPING_WHITESPACE = true +NVG_FONT_TEXTURE_FLAGS = NVG_IMAGE_NEAREST USE_NANOVG_FBO = true +WASM_EXCEPTIONS = true include ../../dpf/Makefile.base.mk # -------------------------------------------------------------- @@ -57,7 +69,11 @@ endif # -------------------------------------------------------------- # Extra libraries to link against +ifeq ($(NOPLUGINS),true) +RACK_EXTRA_LIBS = ../../plugins/noplugins.a +else RACK_EXTRA_LIBS = ../../plugins/plugins.a +endif RACK_EXTRA_LIBS += ../rack.a RACK_EXTRA_LIBS += $(DEP_LIB_PATH)/libquickjs.a @@ -74,22 +90,51 @@ RACK_EXTRA_LIBS += $(DEP_LIB_PATH)/libzstd.a endif # -------------------------------------------------------------- +# surgext libraries + +ifneq ($(NOPLUGINS),true) +SURGE_DEP_PATH = $(abspath ../../deps/surge-build) +RACK_EXTRA_LIBS += $(SURGE_DEP_PATH)/src/common/libsurge-common.a +RACK_EXTRA_LIBS += $(SURGE_DEP_PATH)/src/common/libjuce_dsp_rack_sub.a +RACK_EXTRA_LIBS += $(SURGE_DEP_PATH)/libs/airwindows/libairwindows.a +RACK_EXTRA_LIBS += $(SURGE_DEP_PATH)/libs/eurorack/libeurorack.a +ifeq ($(DEBUG),true) +RACK_EXTRA_LIBS += $(SURGE_DEP_PATH)/libs/fmt/libfmtd.a +else +RACK_EXTRA_LIBS += $(SURGE_DEP_PATH)/libs/fmt/libfmt.a +endif +RACK_EXTRA_LIBS += $(SURGE_DEP_PATH)/libs/sqlite-3.23.3/libsqlite.a +RACK_EXTRA_LIBS += $(SURGE_DEP_PATH)/libs/sst/sst-plugininfra/libsst-plugininfra.a +ifneq ($(WINDOWS),true) +RACK_EXTRA_LIBS += $(SURGE_DEP_PATH)/libs/sst/sst-plugininfra/libs/filesystem/libfilesystem.a +endif +RACK_EXTRA_LIBS += $(SURGE_DEP_PATH)/libs/sst/sst-plugininfra/libs/strnatcmp/libstrnatcmp.a +RACK_EXTRA_LIBS += $(SURGE_DEP_PATH)/libs/sst/sst-plugininfra/libs/tinyxml/libtinyxml.a +endif + +# -------------------------------------------------------------- + +# FIXME +ifeq ($(CIBUILD)$(WASM),truetrue) +ifneq ($(STATIC_BUILD),true) +STATIC_CARLA_PLUGIN_LIBS = -lsndfile -lopus -lFLAC -lvorbisenc -lvorbis -logg -lm +endif +endif EXTRA_DEPENDENCIES = $(RACK_EXTRA_LIBS) $(CARLA_EXTRA_LIBS) EXTRA_LIBS = $(RACK_EXTRA_LIBS) $(CARLA_EXTRA_LIBS) $(STATIC_CARLA_PLUGIN_LIBS) -ifeq ($(shell pkg-config --exists fftw3f && echo true),true) +ifeq ($(shell $(PKG_CONFIG) --exists fftw3f && echo true),true) EXTRA_DEPENDENCIES += ../../deps/aubio/libaubio.a EXTRA_LIBS += ../../deps/aubio/libaubio.a EXTRA_LIBS += $(shell $(PKG_CONFIG) --libs fftw3f) endif -# -------------------------------------------------------------- -# Extra flags for liblo - -BASE_FLAGS += -DHAVE_LIBLO -BASE_FLAGS += $(LIBLO_FLAGS) -LINK_FLAGS += $(LIBLO_LIBS) +ifneq ($(NOPLUGINS),true) +ifeq ($(MACOS),true) +EXTRA_LIBS += -framework Accelerate +endif +endif # -------------------------------------------------------------- # Extra flags for VCV stuff @@ -106,11 +151,11 @@ BASE_FLAGS += -DPRIVATE= BASE_FLAGS += -I.. BASE_FLAGS += -I../../dpf/dgl/src/nanovg BASE_FLAGS += -I../../include -BASE_FLAGS += -I../../include/neon-compat +BASE_FLAGS += -I../../include/simd-compat BASE_FLAGS += -I../Rack/include ifeq ($(SYSDEPS),true) BASE_FLAGS += -DCARDINAL_SYSDEPS -BASE_FLAGS += $(shell pkg-config --cflags jansson libarchive samplerate speexdsp) +BASE_FLAGS += $(shell $(PKG_CONFIG) --cflags jansson libarchive samplerate speexdsp) else BASE_FLAGS += -DZSTDLIB_VISIBILITY= BASE_FLAGS += -I../Rack/dep/include @@ -119,41 +164,98 @@ BASE_FLAGS += -I../Rack/dep/glfw/include BASE_FLAGS += -I../Rack/dep/nanosvg/src BASE_FLAGS += -I../Rack/dep/oui-blendish -ifeq ($(WASM),true) -BASE_FLAGS += -DNANOVG_GLES2=1 -BASE_FLAGS += -msse -msse2 -msse3 -msimd128 -else ifneq ($(HAIKU),true) +ifeq ($(HEADLESS),true) +BASE_FLAGS += -DHEADLESS +endif + +ifeq ($(MOD_BUILD),true) +BASE_FLAGS += -DDISTRHO_PLUGIN_USES_MODGUI=1 -DDISTRHO_PLUGIN_MINIMUM_BUFFER_SIZE=0xffff +endif + +ifneq ($(WASM),true) +ifneq ($(HAIKU),true) BASE_FLAGS += -pthread endif +endif ifeq ($(WINDOWS),true) BASE_FLAGS += -D_USE_MATH_DEFINES BASE_FLAGS += -DWIN32_LEAN_AND_MEAN +BASE_FLAGS += -D_WIN32_WINNT=0x0600 BASE_FLAGS += -I../../include/mingw-compat BASE_FLAGS += -I../../include/mingw-std-threads endif +ifeq ($(USE_GLES2),true) +BASE_FLAGS += -DNANOVG_GLES2_FORCED +else ifeq ($(USE_GLES3),true) +BASE_FLAGS += -DNANOVG_GLES3_FORCED +endif + BUILD_C_FLAGS += -std=gnu11 BUILD_C_FLAGS += -fno-finite-math-only -fno-strict-aliasing BUILD_CXX_FLAGS += -fno-finite-math-only -fno-strict-aliasing ifneq ($(MACOS),true) BUILD_CXX_FLAGS += -faligned-new -Wno-abi +ifeq ($(MOD_BUILD),true) +BUILD_CXX_FLAGS += -std=gnu++17 +endif endif # Rack code is not tested for this flag, unset it BUILD_CXX_FLAGS += -U_GLIBCXX_ASSERTIONS -Wp,-U_GLIBCXX_ASSERTIONS +# Ignore bad behaviour from Rack API +BUILD_CXX_FLAGS += -Wno-format-security + # -------------------------------------------------------------- # FIXME lots of warnings from VCV side BASE_FLAGS += -Wno-unused-parameter BASE_FLAGS += -Wno-unused-variable -# -------------------------------------------------------------- -# extra linker flags - -ifeq ($(HAIKU),true) +ifeq ($(WASM),true) +ifneq ($(STATIC_BUILD),true) +LINK_FLAGS += --use-preload-plugins +LINK_FLAGS += --preload-file=./jsfx +LINK_FLAGS += --preload-file=./lv2 +endif +LINK_FLAGS += --preload-file=../../bin/CardinalNative.lv2/resources@/resources +LINK_FLAGS += --use-preload-cache +ifneq ($(NOPLUGINS),true) +SYMLINKED_DIRS_RESOURCES = +# find . -type l | grep -v svg | grep -v ttf | grep -v art | grep -v json | grep -v png | grep -v otf | sort +SYMLINKED_DIRS_RESOURCES += BaconPlugs/res/midi/chopin +SYMLINKED_DIRS_RESOURCES += BaconPlugs/res/midi/debussy +SYMLINKED_DIRS_RESOURCES += BaconPlugs/res/midi/goldberg +SYMLINKED_DIRS_RESOURCES += cf/playeroscs +SYMLINKED_DIRS_RESOURCES += DrumKit/res/samples +SYMLINKED_DIRS_RESOURCES += Fundamental/presets +SYMLINKED_DIRS_RESOURCES += GrandeModular/presets +SYMLINKED_DIRS_RESOURCES += LyraeModules/presets +SYMLINKED_DIRS_RESOURCES += Meander/res +SYMLINKED_DIRS_RESOURCES += MindMeldModular/presets +SYMLINKED_DIRS_RESOURCES += MindMeldModular/res/ShapeMaster/CommunityPresets +SYMLINKED_DIRS_RESOURCES += MindMeldModular/res/ShapeMaster/CommunityShapes +SYMLINKED_DIRS_RESOURCES += MindMeldModular/res/ShapeMaster/MindMeldPresets +SYMLINKED_DIRS_RESOURCES += MindMeldModular/res/ShapeMaster/MindMeldShapes +SYMLINKED_DIRS_RESOURCES += Mog/res +SYMLINKED_DIRS_RESOURCES += nonlinearcircuits/res +SYMLINKED_DIRS_RESOURCES += Orbits/presets +SYMLINKED_DIRS_RESOURCES += stoermelder-packone/presets +SYMLINKED_DIRS_RESOURCES += surgext/build/surge-data/fx_presets +SYMLINKED_DIRS_RESOURCES += surgext/build/surge-data/wavetables +SYMLINKED_DIRS_RESOURCES += surgext/patches +SYMLINKED_DIRS_RESOURCES += surgext/presets +LINK_FLAGS += $(foreach d,$(SYMLINKED_DIRS_RESOURCES),--preload-file=../../bin/CardinalNative.lv2/resources/$(d)@/resources/$(d)) +endif +LINK_FLAGS += -sALLOW_MEMORY_GROWTH +LINK_FLAGS += -sINITIAL_MEMORY=64Mb +LINK_FLAGS += -sLZ4=1 +LINK_FLAGS += --shell-file=../emscripten/shell.html +LINK_FLAGS += -O3 +else ifeq ($(HAIKU),true) LINK_FLAGS += -lpthread else LINK_FLAGS += -pthread @@ -181,7 +283,7 @@ EXTRA_LIBS += -lws2_32 -lwinmm endif ifeq ($(SYSDEPS),true) -EXTRA_LIBS += $(shell pkg-config --libs jansson libarchive samplerate speexdsp) +EXTRA_LIBS += $(shell $(PKG_CONFIG) --libs jansson libarchive samplerate speexdsp) endif ifeq ($(WITH_LTO),true) @@ -193,6 +295,13 @@ LINK_FLAGS += -Wno-stringop-overflow endif endif +# -------------------------------------------------------------- +# Extra flags for liblo + +BASE_FLAGS += -DHAVE_LIBLO +BASE_FLAGS += $(LIBLO_FLAGS) +LINK_FLAGS += $(LIBLO_LIBS) + # -------------------------------------------------------------- # fallback path to resource files diff --git a/src/CardinalRemote/RemoteUI.cpp b/src/CardinalRemote/RemoteUI.cpp index 1295f13..97f4038 100644 --- a/src/CardinalRemote/RemoteUI.cpp +++ b/src/CardinalRemote/RemoteUI.cpp @@ -17,7 +17,7 @@ #include "RemoteUI.hpp" -// #include +#include // #include #include #include @@ -26,66 +26,293 @@ #include #include +#include "AsyncDialog.hpp" +#include "WindowParameters.hpp" + +// -------------------------------------------------------------------------------------------------------------------- + +namespace rack { +namespace app { + widget::Widget* createMenuBar(bool isStandalone); +} +namespace window { + void WindowSetPluginRemote(Window* window, NanoTopLevelWidget* tlw); + void WindowSetMods(Window* window, int mods); + void WindowSetInternalSize(rack::window::Window* window, math::Vec size); +} +} + +// -------------------------------------------------------------------------------------------------------------------- + CardinalRemoteUI::CardinalRemoteUI(Window& window, const std::string& templatePath) - : NanoTopLevelWidget(window), - context(nullptr) + : NanoTopLevelWidget(window) { - // create unique temporary path for this instance - try { - char uidBuf[24]; - const std::string tmp = rack::system::getTempDirectory(); + CardinalPluginContext& context(*static_cast(rack::contextGet())); + context.nativeWindowId = getWindow().getNativeWindowHandle(); + context.tlw = this; - for (int i=1;; ++i) - { - std::snprintf(uidBuf, sizeof(uidBuf), "CardinalRemote.%04d", i); - const std::string trypath = rack::system::join(tmp, uidBuf); - - if (! rack::system::exists(trypath)) - { - if (rack::system::createDirectories(trypath)) - autosavePath = trypath; - break; - } - } - } DISTRHO_SAFE_EXCEPTION("create unique temporary path"); + window.setIgnoringKeyRepeat(true); + context.nativeWindowId = window.getNativeWindowHandle(); - rack::contextSet(&context); + const double scaleFactor = getScaleFactor(); - context.bufferSize = 512; - rack::settings::sampleRate = context.sampleRate = 48000; + setGeometryConstraints(648 * scaleFactor, 538 * scaleFactor); - context.engine = new rack::engine::Engine; - context.engine->setSampleRate(context.sampleRate); + if (scaleFactor != 1.0) + setSize(DISTRHO_UI_DEFAULT_WIDTH * scaleFactor, DISTRHO_UI_DEFAULT_HEIGHT * scaleFactor); - context.history = new rack::history::State; - context.patch = new rack::patch::Manager; - context.patch->autosavePath = autosavePath; - context.patch->templatePath = templatePath; + rack::window::WindowSetPluginRemote(context.window, this); - context.event = new rack::widget::EventState; - context.scene = new rack::app::Scene; - context.event->rootWidget = context.scene; - context.window = new rack::window::Window; + if (rack::widget::Widget* const menuBar = context.scene->menuBar) + { + context.scene->removeChild(menuBar); + delete menuBar; + } - context.patch->loadTemplate(); - context.scene->rackScroll->reset(); + context.scene->menuBar = rack::app::createMenuBar(true); + context.scene->addChildBelow(context.scene->menuBar, context.scene->rackScroll); - context.nativeWindowId = getWindow().getNativeWindowHandle(); + // hide "Browse VCV Library" button + rack::widget::Widget* const browser = context.scene->browser->children.back(); + rack::widget::Widget* const headerLayout = browser->children.front(); + rack::widget::Widget* const libraryButton = headerLayout->children.back(); + libraryButton->hide(); + + // Report to user if something is wrong with the installation + std::string errorMessage; + + if (rack::asset::systemDir.empty()) + { + errorMessage = "Failed to locate Cardinal plugin bundle.\n" + "Install Cardinal with its plugin bundle folder intact and try again."; + } + else if (! rack::system::exists(rack::asset::systemDir)) + { + errorMessage = rack::string::f("System directory \"%s\" does not exist. " + "Make sure Cardinal was downloaded and installed correctly.", + rack::asset::systemDir.c_str()); + } + + if (! errorMessage.empty()) + { + static bool shown = false; + + if (! shown) + { + shown = true; + asyncDialog::create(errorMessage.c_str()); + } + } + + context.window->step(); + + // WindowParametersSetCallback(context.window, this); } CardinalRemoteUI::~CardinalRemoteUI() { - rack::contextSet(&context); - + CardinalPluginContext& context(*static_cast(rack::contextGet())); context.nativeWindowId = 0; - context.patch->clear(); - - if (! autosavePath.empty()) - rack::system::removeRecursively(autosavePath); } void CardinalRemoteUI::onNanoDisplay() { - rack::contextSet(&context); + CardinalPluginContext& context(*static_cast(rack::contextGet())); context.window->step(); + + // TODO + repaint(); +} + +// -------------------------------------------------------------------------------------------------------------------- + +static int glfwMods(const uint mod) noexcept +{ + int mods = 0; + + if (mod & kModifierControl) + mods |= GLFW_MOD_CONTROL; + if (mod & kModifierShift) + mods |= GLFW_MOD_SHIFT; + if (mod & kModifierAlt) + mods |= GLFW_MOD_ALT; + if (mod & kModifierSuper) + mods |= GLFW_MOD_SUPER; + + /* + if (glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS || glfwGetKey(win, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS) + mods |= GLFW_MOD_SHIFT; + if (glfwGetKey(win, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS || glfwGetKey(win, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS) + mods |= GLFW_MOD_CONTROL; + if (glfwGetKey(win, GLFW_KEY_LEFT_ALT) == GLFW_PRESS || glfwGetKey(win, GLFW_KEY_RIGHT_ALT) == GLFW_PRESS) + mods |= GLFW_MOD_ALT; + if (glfwGetKey(win, GLFW_KEY_LEFT_SUPER) == GLFW_PRESS || glfwGetKey(win, GLFW_KEY_RIGHT_SUPER) == GLFW_PRESS) + mods |= GLFW_MOD_SUPER; + */ + + return mods; +} + +bool CardinalRemoteUI::onMouse(const MouseEvent& ev) +{ + if (ev.press) + getWindow().focus(); + + const int action = ev.press ? GLFW_PRESS : GLFW_RELEASE; + int mods = glfwMods(ev.mod); + + int button; + + switch (ev.button) + { + case 1: button = GLFW_MOUSE_BUTTON_LEFT; break; + case 2: button = GLFW_MOUSE_BUTTON_RIGHT; break; + case 3: button = GLFW_MOUSE_BUTTON_MIDDLE; break; + default: + button = ev.button; + break; + } + + #ifdef DISTRHO_OS_MAC + // Remap Ctrl-left click to right click on macOS + if (button == GLFW_MOUSE_BUTTON_LEFT && (mods & RACK_MOD_MASK) == GLFW_MOD_CONTROL) { + button = GLFW_MOUSE_BUTTON_RIGHT; + mods &= ~GLFW_MOD_CONTROL; + } + // Remap Ctrl-shift-left click to middle click on macOS + if (button == GLFW_MOUSE_BUTTON_LEFT && (mods & RACK_MOD_MASK) == (GLFW_MOD_CONTROL | GLFW_MOD_SHIFT)) { + button = GLFW_MOUSE_BUTTON_MIDDLE; + mods &= ~(GLFW_MOD_CONTROL | GLFW_MOD_SHIFT); + } + #endif + + CardinalPluginContext* context = static_cast(rack::contextGet()); + return context->event->handleButton(lastMousePos, button, action, mods); +} + +bool CardinalRemoteUI::onMotion(const MotionEvent& ev) +{ + const rack::math::Vec mousePos = rack::math::Vec(ev.pos.getX(), ev.pos.getY()).div(getScaleFactor()).round(); + const rack::math::Vec mouseDelta = mousePos.minus(lastMousePos); + + lastMousePos = mousePos; + + CardinalPluginContext* context = static_cast(rack::contextGet()); + return context->event->handleHover(mousePos, mouseDelta); +} + +bool CardinalRemoteUI::onScroll(const ScrollEvent& ev) +{ + rack::math::Vec scrollDelta = rack::math::Vec(ev.delta.getX(), ev.delta.getY()); + #ifndef DISTRHO_OS_MAC + scrollDelta = scrollDelta.mult(50.0); + #endif + + const int mods = glfwMods(ev.mod); + + CardinalPluginContext* context = static_cast(rack::contextGet()); + return context->event->handleScroll(lastMousePos, scrollDelta); } + +bool CardinalRemoteUI::onCharacterInput(const CharacterInputEvent& ev) +{ + if (ev.character < ' ' || ev.character >= kKeyDelete) + return false; + + const int mods = glfwMods(ev.mod); + + CardinalPluginContext* context = static_cast(rack::contextGet()); + return context->event->handleText(lastMousePos, ev.character); +} + +bool CardinalRemoteUI::onKeyboard(const KeyboardEvent& ev) +{ + const int action = ev.press ? GLFW_PRESS : GLFW_RELEASE; + const int mods = glfwMods(ev.mod); + + /* These are unsupported in pugl right now + #define GLFW_KEY_KP_0 320 + #define GLFW_KEY_KP_1 321 + #define GLFW_KEY_KP_2 322 + #define GLFW_KEY_KP_3 323 + #define GLFW_KEY_KP_4 324 + #define GLFW_KEY_KP_5 325 + #define GLFW_KEY_KP_6 326 + #define GLFW_KEY_KP_7 327 + #define GLFW_KEY_KP_8 328 + #define GLFW_KEY_KP_9 329 + #define GLFW_KEY_KP_DECIMAL 330 + #define GLFW_KEY_KP_DIVIDE 331 + #define GLFW_KEY_KP_MULTIPLY 332 + #define GLFW_KEY_KP_SUBTRACT 333 + #define GLFW_KEY_KP_ADD 334 + #define GLFW_KEY_KP_ENTER 335 + #define GLFW_KEY_KP_EQUAL 336 + */ + + int key; + switch (ev.key) + { + case '\r': key = GLFW_KEY_ENTER; break; + case '\t': key = GLFW_KEY_TAB; break; + case kKeyBackspace: key = GLFW_KEY_BACKSPACE; break; + case kKeyEscape: key = GLFW_KEY_ESCAPE; break; + case kKeyDelete: key = GLFW_KEY_DELETE; break; + case kKeyF1: key = GLFW_KEY_F1; break; + case kKeyF2: key = GLFW_KEY_F2; break; + case kKeyF3: key = GLFW_KEY_F3; break; + case kKeyF4: key = GLFW_KEY_F4; break; + case kKeyF5: key = GLFW_KEY_F5; break; + case kKeyF6: key = GLFW_KEY_F6; break; + case kKeyF7: key = GLFW_KEY_F7; break; + case kKeyF8: key = GLFW_KEY_F8; break; + case kKeyF9: key = GLFW_KEY_F9; break; + case kKeyF10: key = GLFW_KEY_F10; break; + case kKeyF11: key = GLFW_KEY_F11; break; + case kKeyF12: key = GLFW_KEY_F12; break; + case kKeyLeft: key = GLFW_KEY_LEFT; break; + case kKeyUp: key = GLFW_KEY_UP; break; + case kKeyRight: key = GLFW_KEY_RIGHT; break; + case kKeyDown: key = GLFW_KEY_DOWN; break; + case kKeyPageUp: key = GLFW_KEY_PAGE_UP; break; + case kKeyPageDown: key = GLFW_KEY_PAGE_DOWN; break; + case kKeyHome: key = GLFW_KEY_HOME; break; + case kKeyEnd: key = GLFW_KEY_END; break; + case kKeyInsert: key = GLFW_KEY_INSERT; break; + case kKeyShiftL: key = GLFW_KEY_LEFT_SHIFT; break; + case kKeyShiftR: key = GLFW_KEY_RIGHT_SHIFT; break; + case kKeyControlL: key = GLFW_KEY_LEFT_CONTROL; break; + case kKeyControlR: key = GLFW_KEY_RIGHT_CONTROL; break; + case kKeyAltL: key = GLFW_KEY_LEFT_ALT; break; + case kKeyAltR: key = GLFW_KEY_RIGHT_ALT; break; + case kKeySuperL: key = GLFW_KEY_LEFT_SUPER; break; + case kKeySuperR: key = GLFW_KEY_RIGHT_SUPER; break; + case kKeyMenu: key = GLFW_KEY_MENU; break; + case kKeyCapsLock: key = GLFW_KEY_CAPS_LOCK; break; + case kKeyScrollLock: key = GLFW_KEY_SCROLL_LOCK; break; + case kKeyNumLock: key = GLFW_KEY_NUM_LOCK; break; + case kKeyPrintScreen: key = GLFW_KEY_PRINT_SCREEN; break; + case kKeyPause: key = GLFW_KEY_PAUSE; break; + default: + // glfw expects uppercase + if (ev.key >= 'a' && ev.key <= 'z') + key = ev.key - ('a' - 'A'); + else + key = ev.key; + break; + } + + CardinalPluginContext* context = static_cast(rack::contextGet()); + return context->event->handleKey(lastMousePos, key, ev.keycode, action, mods); +} + +void CardinalRemoteUI::onResize(const ResizeEvent& ev) +{ + NanoTopLevelWidget::onResize(ev); + + CardinalPluginContext* context = static_cast(rack::contextGet()); + if (context->window != nullptr) + WindowSetInternalSize(context->window, rack::math::Vec(ev.size.getWidth(), ev.size.getHeight())); +} + +// -------------------------------------------------------------------------------------------------------------------- diff --git a/src/CardinalRemote/RemoteUI.hpp b/src/CardinalRemote/RemoteUI.hpp index 1ed4696..ca29d28 100644 --- a/src/CardinalRemote/RemoteUI.hpp +++ b/src/CardinalRemote/RemoteUI.hpp @@ -20,10 +20,11 @@ #include "NanoVG.hpp" #include "PluginContext.hpp" +#include + class CardinalRemoteUI : public NanoTopLevelWidget { - CardinalPluginContext context; - std::string autosavePath; + rack::math::Vec lastMousePos; public: explicit CardinalRemoteUI(Window& window, const std::string& templatePath); @@ -31,6 +32,12 @@ public: protected: void onNanoDisplay() override; + bool onMouse(const MouseEvent& ev) override; + bool onMotion(const MotionEvent& ev) override; + bool onScroll(const ScrollEvent& ev) override; + bool onCharacterInput(const CharacterInputEvent& ev) override; + bool onKeyboard(const KeyboardEvent& ev) override; + void onResize(const ResizeEvent& ev) override; DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CardinalRemoteUI) }; diff --git a/src/CardinalRemote/main.cpp b/src/CardinalRemote/main.cpp index a2329fe..b5b6788 100644 --- a/src/CardinalRemote/main.cpp +++ b/src/CardinalRemote/main.cpp @@ -20,13 +20,19 @@ #include "RemoteUI.hpp" #include +#include #include #include #include #include +#include +#include #include + +#include "PluginContext.hpp" + namespace rack { namespace plugin { void initStaticPlugins(); @@ -34,6 +40,26 @@ namespace plugin { } } +START_NAMESPACE_DISTRHO + +bool isUsingNativeAudio() noexcept { return false; } +bool supportsAudioInput() { return false; } +bool supportsBufferSizeChanges() { return false; } +bool supportsMIDI() { return false; } +bool isAudioInputEnabled() { return false; } +bool isMIDIEnabled() { return false; } +uint getBufferSize() { return 0; } +bool requestAudioInput() { return false; } +bool requestBufferSizeChange(uint) { return false; } +bool requestMIDI() { return false; } +const char* getPluginFormatName() noexcept { return "Remote"; } + +uint32_t Plugin::getBufferSize() const noexcept { return 128; } +double Plugin::getSampleRate() const noexcept { return 48000; } +bool Plugin::writeMidiEvent(const MidiEvent&) noexcept { return false; } + +END_NAMESPACE_DISTRHO + int main(const int argc, const char* argv[]) { using namespace rack; @@ -42,7 +68,6 @@ int main(const int argc, const char* argv[]) settings::autoCheckUpdates = false; settings::autosaveInterval = 0; settings::devMode = true; - settings::discordUpdateActivity = false; settings::isPlugin = true; settings::skipLoadOnLaunch = true; settings::showTipsOnLaunch = false; @@ -131,17 +156,68 @@ int main(const int argc, const char* argv[]) INFO("Initializing plugin browser DB"); app::browserInit(); + // create unique temporary path for this instance + std::string autosavePath; + + try { + char uidBuf[24]; + const std::string tmp = rack::system::getTempDirectory(); + + for (int i=1;; ++i) + { + std::snprintf(uidBuf, sizeof(uidBuf), "CardinalRemote.%04d", i); + const std::string trypath = rack::system::join(tmp, uidBuf); + + if (! rack::system::exists(trypath)) + { + if (rack::system::createDirectories(trypath)) + autosavePath = trypath; + break; + } + } + } DISTRHO_SAFE_EXCEPTION("create unique temporary path"); + + CardinalPluginContext context(nullptr); + rack::contextSet(&context); + + context.bufferSize = 512; + rack::settings::sampleRate = context.sampleRate = 48000; + + context.engine = new rack::engine::Engine; + context.engine->setSampleRate(context.sampleRate); + + context.history = new rack::history::State; + context.patch = new rack::patch::Manager; + context.patch->autosavePath = autosavePath; + context.patch->templatePath = templatePath; + + 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(); + Application app; Window win(app); + win.setResizable(true); win.setTitle("CardinalRemote"); ScopedPointer remoteUI; - + { + const Window::ScopedGraphicsContext sgc(win); remoteUI = new CardinalRemoteUI(win, templatePath); } + win.show(); app.exec(); + context.patch->clear(); + + if (! autosavePath.empty()) + rack::system::removeRecursively(autosavePath); + INFO("Clearing asset paths"); asset::bundlePath.clear(); asset::systemDir.clear(); diff --git a/src/CardinalUI.cpp b/src/CardinalUI.cpp index 5b1496e..49caa38 100644 --- a/src/CardinalUI.cpp +++ b/src/CardinalUI.cpp @@ -67,40 +67,6 @@ START_NAMESPACE_DISTRHO // ----------------------------------------------------------------------------------------------------------- -bool CardinalPluginContext::addIdleCallback(IdleCallback* const cb) const -{ - if (ui == nullptr) - return false; - - ui->addIdleCallback(cb); - return true; -} - -void CardinalPluginContext::removeIdleCallback(IdleCallback* const cb) const -{ - if (ui == nullptr) - return; - - ui->removeIdleCallback(cb); -} - -void handleHostParameterDrag(const CardinalPluginContext* pcontext, uint index, bool started) -{ - DISTRHO_SAFE_ASSERT_RETURN(pcontext->ui != nullptr,); - - if (started) - { - pcontext->ui->editParameter(index, true); - pcontext->ui->setParameterValue(index, pcontext->parameters[index]); - } - else - { - pcontext->ui->editParameter(index, false); - } -} - -// ----------------------------------------------------------------------------------------------------------- - #ifdef DISTRHO_OS_WASM struct WasmWelcomeDialog : rack::widget::OpaqueWidget { diff --git a/src/PluginContext.hpp b/src/PluginContext.hpp index c5a2292..933d416 100644 --- a/src/PluginContext.hpp +++ b/src/PluginContext.hpp @@ -64,13 +64,14 @@ struct CardinalPluginContext : rack::Context { uint32_t midiEventCount; Plugin* const plugin; #ifndef HEADLESS + NanoTopLevelWidget* tlw; UI* ui; #endif CardinalPluginContext(Plugin* const p) - : bufferSize(p->getBufferSize()), + : bufferSize(p != nullptr ? p->getBufferSize() : 0), processCounter(0), - sampleRate(p->getSampleRate()), + sampleRate(p != nullptr ? p->getSampleRate() : 0.0), #if CARDINAL_VARIANT_MAIN variant(kCardinalVariantMain), #elif CARDINAL_VARIANT_FX @@ -105,6 +106,7 @@ struct CardinalPluginContext : rack::Context { midiEventCount(0), plugin(p) #ifndef HEADLESS + , tlw(nullptr) , ui(nullptr) #endif { @@ -169,6 +171,7 @@ public: filebrowseraction(), filebrowserhandle(nullptr) { + context->tlw = this; context->ui = this; } @@ -177,6 +180,7 @@ public: if (filebrowserhandle != nullptr) fileBrowserClose(filebrowserhandle); + context->tlw = nullptr; context->ui = nullptr; } }; diff --git a/src/custom/glfw.cpp b/src/custom/glfw.cpp index 250586e..b4fa62a 100644 --- a/src/custom/glfw.cpp +++ b/src/custom/glfw.cpp @@ -30,10 +30,10 @@ GLFWAPI const char* glfwGetClipboardString(GLFWwindow*) { CardinalPluginContext* const context = static_cast(APP); DISTRHO_SAFE_ASSERT_RETURN(context != nullptr, nullptr); - DISTRHO_SAFE_ASSERT_RETURN(context->ui != nullptr, nullptr); + DISTRHO_SAFE_ASSERT_RETURN(context->tlw != nullptr, nullptr); size_t dataSize; - return static_cast(context->ui->getClipboard(dataSize)); + return static_cast(context->tlw->getClipboard(dataSize)); } GLFWAPI void glfwSetClipboardString(GLFWwindow*, const char* const text) @@ -42,9 +42,9 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow*, const char* const text) CardinalPluginContext* const context = static_cast(APP); DISTRHO_SAFE_ASSERT_RETURN(context != nullptr,); - DISTRHO_SAFE_ASSERT_RETURN(context->ui != nullptr,); + DISTRHO_SAFE_ASSERT_RETURN(context->tlw != nullptr,); - context->ui->setClipboard(nullptr, text, std::strlen(text)+1); + context->tlw->setClipboard(nullptr, text, std::strlen(text)+1); } GLFWAPI GLFWcursor* glfwCreateStandardCursor(const int shape) @@ -91,18 +91,18 @@ GLFWAPI void glfwSetCursor(GLFWwindow*, GLFWcursor* const cursor) { CardinalPluginContext* const context = static_cast(APP); DISTRHO_SAFE_ASSERT_RETURN(context != nullptr,); - DISTRHO_SAFE_ASSERT_RETURN(context->ui != nullptr,); + DISTRHO_SAFE_ASSERT_RETURN(context->tlw != nullptr,); - context->ui->setCursor(cursor != nullptr ? cursor->cursorId : kMouseCursorArrow); + context->tlw->setCursor(cursor != nullptr ? cursor->cursorId : kMouseCursorArrow); } GLFWAPI double glfwGetTime(void) { CardinalPluginContext* const context = static_cast(APP); DISTRHO_SAFE_ASSERT_RETURN(context != nullptr, 0.0); - DISTRHO_SAFE_ASSERT_RETURN(context->ui != nullptr, 0.0); + DISTRHO_SAFE_ASSERT_RETURN(context->tlw != nullptr, 0.0); - return context->ui->getApp().getTime(); + return context->tlw->getApp().getTime(); } GLFWAPI const char* glfwGetKeyName(const int key, int) diff --git a/src/override/Window.cpp b/src/override/Window.cpp index 7c9d481..32fddbb 100644 --- a/src/override/Window.cpp +++ b/src/override/Window.cpp @@ -145,6 +145,7 @@ struct Window::Internal { std::string lastWindowTitle; DISTRHO_NAMESPACE::UI* ui = nullptr; + DGL_NAMESPACE::NanoTopLevelWidget* tlw = nullptr; DISTRHO_NAMESPACE::WindowParameters params; DISTRHO_NAMESPACE::WindowParametersCallback* callback = nullptr; DGL_NAMESPACE::Application hiddenApp; @@ -238,6 +239,112 @@ Window::Window() { #endif } +void WindowSetPluginRemote(Window* const window, NanoTopLevelWidget* const tlw) +{ + // if nanovg context failed, init only bare minimum + if (window->vg == nullptr) + { + if (tlw != nullptr) + { + window->internal->tlw = tlw; + window->internal->size = rack::math::Vec(tlw->getWidth(), tlw->getHeight()); + } + else + { + window->internal->tlw = nullptr; + window->internal->callback = nullptr; + } + return; + } + + if (tlw != nullptr) + { + const GLubyte* vendor = glGetString(GL_VENDOR); + const GLubyte* renderer = glGetString(GL_RENDERER); + const GLubyte* version = glGetString(GL_VERSION); + INFO("Renderer: %s %s", vendor, renderer); + INFO("OpenGL: %s", version); + + window->internal->tlw = tlw; + window->internal->size = rack::math::Vec(tlw->getWidth(), tlw->getHeight()); + + // Set up NanoVG + window->internal->r_vg = tlw->getContext(); +#ifdef NANOVG_GLES2 + window->internal->r_fbVg = nvgCreateSharedGLES2(window->internal->r_vg, NVG_ANTIALIAS); +#else + window->internal->r_fbVg = nvgCreateSharedGL2(window->internal->r_vg, NVG_ANTIALIAS); +#endif + + // swap contexts + window->internal->o_vg = window->vg; + window->internal->o_fbVg = window->fbVg; + window->vg = window->internal->r_vg; + window->fbVg = window->internal->r_fbVg; + + // also for fonts and images + window->uiFont->vg = window->vg; + window->uiFont->handle = loadFallbackFont(window->vg); + for (auto& font : window->internal->fontCache) + { + font.second->vg = window->vg; + font.second->ohandle = font.second->handle; + font.second->handle = nvgCreateFont(window->vg, + font.second->ofilename.c_str(), font.second->ofilename.c_str()); + } + for (auto& image : window->internal->imageCache) + { + image.second->vg = window->vg; + image.second->ohandle = image.second->handle; + image.second->handle = nvgCreateImage(window->vg, image.second->ofilename.c_str(), + NVG_IMAGE_REPEATX | NVG_IMAGE_REPEATY); + } + + // Init settings + WindowParametersRestore(window); + + widget::Widget::ContextCreateEvent e; + APP->scene->onContextCreate(e); + } + else + { + widget::Widget::ContextDestroyEvent e; + APP->scene->onContextDestroy(e); + + // swap contexts + window->uiFont->vg = window->internal->o_vg; + window->vg = window->internal->o_vg; + window->fbVg = window->internal->o_fbVg; + window->internal->o_vg = nullptr; + window->internal->o_fbVg = nullptr; + + // also for fonts and images + window->uiFont->vg = window->vg; + window->uiFont->handle = loadFallbackFont(window->vg); + for (auto& font : window->internal->fontCache) + { + font.second->vg = window->vg; + font.second->handle = font.second->ohandle; + font.second->ohandle = -1; + } + for (auto& image : window->internal->imageCache) + { + image.second->vg = window->vg; + image.second->handle = image.second->ohandle; + image.second->ohandle = -1; + } + +#if defined NANOVG_GLES2 + nvgDeleteGLES2(window->internal->r_fbVg); +#else + nvgDeleteGL2(window->internal->r_fbVg); +#endif + + window->internal->tlw = nullptr; + window->internal->callback = nullptr; + } +} + void WindowSetPluginUI(Window* const window, DISTRHO_NAMESPACE::UI* const ui) { // if nanovg context failed, init only bare minimum @@ -264,6 +371,7 @@ void WindowSetPluginUI(Window* const window, DISTRHO_NAMESPACE::UI* const ui) INFO("Renderer: %s %s", vendor, renderer); INFO("OpenGL: %s", version); + window->internal->tlw = ui; window->internal->ui = ui; window->internal->size = rack::math::Vec(ui->getWidth(), ui->getHeight()); @@ -339,6 +447,7 @@ void WindowSetPluginUI(Window* const window, DISTRHO_NAMESPACE::UI* const ui) nvgDeleteGL2(window->internal->r_fbVg); #endif + window->internal->tlw = nullptr; window->internal->ui = nullptr; window->internal->callback = nullptr; } @@ -384,8 +493,8 @@ void Window::setSize(math::Vec size) { size = size.max(WINDOW_SIZE_MIN); internal->size = size; - if (DISTRHO_NAMESPACE::UI* const ui = internal->ui) - ui->setSize(internal->size.x, internal->size.y); + if (DGL_NAMESPACE::NanoTopLevelWidget* const tlw = internal->ui) + tlw->setSize(internal->size.x, internal->size.y); } void WindowSetInternalSize(rack::window::Window* const window, math::Vec size) { @@ -453,7 +562,7 @@ static void Window__writeImagePNG(void* context, void* data, int size) { void Window::step() { - DISTRHO_SAFE_ASSERT_RETURN(internal->ui != nullptr,); + DISTRHO_SAFE_ASSERT_RETURN(internal->tlw != nullptr,); if (vg == nullptr) return; @@ -480,12 +589,12 @@ void Window::step() { windowTitle += system::getFilename(APP->patch->path); } if (windowTitle != internal->lastWindowTitle) { - internal->ui->getWindow().setTitle(windowTitle.c_str()); + internal->tlw->getWindow().setTitle(windowTitle.c_str()); internal->lastWindowTitle = windowTitle; } // Get desired pixel ratio - float newPixelRatio = internal->ui->getScaleFactor(); + float newPixelRatio = internal->tlw->getScaleFactor(); if (newPixelRatio != pixelRatio) { pixelRatio = newPixelRatio; APP->event->handleDirty(); @@ -504,8 +613,8 @@ void Window::step() { #endif // Get framebuffer/window ratio - int winWidth = internal->ui->getWidth(); - int winHeight = internal->ui->getHeight(); + int winWidth = internal->tlw->getWidth(); + int winHeight = internal->tlw->getHeight(); int fbWidth = winWidth;// * newPixelRatio; int fbHeight = winHeight;// * newPixelRatio; windowRatio = (float)fbWidth / winWidth; @@ -599,9 +708,9 @@ void Window::screenshotModules(const std::string&, float) { void Window::close() { - DISTRHO_SAFE_ASSERT_RETURN(internal->ui != nullptr,); + DISTRHO_SAFE_ASSERT_RETURN(internal->tlw != nullptr,); - internal->ui->getWindow().close(); + internal->tlw->getWindow().close(); } @@ -610,7 +719,7 @@ void Window::cursorLock() { if (!settings::allowCursorLock) return; - emscripten_request_pointerlock(internal->ui->getWindow().getApp().getClassName(), false); + emscripten_request_pointerlock(internal->tlw->getWindow().getApp().getClassName(), false); #endif } @@ -643,7 +752,7 @@ int Window::getMods() { void Window::setFullScreen(const bool fullscreen) { #ifdef DISTRHO_OS_WASM if (fullscreen) - emscripten_request_fullscreen(internal->ui->getWindow().getApp().getClassName(), false); + emscripten_request_fullscreen(internal->tlw->getWindow().getApp().getClassName(), false); else emscripten_exit_fullscreen(); #endif