|
|
@@ -79,23 +79,12 @@ class IldaeilUI : public UI, |
|
|
|
public Thread, |
|
|
|
public PluginHostWindow::Callbacks |
|
|
|
{ |
|
|
|
static constexpr const uint kInitialWidth = 1220; |
|
|
|
static constexpr const uint kInitialHeight = 640; |
|
|
|
static constexpr const uint kGenericWidth = 360; |
|
|
|
static constexpr const uint kInitialWidth = 520; |
|
|
|
static constexpr const uint kInitialHeight = 520; |
|
|
|
static constexpr const uint kGenericWidth = 380; |
|
|
|
static constexpr const uint kGenericHeight = 400; |
|
|
|
static constexpr const uint kButtonHeight = 20; |
|
|
|
|
|
|
|
enum { |
|
|
|
kDrawingInit, |
|
|
|
kDrawingErrorInit, |
|
|
|
kDrawingErrorDraw, |
|
|
|
kDrawingLoading, |
|
|
|
kDrawingPluginList, |
|
|
|
kDrawingPluginEmbedUI, |
|
|
|
kDrawingPluginGenericUI, |
|
|
|
kDrawingPluginPendingFromInit |
|
|
|
} fDrawingState; |
|
|
|
|
|
|
|
struct PluginInfoCache { |
|
|
|
char* name; |
|
|
|
char* label; |
|
|
@@ -116,13 +105,13 @@ class IldaeilUI : public UI, |
|
|
|
uint parameterCount; |
|
|
|
struct Parameter { |
|
|
|
char* name; |
|
|
|
char* format; |
|
|
|
char* printformat; |
|
|
|
uint32_t rindex; |
|
|
|
bool boolean, bvalue, log; |
|
|
|
bool boolean, bvalue, log, readonly; |
|
|
|
float min, max, power; |
|
|
|
Parameter() |
|
|
|
: name(nullptr), |
|
|
|
format(nullptr), |
|
|
|
printformat(nullptr), |
|
|
|
rindex(0), |
|
|
|
boolean(false), |
|
|
|
bvalue(false), |
|
|
@@ -132,7 +121,7 @@ class IldaeilUI : public UI, |
|
|
|
~Parameter() |
|
|
|
{ |
|
|
|
std::free(name); |
|
|
|
std::free(format); |
|
|
|
std::free(printformat); |
|
|
|
} |
|
|
|
}* parameters; |
|
|
|
float* values; |
|
|
@@ -151,15 +140,42 @@ class IldaeilUI : public UI, |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
enum { |
|
|
|
kDrawingLoading, |
|
|
|
kDrawingPluginError, |
|
|
|
kDrawingPluginList, |
|
|
|
kDrawingPluginEmbedUI, |
|
|
|
kDrawingPluginGenericUI, |
|
|
|
kDrawingErrorInit, |
|
|
|
kDrawingErrorDraw |
|
|
|
} fDrawingState; |
|
|
|
|
|
|
|
enum { |
|
|
|
kIdleInit, |
|
|
|
kIdleInitPluginAlreadyLoaded, |
|
|
|
kIdleLoadSelectedPlugin, |
|
|
|
kIdlePluginLoadedFromDSP, |
|
|
|
kIdleResetPlugin, |
|
|
|
kIdleShowCustomUI, |
|
|
|
kIdleHideEmbedAndShowGenericUI, |
|
|
|
kIdleHidePluginUI, |
|
|
|
kIdleGiveIdleToUI, |
|
|
|
kIdleChangePluginType, |
|
|
|
kIdleNothing |
|
|
|
} fIdleState = kIdleInit; |
|
|
|
|
|
|
|
IldaeilPlugin* const fPlugin; |
|
|
|
PluginHostWindow fPluginHostWindow; |
|
|
|
|
|
|
|
PluginType fPluginType; |
|
|
|
PluginType fNextPluginType; |
|
|
|
uint fPluginCount; |
|
|
|
uint fPluginSelected; |
|
|
|
int fPluginSelected; |
|
|
|
bool fPluginScanningFinished; |
|
|
|
bool fPluginHasCustomUI; |
|
|
|
bool fPluginHasEmbedUI; |
|
|
|
bool fPluginHasOutputParameters; |
|
|
|
bool fPluginRunning; |
|
|
|
bool fPluginWillRunInBridgeMode; |
|
|
|
PluginInfoCache* fPlugins; |
|
|
|
ScopedPointer<PluginGenericUI> fPluginGenericUI; |
|
|
@@ -176,15 +192,19 @@ public: |
|
|
|
IldaeilUI() |
|
|
|
: UI(kInitialWidth, kInitialHeight), |
|
|
|
Thread("IldaeilScanner"), |
|
|
|
fDrawingState(kDrawingInit), |
|
|
|
fDrawingState(kDrawingLoading), |
|
|
|
fIdleState(kIdleInit), |
|
|
|
fPlugin((IldaeilPlugin*)getPluginInstancePointer()), |
|
|
|
fPluginHostWindow(getWindow(), this), |
|
|
|
fPluginType(PLUGIN_LV2), |
|
|
|
fNextPluginType(fPluginType), |
|
|
|
fPluginCount(0), |
|
|
|
fPluginSelected(0), |
|
|
|
fPluginSelected(-1), |
|
|
|
fPluginScanningFinished(false), |
|
|
|
fPluginHasCustomUI(false), |
|
|
|
fPluginHasEmbedUI(false), |
|
|
|
fPluginHasOutputParameters(false), |
|
|
|
fPluginRunning(false), |
|
|
|
fPluginWillRunInBridgeMode(false), |
|
|
|
fPlugins(nullptr), |
|
|
|
fPluginSearchActive(false), |
|
|
@@ -195,6 +215,7 @@ public: |
|
|
|
if (fPlugin == nullptr || fPlugin->fCarlaHostHandle == nullptr) |
|
|
|
{ |
|
|
|
fDrawingState = kDrawingErrorInit; |
|
|
|
fIdleState = kIdleNothing; |
|
|
|
fPopupError = "Ildaeil backend failed to init properly, cannot continue."; |
|
|
|
setSize(kInitialWidth * scaleFactor * 0.5, kInitialHeight * scaleFactor * 0.5); |
|
|
|
return; |
|
|
@@ -225,15 +246,10 @@ public: |
|
|
|
char winIdStr[24]; |
|
|
|
std::snprintf(winIdStr, sizeof(winIdStr), "%lx", (ulong)getWindow().getNativeWindowHandle()); |
|
|
|
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); |
|
|
|
carla_set_engine_option(handle, ENGINE_OPTION_FRONTEND_UI_SCALE, scaleFactor*1000, nullptr); |
|
|
|
|
|
|
|
if (carla_get_current_plugin_count(handle) != 0) |
|
|
|
{ |
|
|
|
const uint hints = carla_get_plugin_info(handle, 0)->hints; |
|
|
|
fDrawingState = kDrawingPluginPendingFromInit; |
|
|
|
fPluginHasCustomUI = hints & PLUGIN_HAS_CUSTOM_UI; |
|
|
|
fPluginHasEmbedUI = hints & PLUGIN_HAS_CUSTOM_EMBED_UI; |
|
|
|
} |
|
|
|
if (checkIfPluginIsLoaded()) |
|
|
|
fIdleState = kIdleInitPluginAlreadyLoaded; |
|
|
|
|
|
|
|
fPlugin->fUI = this; |
|
|
|
} |
|
|
@@ -243,19 +259,43 @@ public: |
|
|
|
if (fPlugin != nullptr && fPlugin->fCarlaHostHandle != nullptr) |
|
|
|
{ |
|
|
|
fPlugin->fUI = nullptr; |
|
|
|
|
|
|
|
if (fPluginRunning) |
|
|
|
hidePluginUI(fPlugin->fCarlaHostHandle); |
|
|
|
|
|
|
|
carla_set_engine_option(fPlugin->fCarlaHostHandle, ENGINE_OPTION_FRONTEND_WIN_ID, 0, "0"); |
|
|
|
} |
|
|
|
|
|
|
|
if (isThreadRunning()) |
|
|
|
stopThread(-1); |
|
|
|
|
|
|
|
hidePluginUI(); |
|
|
|
|
|
|
|
fPluginGenericUI = nullptr; |
|
|
|
|
|
|
|
delete[] fPlugins; |
|
|
|
} |
|
|
|
|
|
|
|
bool checkIfPluginIsLoaded() |
|
|
|
{ |
|
|
|
const CarlaHostHandle handle = fPlugin->fCarlaHostHandle; |
|
|
|
|
|
|
|
if (carla_get_current_plugin_count(handle) != 0) |
|
|
|
{ |
|
|
|
const uint hints = carla_get_plugin_info(handle, 0)->hints; |
|
|
|
fPluginHasCustomUI = hints & PLUGIN_HAS_CUSTOM_UI; |
|
|
|
fPluginHasEmbedUI = hints & PLUGIN_HAS_CUSTOM_EMBED_UI; |
|
|
|
fPluginRunning = true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
void projectLoadedFromDSP() |
|
|
|
{ |
|
|
|
if (checkIfPluginIsLoaded()) |
|
|
|
fIdleState = kIdlePluginLoadedFromDSP; |
|
|
|
} |
|
|
|
|
|
|
|
void changeParameterFromDSP(const uint32_t index, const float value) |
|
|
|
{ |
|
|
|
if (PluginGenericUI* const ui = fPluginGenericUI) |
|
|
@@ -273,53 +313,72 @@ public: |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
repaint(); |
|
|
|
} |
|
|
|
|
|
|
|
const char* openFileFromDSP(const bool /*isDir*/, const char* const title, const char* const /*filter*/) |
|
|
|
{ |
|
|
|
DISTRHO_SAFE_ASSERT_RETURN(fPluginType == PLUGIN_INTERNAL || fPluginType == PLUGIN_LV2, nullptr); |
|
|
|
|
|
|
|
Window::FileBrowserOptions opts; |
|
|
|
opts.title = title; |
|
|
|
getWindow().openFileBrowser(opts); |
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
|
|
|
|
void showPluginUI(const CarlaHostHandle handle) |
|
|
|
void showPluginUI(const CarlaHostHandle handle, const bool showIfNotEmbed) |
|
|
|
{ |
|
|
|
const CarlaPluginInfo* const info = carla_get_plugin_info(handle, 0); |
|
|
|
|
|
|
|
if (info->hints & PLUGIN_HAS_CUSTOM_EMBED_UI) |
|
|
|
{ |
|
|
|
fDrawingState = kDrawingPluginEmbedUI; |
|
|
|
fIdleState = kIdleGiveIdleToUI; |
|
|
|
fPluginHasCustomUI = true; |
|
|
|
fPluginHasEmbedUI = true; |
|
|
|
|
|
|
|
carla_embed_custom_ui(handle, 0, fPluginHostWindow.attachAndGetWindowHandle()); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
fDrawingState = kDrawingPluginGenericUI; |
|
|
|
fPluginHasCustomUI = info->hints & PLUGIN_HAS_CUSTOM_UI; |
|
|
|
fPluginHasEmbedUI = false; |
|
|
|
if (fPluginGenericUI == nullptr) |
|
|
|
createPluginGenericUI(handle, info); |
|
|
|
else |
|
|
|
updatePluginGenericUI(handle); |
|
|
|
ImGuiStyle& style(ImGui::GetStyle()); |
|
|
|
const double scaleFactor = getScaleFactor(); |
|
|
|
fNextSize = Size<uint>(kGenericWidth * scaleFactor, (kGenericHeight + style.FramePadding.x) * scaleFactor); |
|
|
|
createOrUpdatePluginGenericUI(handle); |
|
|
|
|
|
|
|
if (showIfNotEmbed && fPluginHasCustomUI) |
|
|
|
{ |
|
|
|
fIdleState = kIdleGiveIdleToUI; |
|
|
|
carla_show_custom_ui(handle, 0, true); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
repaint(); |
|
|
|
} |
|
|
|
|
|
|
|
void hidePluginUI() |
|
|
|
void hidePluginUI(const CarlaHostHandle handle) |
|
|
|
{ |
|
|
|
if (fPlugin == nullptr || fPlugin->fCarlaHostHandle == nullptr) |
|
|
|
return; |
|
|
|
DISTRHO_SAFE_ASSERT_RETURN(fPluginRunning,); |
|
|
|
|
|
|
|
fPluginHostWindow.hide(); |
|
|
|
carla_show_custom_ui(handle, 0, false); |
|
|
|
} |
|
|
|
|
|
|
|
void createOrUpdatePluginGenericUI(const CarlaHostHandle handle, const CarlaPluginInfo* info = nullptr) |
|
|
|
{ |
|
|
|
if (info == nullptr) |
|
|
|
info = carla_get_plugin_info(handle, 0); |
|
|
|
|
|
|
|
fDrawingState = kDrawingPluginGenericUI; |
|
|
|
fPluginHasCustomUI = info->hints & PLUGIN_HAS_CUSTOM_UI; |
|
|
|
fPluginHasEmbedUI = info->hints & PLUGIN_HAS_CUSTOM_EMBED_UI; |
|
|
|
|
|
|
|
if (fPluginGenericUI == nullptr) |
|
|
|
createPluginGenericUI(handle, info); |
|
|
|
else |
|
|
|
updatePluginGenericUI(handle); |
|
|
|
|
|
|
|
if (fDrawingState == kDrawingPluginGenericUI || fDrawingState == kDrawingPluginEmbedUI) |
|
|
|
carla_show_custom_ui(fPlugin->fCarlaHostHandle, 0, false); |
|
|
|
ImGuiStyle& style(ImGui::GetStyle()); |
|
|
|
const double scaleFactor = getScaleFactor(); |
|
|
|
fNextSize = Size<uint>(kGenericWidth * scaleFactor, (kGenericHeight + style.FramePadding.x) * scaleFactor); |
|
|
|
} |
|
|
|
|
|
|
|
void createPluginGenericUI(const CarlaHostHandle handle, const CarlaPluginInfo* const info) |
|
|
@@ -338,13 +397,14 @@ public: |
|
|
|
{ |
|
|
|
const ParameterData* const pdata = carla_get_parameter_data(handle, 0, i); |
|
|
|
|
|
|
|
if (pdata->type != PARAMETER_INPUT || |
|
|
|
(pdata->hints & PARAMETER_IS_ENABLED) == 0x0 || |
|
|
|
(pdata->hints & PARAMETER_IS_READ_ONLY) != 0x0) |
|
|
|
if ((pdata->hints & PARAMETER_IS_ENABLED) == 0x0) |
|
|
|
{ |
|
|
|
--ui->parameterCount; |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
if (pdata->type == PARAMETER_OUTPUT) |
|
|
|
fPluginHasOutputParameters = true; |
|
|
|
} |
|
|
|
|
|
|
|
ui->parameters = new PluginGenericUI::Parameter[ui->parameterCount]; |
|
|
@@ -355,31 +415,31 @@ public: |
|
|
|
{ |
|
|
|
const ParameterData* const pdata = carla_get_parameter_data(handle, 0, i); |
|
|
|
|
|
|
|
if (pdata->type != PARAMETER_INPUT || |
|
|
|
(pdata->hints & PARAMETER_IS_ENABLED) == 0x0 || |
|
|
|
(pdata->hints & PARAMETER_IS_READ_ONLY) != 0x0) |
|
|
|
if ((pdata->hints & PARAMETER_IS_ENABLED) == 0x0) |
|
|
|
continue; |
|
|
|
|
|
|
|
const CarlaParameterInfo* const pinfo = carla_get_parameter_info(handle, 0, i); |
|
|
|
const ::ParameterRanges* const pranges = carla_get_parameter_ranges(handle, 0, i); |
|
|
|
|
|
|
|
String format; |
|
|
|
String printformat; |
|
|
|
|
|
|
|
if (pdata->hints & PARAMETER_IS_INTEGER) |
|
|
|
format = "%.0f "; |
|
|
|
printformat = "%.0f "; |
|
|
|
else |
|
|
|
format = "%.3f "; |
|
|
|
printformat = "%.3f "; |
|
|
|
|
|
|
|
format += pinfo->unit; |
|
|
|
printformat += pinfo->unit; |
|
|
|
|
|
|
|
PluginGenericUI::Parameter& param(ui->parameters[j]); |
|
|
|
param.name = strdup(pinfo->name); |
|
|
|
param.format = format.getAndReleaseBuffer(); |
|
|
|
param.printformat = printformat.getAndReleaseBuffer(); |
|
|
|
param.rindex = i; |
|
|
|
param.boolean = pdata->hints & PARAMETER_IS_BOOLEAN; |
|
|
|
param.log = pdata->hints & PARAMETER_IS_LOGARITHMIC; |
|
|
|
param.readonly = pdata->type != PARAMETER_INPUT || (pdata->hints & PARAMETER_IS_READ_ONLY); |
|
|
|
param.min = pranges->min; |
|
|
|
param.max = pranges->max; |
|
|
|
|
|
|
|
ui->values[j] = carla_get_current_parameter_value(handle, 0, i); |
|
|
|
|
|
|
|
if (param.boolean) |
|
|
@@ -407,31 +467,34 @@ public: |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
bool loadPlugin(const CarlaHostHandle handle, const char* const label) |
|
|
|
void loadPlugin(const CarlaHostHandle handle, const char* const label) |
|
|
|
{ |
|
|
|
if (carla_get_current_plugin_count(handle) != 0) |
|
|
|
if (fPluginRunning) |
|
|
|
{ |
|
|
|
hidePluginUI(); |
|
|
|
hidePluginUI(handle); |
|
|
|
carla_replace_plugin(handle, 0); |
|
|
|
} |
|
|
|
|
|
|
|
carla_set_engine_option(handle, ENGINE_OPTION_PREFER_PLUGIN_BRIDGES, fPluginWillRunInBridgeMode, nullptr); |
|
|
|
|
|
|
|
// xx cardinal |
|
|
|
// const MutexLocker cml(sPluginInfoLoadMutex); |
|
|
|
|
|
|
|
if (carla_add_plugin(handle, BINARY_NATIVE, fPluginType, nullptr, nullptr, |
|
|
|
label, 0, 0x0, PLUGIN_OPTIONS_NULL)) |
|
|
|
{ |
|
|
|
fPluginRunning = true; |
|
|
|
fPluginGenericUI = nullptr; |
|
|
|
showPluginUI(handle); |
|
|
|
return true; |
|
|
|
showPluginUI(handle, false); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
fPopupError = carla_get_last_error(handle); |
|
|
|
d_stdout("got error: %s", fPopupError.buffer()); |
|
|
|
ImGui::OpenPopup("Plugin Error"); |
|
|
|
fDrawingState = kDrawingPluginError; |
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
repaint(); |
|
|
|
} |
|
|
|
|
|
|
|
protected: |
|
|
@@ -443,38 +506,117 @@ protected: |
|
|
|
|
|
|
|
void uiIdle() override |
|
|
|
{ |
|
|
|
switch (fDrawingState) |
|
|
|
const CarlaHostHandle handle = fPlugin->fCarlaHostHandle; |
|
|
|
DISTRHO_SAFE_ASSERT_RETURN(handle != nullptr,); |
|
|
|
|
|
|
|
// carla_juce_idle(); |
|
|
|
|
|
|
|
if (fDrawingState == kDrawingPluginGenericUI && fPluginGenericUI != nullptr && fPluginHasOutputParameters) |
|
|
|
{ |
|
|
|
case kDrawingInit: |
|
|
|
fDrawingState = kDrawingLoading; |
|
|
|
startThread(); |
|
|
|
updatePluginGenericUI(handle); |
|
|
|
repaint(); |
|
|
|
} |
|
|
|
|
|
|
|
if (fNextSize.isValid()) |
|
|
|
{ |
|
|
|
setSize(fNextSize); |
|
|
|
fNextSize = Size<uint>(); |
|
|
|
} |
|
|
|
|
|
|
|
switch (fIdleState) |
|
|
|
{ |
|
|
|
case kIdleInit: |
|
|
|
fIdleState = kIdleNothing; |
|
|
|
startThread(); |
|
|
|
break; |
|
|
|
|
|
|
|
case kDrawingPluginPendingFromInit: |
|
|
|
showPluginUI(fPlugin->fCarlaHostHandle); |
|
|
|
case kIdleInitPluginAlreadyLoaded: |
|
|
|
fIdleState = kIdleNothing; |
|
|
|
showPluginUI(handle, false); |
|
|
|
startThread(); |
|
|
|
break; |
|
|
|
|
|
|
|
case kDrawingPluginEmbedUI: |
|
|
|
case kIdlePluginLoadedFromDSP: |
|
|
|
fIdleState = kIdleNothing; |
|
|
|
showPluginUI(handle, false); |
|
|
|
break; |
|
|
|
|
|
|
|
case kIdleLoadSelectedPlugin: |
|
|
|
fIdleState = kIdleNothing; |
|
|
|
loadSelectedPlugin(handle); |
|
|
|
break; |
|
|
|
|
|
|
|
case kIdleResetPlugin: |
|
|
|
fIdleState = kIdleNothing; |
|
|
|
loadPlugin(handle, carla_get_plugin_info(handle, 0)->label); |
|
|
|
break; |
|
|
|
|
|
|
|
case kIdleShowCustomUI: |
|
|
|
fIdleState = kIdleNothing; |
|
|
|
showPluginUI(handle, true); |
|
|
|
break; |
|
|
|
|
|
|
|
case kIdleHideEmbedAndShowGenericUI: |
|
|
|
fIdleState = kIdleNothing; |
|
|
|
hidePluginUI(handle); |
|
|
|
createOrUpdatePluginGenericUI(handle); |
|
|
|
break; |
|
|
|
|
|
|
|
case kIdleHidePluginUI: |
|
|
|
fIdleState = kIdleNothing; |
|
|
|
carla_show_custom_ui(handle, 0, false); |
|
|
|
break; |
|
|
|
|
|
|
|
case kIdleGiveIdleToUI: |
|
|
|
fPlugin->fCarlaPluginDescriptor->ui_idle(fPlugin->fCarlaPluginHandle); |
|
|
|
fPluginHostWindow.idle(); |
|
|
|
break; |
|
|
|
|
|
|
|
case kDrawingPluginGenericUI: |
|
|
|
fPlugin->fCarlaPluginDescriptor->ui_idle(fPlugin->fCarlaPluginHandle); |
|
|
|
case kIdleChangePluginType: |
|
|
|
fIdleState = kIdleNothing; |
|
|
|
hidePluginUI(handle); |
|
|
|
fPluginSelected = -1; |
|
|
|
if (isThreadRunning()) |
|
|
|
stopThread(-1); |
|
|
|
fPluginType = fNextPluginType; |
|
|
|
startThread(); |
|
|
|
break; |
|
|
|
|
|
|
|
default: |
|
|
|
case kIdleNothing: |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (fNextSize.isValid()) |
|
|
|
void loadSelectedPlugin(const CarlaHostHandle handle) |
|
|
|
{ |
|
|
|
DISTRHO_SAFE_ASSERT_RETURN(fPluginSelected >= 0,); |
|
|
|
|
|
|
|
const PluginInfoCache& info(fPlugins[fPluginSelected]); |
|
|
|
|
|
|
|
const char* label = nullptr; |
|
|
|
|
|
|
|
switch (fPluginType) |
|
|
|
{ |
|
|
|
setSize(fNextSize); |
|
|
|
fNextSize = Size<uint>(); |
|
|
|
return; |
|
|
|
case PLUGIN_INTERNAL: |
|
|
|
case PLUGIN_AU: |
|
|
|
// case PLUGIN_JSFX: |
|
|
|
case PLUGIN_SFZ: |
|
|
|
label = info.label; |
|
|
|
break; |
|
|
|
case PLUGIN_LV2: { |
|
|
|
const char* const slash = std::strchr(info.label, DISTRHO_OS_SEP); |
|
|
|
DISTRHO_SAFE_ASSERT_RETURN(slash != nullptr,); |
|
|
|
label = slash+1; |
|
|
|
break; |
|
|
|
} |
|
|
|
default: |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
DISTRHO_SAFE_ASSERT_RETURN(label != nullptr,); |
|
|
|
|
|
|
|
d_stdout("Loading %s...", info.name); |
|
|
|
loadPlugin(handle, label); |
|
|
|
} |
|
|
|
|
|
|
|
void uiFileBrowserSelected(const char* const filename) override |
|
|
@@ -486,7 +628,6 @@ protected: |
|
|
|
void run() override |
|
|
|
{ |
|
|
|
const char* path; |
|
|
|
|
|
|
|
switch (fPluginType) |
|
|
|
{ |
|
|
|
case PLUGIN_LV2: |
|
|
@@ -496,23 +637,29 @@ protected: |
|
|
|
path = nullptr; |
|
|
|
break; |
|
|
|
} |
|
|
|
/* TESTING |
|
|
|
const char* const path = "/home/falktx/bin/reaper_linux_x86_64/REAPER/InstallData/Effects"; |
|
|
|
*/ |
|
|
|
|
|
|
|
if (path != nullptr) |
|
|
|
carla_set_engine_option(fPlugin->fCarlaHostHandle, ENGINE_OPTION_PLUGIN_PATH, fPluginType, path); |
|
|
|
|
|
|
|
if (const uint count = carla_get_cached_plugin_count(fPluginType, path)) |
|
|
|
fPluginCount = 0; |
|
|
|
delete[] fPlugins; |
|
|
|
|
|
|
|
// xx cardinal |
|
|
|
// const MutexLocker cml(sPluginInfoLoadMutex); |
|
|
|
|
|
|
|
d_stdout("Will scan plugins now..."); |
|
|
|
const uint count = carla_get_cached_plugin_count(fPluginType, path); |
|
|
|
d_stdout("Scanning found %u plugins", count); |
|
|
|
|
|
|
|
if (fDrawingState == kDrawingLoading) |
|
|
|
{ |
|
|
|
fPluginCount = 0; |
|
|
|
fPlugins = new PluginInfoCache[count]; |
|
|
|
fDrawingState = kDrawingPluginList; |
|
|
|
fPluginSearchFirstShow = true; |
|
|
|
} |
|
|
|
|
|
|
|
if (fDrawingState == kDrawingLoading) |
|
|
|
{ |
|
|
|
fDrawingState = kDrawingPluginList; |
|
|
|
fPluginSearchFirstShow = true; |
|
|
|
} |
|
|
|
if (count != 0) |
|
|
|
{ |
|
|
|
fPlugins = new PluginInfoCache[count]; |
|
|
|
|
|
|
|
for (uint i=0, j; i < count && ! shouldThreadExit(); ++i) |
|
|
|
{ |
|
|
@@ -537,6 +684,22 @@ protected: |
|
|
|
continue; |
|
|
|
#endif |
|
|
|
|
|
|
|
if (fPluginType == PLUGIN_INTERNAL) |
|
|
|
{ |
|
|
|
if (std::strcmp(info->label, "audiogain_s") == 0) |
|
|
|
continue; |
|
|
|
if (std::strcmp(info->label, "cv2audio") == 0) |
|
|
|
continue; |
|
|
|
if (std::strcmp(info->label, "lfo") == 0) |
|
|
|
continue; |
|
|
|
if (std::strcmp(info->label, "midi2cv") == 0) |
|
|
|
continue; |
|
|
|
if (std::strcmp(info->label, "midithrough") == 0) |
|
|
|
continue; |
|
|
|
if (std::strcmp(info->label, "3bandsplitter") == 0) |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
j = fPluginCount; |
|
|
|
fPlugins[j].name = strdup(info->name); |
|
|
|
fPlugins[j].label = strdup(info->label); |
|
|
@@ -545,11 +708,7 @@ protected: |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
String error("There are no "); |
|
|
|
error += getPluginTypeAsString(fPluginType); |
|
|
|
error += " audio plugins on this system."; |
|
|
|
fPopupError = error; |
|
|
|
fDrawingState = kDrawingErrorInit; |
|
|
|
fPlugins = nullptr; |
|
|
|
} |
|
|
|
|
|
|
|
if (! shouldThreadExit()) |
|
|
@@ -560,14 +719,25 @@ protected: |
|
|
|
{ |
|
|
|
switch (fDrawingState) |
|
|
|
{ |
|
|
|
case kDrawingInit: |
|
|
|
case kDrawingLoading: |
|
|
|
case kDrawingPluginPendingFromInit: |
|
|
|
drawLoading(); |
|
|
|
break; |
|
|
|
case kDrawingPluginError: |
|
|
|
ImGui::OpenPopup("Plugin Error"); |
|
|
|
// call ourselves again with the plugin list |
|
|
|
fDrawingState = kDrawingPluginList; |
|
|
|
onImGuiDisplay(); |
|
|
|
break; |
|
|
|
case kDrawingPluginList: |
|
|
|
drawPluginList(); |
|
|
|
break; |
|
|
|
case kDrawingPluginGenericUI: |
|
|
|
drawTopBar(); |
|
|
|
drawGenericUI(); |
|
|
|
break; |
|
|
|
case kDrawingPluginEmbedUI: |
|
|
|
drawTopBar(); |
|
|
|
break; |
|
|
|
case kDrawingErrorInit: |
|
|
|
fDrawingState = kDrawingErrorDraw; |
|
|
|
drawError(true); |
|
|
@@ -575,12 +745,6 @@ protected: |
|
|
|
case kDrawingErrorDraw: |
|
|
|
drawError(false); |
|
|
|
break; |
|
|
|
case kDrawingPluginGenericUI: |
|
|
|
drawGenericUI(); |
|
|
|
// fall-through |
|
|
|
case kDrawingPluginEmbedUI: |
|
|
|
drawTopBar(); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -594,8 +758,7 @@ protected: |
|
|
|
| ImGuiWindowFlags_NoResize |
|
|
|
| ImGuiWindowFlags_NoCollapse |
|
|
|
| ImGuiWindowFlags_NoScrollbar |
|
|
|
| ImGuiWindowFlags_NoScrollWithMouse |
|
|
|
| ImGuiWindowFlags_NoCollapse; |
|
|
|
| ImGuiWindowFlags_NoScrollWithMouse; |
|
|
|
|
|
|
|
if (ImGui::Begin("Error Window", nullptr, flags)) |
|
|
|
{ |
|
|
@@ -607,7 +770,6 @@ protected: |
|
|
|
| ImGuiWindowFlags_NoCollapse |
|
|
|
| ImGuiWindowFlags_NoScrollbar |
|
|
|
| ImGuiWindowFlags_NoScrollWithMouse |
|
|
|
| ImGuiWindowFlags_NoCollapse |
|
|
|
| ImGuiWindowFlags_AlwaysAutoResize |
|
|
|
| ImGuiWindowFlags_AlwaysUseWindowPadding; |
|
|
|
|
|
|
@@ -633,16 +795,13 @@ protected: |
|
|
|
| ImGuiWindowFlags_NoResize |
|
|
|
| ImGuiWindowFlags_NoCollapse |
|
|
|
| ImGuiWindowFlags_NoScrollbar |
|
|
|
| ImGuiWindowFlags_NoScrollWithMouse |
|
|
|
| ImGuiWindowFlags_NoCollapse; |
|
|
|
| ImGuiWindowFlags_NoScrollWithMouse; |
|
|
|
|
|
|
|
if (ImGui::Begin("Current Plugin", nullptr, flags)) |
|
|
|
{ |
|
|
|
const CarlaHostHandle handle = fPlugin->fCarlaHostHandle; |
|
|
|
|
|
|
|
if (ImGui::Button("Pick Another...")) |
|
|
|
{ |
|
|
|
hidePluginUI(); |
|
|
|
fIdleState = kIdleHidePluginUI; |
|
|
|
fDrawingState = kDrawingPluginList; |
|
|
|
|
|
|
|
const double scaleFactor = getScaleFactor(); |
|
|
@@ -652,29 +811,14 @@ protected: |
|
|
|
ImGui::SameLine(); |
|
|
|
|
|
|
|
if (ImGui::Button("Reset")) |
|
|
|
{ |
|
|
|
loadPlugin(handle, carla_get_plugin_info(handle, 0)->label); |
|
|
|
} |
|
|
|
fIdleState = kIdleResetPlugin; |
|
|
|
|
|
|
|
if (fDrawingState == kDrawingPluginGenericUI && fPluginHasCustomUI) |
|
|
|
{ |
|
|
|
ImGui::SameLine(); |
|
|
|
|
|
|
|
if (ImGui::Button("Show Custom GUI")) |
|
|
|
{ |
|
|
|
if (fPluginHasEmbedUI) |
|
|
|
{ |
|
|
|
fDrawingState = kDrawingPluginEmbedUI; |
|
|
|
carla_embed_custom_ui(handle, 0, fPluginHostWindow.attachAndGetWindowHandle()); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
carla_show_custom_ui(handle, 0, true); |
|
|
|
} |
|
|
|
|
|
|
|
ImGui::End(); |
|
|
|
return; |
|
|
|
} |
|
|
|
fIdleState = kIdleShowCustomUI; |
|
|
|
} |
|
|
|
|
|
|
|
if (fDrawingState == kDrawingPluginEmbedUI) |
|
|
@@ -682,20 +826,7 @@ protected: |
|
|
|
ImGui::SameLine(); |
|
|
|
|
|
|
|
if (ImGui::Button("Show Generic GUI")) |
|
|
|
{ |
|
|
|
hidePluginUI(); |
|
|
|
fDrawingState = kDrawingPluginGenericUI; |
|
|
|
|
|
|
|
if (fPluginGenericUI == nullptr) |
|
|
|
createPluginGenericUI(handle, carla_get_plugin_info(handle, 0)); |
|
|
|
else |
|
|
|
updatePluginGenericUI(handle); |
|
|
|
|
|
|
|
const double scaleFactor = getScaleFactor(); |
|
|
|
const double padding = ImGui::GetStyle().WindowPadding.y * 2; |
|
|
|
fNextSize = Size<uint>(std::max(getWidth(), static_cast<uint>(kGenericWidth * scaleFactor + 0.5)), |
|
|
|
(kGenericHeight + kButtonHeight) * scaleFactor + padding); |
|
|
|
} |
|
|
|
fIdleState = kIdleHideEmbedAndShowGenericUI; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -704,12 +835,14 @@ protected: |
|
|
|
|
|
|
|
void setupMainWindowPos() |
|
|
|
{ |
|
|
|
const float scaleFactor = getScaleFactor(); |
|
|
|
|
|
|
|
float y = 0; |
|
|
|
float height = getHeight(); |
|
|
|
|
|
|
|
if (fDrawingState == kDrawingPluginGenericUI) |
|
|
|
{ |
|
|
|
y = kButtonHeight * getScaleFactor() + ImGui::GetStyle().WindowPadding.y * 2 - 1; |
|
|
|
y = kButtonHeight * scaleFactor + ImGui::GetStyle().WindowPadding.y * 2 - scaleFactor; |
|
|
|
height -= y; |
|
|
|
} |
|
|
|
|
|
|
@@ -724,9 +857,12 @@ protected: |
|
|
|
PluginGenericUI* const ui = fPluginGenericUI; |
|
|
|
DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); |
|
|
|
|
|
|
|
// ImGui::SetNextWindowFocus(); |
|
|
|
const int pflags = ImGuiWindowFlags_NoSavedSettings |
|
|
|
| ImGuiWindowFlags_NoResize |
|
|
|
| ImGuiWindowFlags_NoCollapse |
|
|
|
| ImGuiWindowFlags_AlwaysAutoResize; |
|
|
|
|
|
|
|
if (ImGui::Begin(ui->title, nullptr, ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoCollapse)) |
|
|
|
if (ImGui::Begin(ui->title, nullptr, pflags)) |
|
|
|
{ |
|
|
|
const CarlaHostHandle handle = fPlugin->fCarlaHostHandle; |
|
|
|
|
|
|
@@ -734,6 +870,14 @@ protected: |
|
|
|
{ |
|
|
|
PluginGenericUI::Parameter& param(ui->parameters[i]); |
|
|
|
|
|
|
|
if (param.readonly) |
|
|
|
{ |
|
|
|
ImGui::BeginDisabled(); |
|
|
|
ImGui::SliderFloat(param.name, &ui->values[i], param.min, param.max, param.printformat, ImGuiSliderFlags_NoInput); |
|
|
|
ImGui::EndDisabled(); |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
if (param.boolean) |
|
|
|
{ |
|
|
|
if (ImGui::Checkbox(param.name, &ui->parameters[i].bvalue)) |
|
|
@@ -752,8 +896,8 @@ protected: |
|
|
|
else |
|
|
|
{ |
|
|
|
const bool ret = param.log |
|
|
|
? ImGui::SliderFloat(param.name, &ui->values[i], param.min, param.max, param.format, 2.0f) |
|
|
|
: ImGui::SliderFloat(param.name, &ui->values[i], param.min, param.max, param.format); |
|
|
|
? ImGui::SliderFloat(param.name, &ui->values[i], param.min, param.max, param.printformat, 2.0f) |
|
|
|
: ImGui::SliderFloat(param.name, &ui->values[i], param.min, param.max, param.printformat); |
|
|
|
if (ret) |
|
|
|
{ |
|
|
|
if (ImGui::IsItemActivated()) |
|
|
@@ -783,18 +927,19 @@ protected: |
|
|
|
setupMainWindowPos(); |
|
|
|
|
|
|
|
if (ImGui::Begin("Plugin List", nullptr, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize)) |
|
|
|
{ |
|
|
|
ImGui::TextUnformatted("Loading...", nullptr); |
|
|
|
} |
|
|
|
|
|
|
|
ImGui::End(); |
|
|
|
} |
|
|
|
|
|
|
|
void drawPluginList() |
|
|
|
{ |
|
|
|
setupMainWindowPos(); |
|
|
|
static const char* pluginTypes[] = { |
|
|
|
getPluginTypeAsString(PLUGIN_INTERNAL), |
|
|
|
getPluginTypeAsString(PLUGIN_LV2), |
|
|
|
}; |
|
|
|
|
|
|
|
const CarlaHostHandle handle = fPlugin->fCarlaHostHandle; |
|
|
|
setupMainWindowPos(); |
|
|
|
|
|
|
|
if (ImGui::Begin("Plugin List", nullptr, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize)) |
|
|
|
{ |
|
|
@@ -803,9 +948,7 @@ protected: |
|
|
|
| ImGuiWindowFlags_NoCollapse |
|
|
|
| ImGuiWindowFlags_NoScrollbar |
|
|
|
| ImGuiWindowFlags_NoScrollWithMouse |
|
|
|
| ImGuiWindowFlags_NoCollapse |
|
|
|
| ImGuiWindowFlags_AlwaysAutoResize |
|
|
|
| ImGuiWindowFlags_AlwaysUseWindowPadding; |
|
|
|
| ImGuiWindowFlags_AlwaysAutoResize; |
|
|
|
|
|
|
|
if (ImGui::BeginPopupModal("Plugin Error", nullptr, pflags)) |
|
|
|
{ |
|
|
@@ -814,9 +957,7 @@ protected: |
|
|
|
ImGui::Separator(); |
|
|
|
|
|
|
|
if (ImGui::Button("Ok")) |
|
|
|
{ |
|
|
|
ImGui::CloseCurrentPopup(); |
|
|
|
} |
|
|
|
|
|
|
|
ImGui::SameLine(); |
|
|
|
ImGui::Dummy(ImVec2(500 * getScaleFactor(), 1)); |
|
|
@@ -828,85 +969,81 @@ protected: |
|
|
|
ImGui::SetKeyboardFocusHere(); |
|
|
|
} |
|
|
|
|
|
|
|
if (ImGui::InputText("", fPluginSearchString, sizeof(fPluginSearchString)-1, ImGuiInputTextFlags_CharsNoBlank|ImGuiInputTextFlags_AutoSelectAll)) |
|
|
|
if (ImGui::InputText("##pluginsearch", fPluginSearchString, sizeof(fPluginSearchString)-1, |
|
|
|
ImGuiInputTextFlags_CharsNoBlank|ImGuiInputTextFlags_AutoSelectAll)) |
|
|
|
fPluginSearchActive = true; |
|
|
|
|
|
|
|
if (ImGui::IsKeyDown(ImGuiKey_Escape)) |
|
|
|
fPluginSearchActive = false; |
|
|
|
|
|
|
|
ImGui::BeginDisabled(!fPluginScanningFinished); |
|
|
|
ImGui::SameLine(); |
|
|
|
ImGui::PushItemWidth(-1.0f); |
|
|
|
|
|
|
|
if (ImGui::Button("Load Plugin")) |
|
|
|
int current; |
|
|
|
switch (fPluginType) |
|
|
|
{ |
|
|
|
do { |
|
|
|
const PluginInfoCache& info(fPlugins[fPluginSelected]); |
|
|
|
|
|
|
|
const char* label = nullptr; |
|
|
|
case PLUGIN_LV2: |
|
|
|
current = 1; |
|
|
|
break; |
|
|
|
default: |
|
|
|
current = 0; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
switch (fPluginType) |
|
|
|
{ |
|
|
|
case PLUGIN_INTERNAL: |
|
|
|
case PLUGIN_JSFX: |
|
|
|
case PLUGIN_SFZ: |
|
|
|
label = info.label; |
|
|
|
break; |
|
|
|
case PLUGIN_LV2: { |
|
|
|
const char* const slash = std::strchr(info.label, DISTRHO_OS_SEP); |
|
|
|
DISTRHO_SAFE_ASSERT_BREAK(slash != nullptr); |
|
|
|
label = slash+1; |
|
|
|
break; |
|
|
|
} |
|
|
|
default: |
|
|
|
break; |
|
|
|
} |
|
|
|
if (ImGui::Combo("##plugintypes", ¤t, pluginTypes, ARRAY_SIZE(pluginTypes))) |
|
|
|
{ |
|
|
|
fIdleState = kIdleChangePluginType; |
|
|
|
switch (current) |
|
|
|
{ |
|
|
|
case 0: |
|
|
|
fNextPluginType = PLUGIN_INTERNAL; |
|
|
|
break; |
|
|
|
case 1: |
|
|
|
fNextPluginType = PLUGIN_LV2; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
DISTRHO_SAFE_ASSERT_BREAK(label != nullptr); |
|
|
|
ImGui::BeginDisabled(!fPluginScanningFinished || fPluginSelected < 0); |
|
|
|
|
|
|
|
d_stdout("Loading %s...", info.name); |
|
|
|
if (ImGui::Button("Load Plugin")) |
|
|
|
fIdleState = kIdleLoadSelectedPlugin; |
|
|
|
|
|
|
|
if (loadPlugin(handle, label)) |
|
|
|
{ |
|
|
|
ImGui::EndDisabled(); |
|
|
|
ImGui::End(); |
|
|
|
return; |
|
|
|
} |
|
|
|
} while (false); |
|
|
|
// xx cardinal |
|
|
|
if (fPluginType != PLUGIN_INTERNAL /*&& module->canUseBridges*/) |
|
|
|
{ |
|
|
|
ImGui::SameLine(); |
|
|
|
ImGui::Checkbox("Run in bridge mode", &fPluginWillRunInBridgeMode); |
|
|
|
} |
|
|
|
|
|
|
|
ImGui::SameLine(); |
|
|
|
ImGui::Checkbox("Run in bridge mode", &fPluginWillRunInBridgeMode); |
|
|
|
ImGui::EndDisabled(); |
|
|
|
|
|
|
|
if (carla_get_current_plugin_count(handle) != 0) |
|
|
|
if (fPluginRunning) |
|
|
|
{ |
|
|
|
ImGui::SameLine(); |
|
|
|
|
|
|
|
if (ImGui::Button("Cancel")) |
|
|
|
{ |
|
|
|
showPluginUI(handle); |
|
|
|
} |
|
|
|
fIdleState = kIdleShowCustomUI; |
|
|
|
} |
|
|
|
|
|
|
|
ImGui::EndDisabled(); |
|
|
|
|
|
|
|
if (ImGui::BeginChild("pluginlistwindow")) |
|
|
|
{ |
|
|
|
if (ImGui::BeginTable("pluginlist", |
|
|
|
fPluginType == PLUGIN_LV2 ? 3 : 2, ImGuiTableFlags_NoSavedSettings)) |
|
|
|
if (ImGui::BeginTable("pluginlist", 2, ImGuiTableFlags_NoSavedSettings)) |
|
|
|
{ |
|
|
|
const char* const search = fPluginSearchActive && fPluginSearchString[0] != '\0' ? fPluginSearchString : nullptr; |
|
|
|
|
|
|
|
switch (fPluginType) |
|
|
|
{ |
|
|
|
case PLUGIN_INTERNAL: |
|
|
|
case PLUGIN_JSFX: |
|
|
|
case PLUGIN_AU: |
|
|
|
case PLUGIN_SFZ: |
|
|
|
// case PLUGIN_JSFX: |
|
|
|
ImGui::TableSetupColumn("Name"); |
|
|
|
ImGui::TableSetupColumn("Label"); |
|
|
|
ImGui::TableHeadersRow(); |
|
|
|
break; |
|
|
|
case PLUGIN_LV2: |
|
|
|
ImGui::TableSetupColumn("Name"); |
|
|
|
ImGui::TableSetupColumn("Bundle"); |
|
|
|
ImGui::TableSetupColumn("URI"); |
|
|
|
ImGui::TableHeadersRow(); |
|
|
|
break; |
|
|
@@ -921,12 +1058,13 @@ protected: |
|
|
|
if (search != nullptr && ildaeil::strcasestr(info.name, search) == nullptr) |
|
|
|
continue; |
|
|
|
|
|
|
|
bool selected = fPluginSelected == i; |
|
|
|
bool selected = fPluginSelected >= 0 && static_cast<uint>(fPluginSelected) == i; |
|
|
|
|
|
|
|
switch (fPluginType) |
|
|
|
{ |
|
|
|
case PLUGIN_INTERNAL: |
|
|
|
case PLUGIN_JSFX: |
|
|
|
case PLUGIN_AU: |
|
|
|
// case PLUGIN_JSFX: |
|
|
|
case PLUGIN_SFZ: |
|
|
|
ImGui::TableNextRow(); |
|
|
|
ImGui::TableSetColumnIndex(0); |
|
|
@@ -942,8 +1080,6 @@ protected: |
|
|
|
ImGui::Selectable(info.name, &selected); |
|
|
|
ImGui::TableSetColumnIndex(1); |
|
|
|
ImGui::Selectable(slash+1, &selected); |
|
|
|
ImGui::TableSetColumnIndex(2); |
|
|
|
ImGui::TextUnformatted(info.label, slash); |
|
|
|
break; |
|
|
|
} |
|
|
|
default: |
|
|
@@ -974,7 +1110,7 @@ protected: |
|
|
|
void stateChanged(const char* const key, const char* const) override |
|
|
|
{ |
|
|
|
if (std::strcmp(key, "project") == 0) |
|
|
|
hidePluginUI(); |
|
|
|
hidePluginUI(fPlugin->fCarlaHostHandle); |
|
|
|
} |
|
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------------- |
|
|
|