Move some code around to help remote tool later
Signed-off-by: falkTX <falktx@falktx.com>
This commit is contained in:
parent
76cdce063c
commit
058ad891d2
11 changed files with 747 additions and 198 deletions
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
#include "RemoteUI.hpp"
|
||||
|
||||
// #include <asset.hpp>
|
||||
#include <asset.hpp>
|
||||
// #include <random.hpp>
|
||||
#include <patch.hpp>
|
||||
#include <settings.hpp>
|
||||
|
@ -26,66 +26,293 @@
|
|||
#include <app/Scene.hpp>
|
||||
#include <engine/Engine.hpp>
|
||||
|
||||
#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();
|
||||
|
||||
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");
|
||||
|
||||
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();
|
||||
|
||||
CardinalPluginContext& context(*static_cast<CardinalPluginContext*>(rack::contextGet()));
|
||||
context.nativeWindowId = getWindow().getNativeWindowHandle();
|
||||
context.tlw = this;
|
||||
|
||||
window.setIgnoringKeyRepeat(true);
|
||||
context.nativeWindowId = window.getNativeWindowHandle();
|
||||
|
||||
const double scaleFactor = getScaleFactor();
|
||||
|
||||
setGeometryConstraints(648 * scaleFactor, 538 * scaleFactor);
|
||||
|
||||
if (scaleFactor != 1.0)
|
||||
setSize(DISTRHO_UI_DEFAULT_WIDTH * scaleFactor, DISTRHO_UI_DEFAULT_HEIGHT * scaleFactor);
|
||||
|
||||
rack::window::WindowSetPluginRemote(context.window, this);
|
||||
|
||||
if (rack::widget::Widget* const menuBar = context.scene->menuBar)
|
||||
{
|
||||
context.scene->removeChild(menuBar);
|
||||
delete menuBar;
|
||||
}
|
||||
|
||||
context.scene->menuBar = rack::app::createMenuBar(true);
|
||||
context.scene->addChildBelow(context.scene->menuBar, context.scene->rackScroll);
|
||||
|
||||
// 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<CardinalPluginContext*>(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<CardinalPluginContext*>(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<CardinalPluginContext*>(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<CardinalPluginContext*>(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<CardinalPluginContext*>(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<CardinalPluginContext*>(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<CardinalPluginContext*>(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<CardinalPluginContext*>(rack::contextGet());
|
||||
if (context->window != nullptr)
|
||||
WindowSetInternalSize(context->window, rack::math::Vec(ev.size.getWidth(), ev.size.getHeight()));
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -20,10 +20,11 @@
|
|||
#include "NanoVG.hpp"
|
||||
#include "PluginContext.hpp"
|
||||
|
||||
#include <app/common.hpp>
|
||||
|
||||
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)
|
||||
};
|
||||
|
|
|
@ -20,13 +20,19 @@
|
|||
#include "RemoteUI.hpp"
|
||||
|
||||
#include <asset.hpp>
|
||||
#include <patch.hpp>
|
||||
#include <random.hpp>
|
||||
#include <settings.hpp>
|
||||
#include <system.hpp>
|
||||
|
||||
#include <app/Browser.hpp>
|
||||
#include <app/Scene.hpp>
|
||||
#include <engine/Engine.hpp>
|
||||
#include <ui/common.hpp>
|
||||
|
||||
|
||||
#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<CardinalRemoteUI> 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();
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -30,10 +30,10 @@ GLFWAPI const char* glfwGetClipboardString(GLFWwindow*)
|
|||
{
|
||||
CardinalPluginContext* const context = static_cast<CardinalPluginContext*>(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<const char*>(context->ui->getClipboard(dataSize));
|
||||
return static_cast<const char*>(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<CardinalPluginContext*>(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<CardinalPluginContext*>(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<CardinalPluginContext*>(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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue