Signed-off-by: falkTX <falktx@falktx.com>tags/22.02
@@ -366,7 +366,7 @@ static intptr_t host_dispatcher(const NativeHostHandle handle, const NativeHostD | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
struct CarlaModuleWidget : ModuleWidget { | |||
struct CarlaModuleWidget : ModuleWidget, IdleCallback { | |||
static constexpr const float startX_In = 14.0f; | |||
static constexpr const float startX_Out = 96.0f; | |||
static constexpr const float startY = 74.0f; | |||
@@ -374,6 +374,7 @@ struct CarlaModuleWidget : ModuleWidget { | |||
static constexpr const float middleX = startX_In + (startX_Out - startX_In) * 0.5f + padding * 0.25f; | |||
CarlaModule* const module; | |||
bool idleCallbackActive = false; | |||
bool visible = false; | |||
CarlaModuleWidget(CarlaModule* const m) | |||
@@ -393,21 +394,6 @@ struct CarlaModuleWidget : ModuleWidget { | |||
for (uint i=0; i<CarlaModule::NUM_OUTPUTS; ++i) | |||
addOutput(createOutput<PJ301MPort>(Vec(startX_Out, startY + padding * i), module, i)); | |||
if (module != nullptr && module->fCarlaHostHandle != nullptr) | |||
{ | |||
const CarlaHostHandle handle = module->fCarlaHostHandle; | |||
char winIdStr[24]; | |||
std::snprintf(winIdStr, sizeof(winIdStr), "%lx", (ulong)module->pcontext->nativeWindowId); | |||
carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, winIdStr); | |||
module->fCarlaHostDescriptor.uiParentId = module->pcontext->nativeWindowId; | |||
/* | |||
carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_UI_SCALE, getScaleFactor()*1000, nullptr); | |||
*/ | |||
module->fUI = this; | |||
} | |||
} | |||
~CarlaModuleWidget() override | |||
@@ -427,25 +413,80 @@ struct CarlaModuleWidget : ModuleWidget { | |||
void onContextCreate(const ContextCreateEvent& e) override | |||
{ | |||
ModuleWidget::onContextCreate(e); | |||
widgetCreated(); | |||
} | |||
void onContextDestroy(const ContextDestroyEvent& e) override | |||
{ | |||
widgetDestroyed(); | |||
ModuleWidget::onContextDestroy(e); | |||
} | |||
void onAdd(const AddEvent& e) override | |||
{ | |||
ModuleWidget::onAdd(e); | |||
widgetCreated(); | |||
} | |||
void onRemove(const RemoveEvent& e) override | |||
{ | |||
widgetDestroyed(); | |||
ModuleWidget::onRemove(e); | |||
} | |||
void widgetCreated() | |||
{ | |||
if (module == nullptr || module->pcontext == nullptr || module->fCarlaHostHandle == nullptr) | |||
return; | |||
const CarlaHostHandle handle = module->fCarlaHostHandle; | |||
CardinalPluginContext* const pcontext = module->pcontext; | |||
char winIdStr[24]; | |||
std::snprintf(winIdStr, sizeof(winIdStr), "%lx", (ulong)module->pcontext->nativeWindowId); | |||
carla_set_engine_option(module->fCarlaHostHandle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, winIdStr); | |||
module->fCarlaHostDescriptor.uiParentId = module->pcontext->nativeWindowId; | |||
std::snprintf(winIdStr, sizeof(winIdStr), "%llx", (ulonglong)pcontext->nativeWindowId); | |||
module->fCarlaHostDescriptor.uiParentId = pcontext->nativeWindowId; | |||
carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, winIdStr); | |||
if (pcontext->window != nullptr) | |||
carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_UI_SCALE, pcontext->window->pixelRatio*1000, nullptr); | |||
if (! idleCallbackActive) | |||
idleCallbackActive = pcontext->addIdleCallback(this); | |||
module->fUI = this; | |||
} | |||
void onContextDestroy(const ContextDestroyEvent& e) override | |||
void widgetDestroyed() | |||
{ | |||
if (module != nullptr && module->fCarlaHostHandle != nullptr) | |||
if (module == nullptr || module->pcontext == nullptr || module->fCarlaHostHandle == nullptr) | |||
return; | |||
const CarlaHostHandle handle = module->fCarlaHostHandle; | |||
CardinalPluginContext* const pcontext = module->pcontext; | |||
module->fUI = nullptr; | |||
if (visible) | |||
{ | |||
module->fCarlaHostDescriptor.uiParentId = 0; | |||
carla_set_engine_option(module->fCarlaHostHandle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, "0"); | |||
visible = false; | |||
module->fCarlaPluginDescriptor->ui_show(module->fCarlaPluginHandle, false); | |||
} | |||
ModuleWidget::onContextDestroy(e); | |||
if (idleCallbackActive) | |||
{ | |||
idleCallbackActive = false; | |||
pcontext->removeIdleCallback(this); | |||
} | |||
module->fCarlaHostDescriptor.uiParentId = 0; | |||
carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, "0"); | |||
} | |||
void idleCallback() override | |||
{ | |||
if (module != nullptr && module->fCarlaHostHandle != nullptr && visible) | |||
module->fCarlaPluginDescriptor->ui_idle(module->fCarlaPluginHandle); | |||
} | |||
void drawTextLine(NVGcontext* const vg, const uint offset, const char* const text) | |||
@@ -488,14 +529,6 @@ struct CarlaModuleWidget : ModuleWidget { | |||
ModuleWidget::draw(args); | |||
} | |||
void step() override | |||
{ | |||
if (module != nullptr && module->fCarlaHostHandle != nullptr && visible) | |||
module->fCarlaPluginDescriptor->ui_idle(module->fCarlaPluginHandle); | |||
ModuleWidget::step(); | |||
} | |||
void showUI() | |||
{ | |||
visible = true; | |||
@@ -357,7 +357,7 @@ static intptr_t host_dispatcher(const NativeHostHandle handle, const NativeHostD | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
#ifndef HEADLESS | |||
struct IldaeilWidget : ImGuiWidget, Thread { | |||
struct IldaeilWidget : ImGuiWidget, IdleCallback, Thread { | |||
static constexpr const uint kButtonHeight = 20; | |||
struct PluginInfoCache { | |||
@@ -440,13 +440,14 @@ struct IldaeilWidget : ImGuiWidget, Thread { | |||
String fPopupError; | |||
bool idleCallbackActive = false; | |||
IldaeilModule* const module; | |||
IldaeilWidget(IldaeilModule* const m) | |||
: ImGuiWidget(), | |||
module(m) | |||
{ | |||
if (module == nullptr || module->fCarlaHostHandle == nullptr) | |||
if (module->fCarlaHostHandle == nullptr) | |||
{ | |||
fDrawingState = kDrawingErrorInit; | |||
fPopupError = "Ildaeil backend failed to init properly, cannot continue."; | |||
@@ -460,13 +461,6 @@ struct IldaeilWidget : ImGuiWidget, Thread { | |||
const CarlaHostHandle handle = module->fCarlaHostHandle; | |||
char winIdStr[24]; | |||
std::snprintf(winIdStr, sizeof(winIdStr), "%lx", (ulong)module->pcontext->nativeWindowId); | |||
carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, winIdStr); | |||
/* | |||
carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_UI_SCALE, getScaleFactor()*1000, nullptr); | |||
*/ | |||
if (carla_get_current_plugin_count(handle) != 0) | |||
{ | |||
const uint hints = carla_get_plugin_info(handle, 0)->hints; | |||
@@ -479,10 +473,12 @@ struct IldaeilWidget : ImGuiWidget, Thread { | |||
~IldaeilWidget() override | |||
{ | |||
if (module != nullptr && module->fCarlaHostHandle != nullptr) | |||
if (module->fCarlaHostHandle != nullptr) | |||
{ | |||
module->fUI = nullptr; | |||
carla_set_engine_option(module->fCarlaHostHandle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, "0"); | |||
module->pcontext->removeIdleCallback(this); | |||
} | |||
if (isThreadRunning()) | |||
@@ -661,28 +657,66 @@ struct IldaeilWidget : ImGuiWidget, Thread { | |||
void onContextCreate(const ContextCreateEvent& e) override | |||
{ | |||
ImGuiWidget::onContextCreate(e); | |||
widgetCreated(); | |||
} | |||
if (module == nullptr || module->pcontext == nullptr || module->fCarlaHostHandle == nullptr) | |||
return; | |||
void onContextDestroy(const ContextDestroyEvent& e) override | |||
{ | |||
widgetDestroyed(); | |||
ImGuiWidget::onContextDestroy(e); | |||
} | |||
char winIdStr[24]; | |||
std::snprintf(winIdStr, sizeof(winIdStr), "%lx", (ulong)module->pcontext->nativeWindowId); | |||
carla_set_engine_option(module->fCarlaHostHandle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, winIdStr); | |||
void onAdd(const AddEvent& e) override | |||
{ | |||
ImGuiWidget::onAdd(e); | |||
widgetCreated(); | |||
} | |||
void onContextDestroy(const ContextDestroyEvent& e) override | |||
void onRemove(const RemoveEvent& e) override | |||
{ | |||
if (module != nullptr && module->fCarlaHostHandle != nullptr) | |||
carla_set_engine_option(module->fCarlaHostHandle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, "0"); | |||
widgetDestroyed(); | |||
ImGuiWidget::onRemove(e); | |||
} | |||
ImGuiWidget::onContextDestroy(e); | |||
void widgetCreated() | |||
{ | |||
if (const CarlaHostHandle handle = module->fCarlaHostHandle) | |||
{ | |||
CardinalPluginContext* const pcontext = module->pcontext; | |||
char winIdStr[24]; | |||
std::snprintf(winIdStr, sizeof(winIdStr), "%llx", (ulonglong)pcontext->nativeWindowId); | |||
module->fCarlaHostDescriptor.uiParentId = pcontext->nativeWindowId; | |||
carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, winIdStr); | |||
if (pcontext->window != nullptr) | |||
carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_UI_SCALE, pcontext->window->pixelRatio*1000, nullptr); | |||
if (! idleCallbackActive) | |||
idleCallbackActive = pcontext->addIdleCallback(this); | |||
} | |||
} | |||
void step() override | |||
void widgetDestroyed() | |||
{ | |||
ImGuiWidget::step(); | |||
setDirty(true); | |||
if (const CarlaHostHandle handle = module->fCarlaHostHandle) | |||
{ | |||
CardinalPluginContext* const pcontext = module->pcontext; | |||
module->fCarlaHostDescriptor.uiParentId = 0; | |||
carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, "0"); | |||
if (idleCallbackActive) | |||
{ | |||
idleCallbackActive = false; | |||
pcontext->removeIdleCallback(this); | |||
} | |||
} | |||
} | |||
void idleCallback() override | |||
{ | |||
switch (fDrawingState) | |||
{ | |||
case kDrawingInit: | |||
@@ -20,6 +20,10 @@ | |||
#include "plugin.hpp" | |||
#include "DistrhoUtils.hpp" | |||
#ifndef HEADLESS | |||
# include "dgl/Base.hpp" | |||
#endif | |||
// ----------------------------------------------------------------------------------------------------------- | |||
// from PluginContext.hpp | |||
@@ -44,6 +48,10 @@ struct CardinalPluginContext : rack::Context { | |||
float** dataOuts; | |||
Plugin* const plugin; | |||
CardinalPluginContext(Plugin* const p); | |||
#ifndef HEADLESS | |||
bool addIdleCallback(IdleCallback* cb); | |||
void removeIdleCallback(IdleCallback* cb); | |||
#endif | |||
}; | |||
END_NAMESPACE_DISTRHO | |||
@@ -56,6 +56,25 @@ START_NAMESPACE_DISTRHO | |||
// ----------------------------------------------------------------------------------------------------------- | |||
bool CardinalPluginContext::addIdleCallback(IdleCallback* const cb) | |||
{ | |||
if (ui == nullptr) | |||
return false; | |||
ui->addIdleCallback(cb); | |||
return true; | |||
} | |||
void CardinalPluginContext::removeIdleCallback(IdleCallback* const cb) | |||
{ | |||
if (ui == nullptr) | |||
return; | |||
ui->removeIdleCallback(cb); | |||
} | |||
// ----------------------------------------------------------------------------------------------------------- | |||
class CardinalUI : public CardinalBaseUI, | |||
public WindowParametersCallback | |||
{ | |||
@@ -54,6 +54,9 @@ struct CardinalPluginContext : rack::Context { | |||
const float** dataIns; | |||
float** dataOuts; | |||
Plugin* const plugin; | |||
#ifndef HEADLESS | |||
UI* ui; | |||
#endif | |||
CardinalPluginContext(Plugin* const p) | |||
: bufferSize(p->getBufferSize()), | |||
@@ -79,9 +82,17 @@ struct CardinalPluginContext : rack::Context { | |||
dataIns(nullptr), | |||
dataOuts(nullptr), | |||
plugin(p) | |||
#ifndef HEADLESS | |||
, ui(nullptr) | |||
#endif | |||
{ | |||
std::memset(parameters, 0, sizeof(parameters)); | |||
} | |||
#ifndef HEADLESS | |||
bool addIdleCallback(IdleCallback* cb); | |||
void removeIdleCallback(IdleCallback* cb); | |||
#endif | |||
}; | |||
// ----------------------------------------------------------------------------------------------------------- | |||
@@ -121,8 +132,14 @@ public: | |||
CardinalBaseUI(const uint width, const uint height) | |||
: UI(width, height), | |||
context(getRackContextFromPlugin(getPluginInstancePointer())), | |||
saving(false) {} | |||
~CardinalBaseUI() override {} | |||
saving(false) | |||
{ | |||
context->ui = this; | |||
} | |||
~CardinalBaseUI() override | |||
{ | |||
context->ui = nullptr; | |||
} | |||
}; | |||
#endif | |||