Signed-off-by: falkTX <falktx@falktx.com>tags/v2.1-rc1
@@ -862,7 +862,7 @@ public: | |||||
* Returned variable must be deleted if non-null. | * Returned variable must be deleted if non-null. | ||||
* @see ENGINE_CALLBACK_PLUGIN_RENAMED | * @see ENGINE_CALLBACK_PLUGIN_RENAMED | ||||
*/ | */ | ||||
virtual const char* renamePlugin(const uint id, const char* const newName); | |||||
virtual bool renamePlugin(const uint id, const char* const newName); | |||||
/*! | /*! | ||||
* Clone plugin with id @a id. | * Clone plugin with id @a id. | ||||
@@ -880,6 +880,15 @@ public: | |||||
* Switch plugins with id @a idA and @a idB. | * Switch plugins with id @a idA and @a idB. | ||||
*/ | */ | ||||
bool switchPlugins(const uint idA, const uint idB) noexcept; | bool switchPlugins(const uint idA, const uint idB) noexcept; | ||||
/*! | |||||
* Set a plugin's parameter in drag/touch mode. | |||||
* Usually happens from a UI when the user is moving a parameter with a mouse or similar input. | |||||
* | |||||
* @param parameterId The parameter to update | |||||
* @param touch The new state for the parameter | |||||
*/ | |||||
virtual void touchPluginParameter(const uint id, const uint32_t parameterId, const bool touch) noexcept; | |||||
#endif | #endif | ||||
/*! | /*! | ||||
@@ -542,7 +542,7 @@ CARLA_EXPORT bool carla_remove_all_plugins(); | |||||
* @param pluginId Plugin to rename | * @param pluginId Plugin to rename | ||||
* @param newName New plugin name | * @param newName New plugin name | ||||
*/ | */ | ||||
CARLA_EXPORT const char* carla_rename_plugin(uint pluginId, const char* newName); | |||||
CARLA_EXPORT bool carla_rename_plugin(uint pluginId, const char* newName); | |||||
/*! | /*! | ||||
* Clone a plugin. | * Clone a plugin. | ||||
@@ -879,6 +879,15 @@ CARLA_EXPORT void carla_set_parameter_midi_channel(uint pluginId, uint32_t param | |||||
* @param cc New MIDI cc | * @param cc New MIDI cc | ||||
*/ | */ | ||||
CARLA_EXPORT void carla_set_parameter_midi_cc(uint pluginId, uint32_t parameterId, int16_t cc); | CARLA_EXPORT void carla_set_parameter_midi_cc(uint pluginId, uint32_t parameterId, int16_t cc); | ||||
/*! | |||||
* Change a plugin's parameter in drag/touch mode state. | |||||
* Usually happens from a UI when the user is moving a parameter with a mouse or similar input. | |||||
* @param pluginId Plugin | |||||
* @param parameterId Parameter index | |||||
* @param touch New state | |||||
*/ | |||||
CARLA_EXPORT void carla_set_parameter_touch(uint pluginId, uint32_t parameterId, bool touch); | |||||
#endif | #endif | ||||
/*! | /*! | ||||
@@ -954,10 +954,10 @@ bool carla_remove_all_plugins() | |||||
} | } | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
const char* carla_rename_plugin(uint pluginId, const char* newName) | |||||
bool carla_rename_plugin(uint pluginId, const char* newName) | |||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(newName != nullptr && newName[0] != '\0', nullptr); | |||||
CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(gStandalone.engine != nullptr, "Engine is not initialized", nullptr); | |||||
CARLA_SAFE_ASSERT_RETURN(newName != nullptr && newName[0] != '\0', false); | |||||
CARLA_SAFE_ASSERT_WITH_LAST_ERROR_RETURN(gStandalone.engine != nullptr, "Engine is not initialized", false); | |||||
carla_debug("carla_rename_plugin(%i, \"%s\")", pluginId, newName); | carla_debug("carla_rename_plugin(%i, \"%s\")", pluginId, newName); | ||||
@@ -1812,6 +1812,14 @@ void carla_set_parameter_midi_cc(uint pluginId, uint32_t parameterId, int16_t cc | |||||
return plugin->setParameterMidiCC(parameterId, cc, true, false); | return plugin->setParameterMidiCC(parameterId, cc, true, false); | ||||
} | } | ||||
void carla_set_parameter_touch(uint pluginId, uint32_t parameterId, bool touch) | |||||
{ | |||||
CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr,); | |||||
carla_debug("carla_set_parameter_touch(%i, %i, %s)", pluginId, parameterId, bool2str(touch)); | |||||
return gStandalone.engine->touchPluginParameter(pluginId, parameterId, touch); | |||||
} | |||||
#endif | #endif | ||||
// -------------------------------------------------------------------------------------------------------------------- | // -------------------------------------------------------------------------------------------------------------------- | ||||
@@ -752,30 +752,32 @@ bool CarlaEngine::removeAllPlugins() | |||||
} | } | ||||
#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH | ||||
const char* CarlaEngine::renamePlugin(const uint id, const char* const newName) | |||||
bool CarlaEngine::renamePlugin(const uint id, const char* const newName) | |||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN_ERRN(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish"); | |||||
CARLA_SAFE_ASSERT_RETURN_ERRN(pData->plugins != nullptr, "Invalid engine internal data"); | |||||
CARLA_SAFE_ASSERT_RETURN_ERRN(pData->curPluginCount != 0, "Invalid engine internal data"); | |||||
CARLA_SAFE_ASSERT_RETURN_ERRN(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data"); | |||||
CARLA_SAFE_ASSERT_RETURN_ERRN(id < pData->curPluginCount, "Invalid plugin Id"); | |||||
CARLA_SAFE_ASSERT_RETURN_ERRN(newName != nullptr && newName[0] != '\0', "Invalid plugin name"); | |||||
CARLA_SAFE_ASSERT_RETURN_ERR(pData->isIdling == 0, "An operation is still being processed, please wait for it to finish"); | |||||
CARLA_SAFE_ASSERT_RETURN_ERR(pData->plugins != nullptr, "Invalid engine internal data"); | |||||
CARLA_SAFE_ASSERT_RETURN_ERR(pData->curPluginCount != 0, "Invalid engine internal data"); | |||||
CARLA_SAFE_ASSERT_RETURN_ERR(pData->nextAction.opcode == kEnginePostActionNull, "Invalid engine internal data"); | |||||
CARLA_SAFE_ASSERT_RETURN_ERR(id < pData->curPluginCount, "Invalid plugin Id"); | |||||
CARLA_SAFE_ASSERT_RETURN_ERR(newName != nullptr && newName[0] != '\0', "Invalid plugin name"); | |||||
carla_debug("CarlaEngine::renamePlugin(%i, \"%s\")", id, newName); | carla_debug("CarlaEngine::renamePlugin(%i, \"%s\")", id, newName); | ||||
CarlaPlugin* const plugin(pData->plugins[id].plugin); | CarlaPlugin* const plugin(pData->plugins[id].plugin); | ||||
CARLA_SAFE_ASSERT_RETURN_ERRN(plugin != nullptr, "Could not find plugin to rename"); | |||||
CARLA_SAFE_ASSERT_RETURN_ERRN(plugin->getId() == id, "Invalid engine internal data"); | |||||
CARLA_SAFE_ASSERT_RETURN_ERR(plugin != nullptr, "Could not find plugin to rename"); | |||||
CARLA_SAFE_ASSERT_RETURN_ERR(plugin->getId() == id, "Invalid engine internal data"); | |||||
const char* const uniqueName(getUniquePluginName(newName)); | const char* const uniqueName(getUniquePluginName(newName)); | ||||
CARLA_SAFE_ASSERT_RETURN_ERRN(uniqueName != nullptr, "Unable to get new unique plugin name"); | |||||
CARLA_SAFE_ASSERT_RETURN_ERR(uniqueName != nullptr, "Unable to get new unique plugin name"); | |||||
plugin->setName(uniqueName); | plugin->setName(uniqueName); | ||||
if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | ||||
pData->graph.renamePlugin(plugin, uniqueName); | pData->graph.renamePlugin(plugin, uniqueName); | ||||
callback(true, true, ENGINE_CALLBACK_PLUGIN_RENAMED, id, 0, 0, 0, 0.0f, uniqueName); | |||||
delete[] uniqueName; | delete[] uniqueName; | ||||
return plugin->getName(); | |||||
return true; | |||||
} | } | ||||
bool CarlaEngine::clonePlugin(const uint id) | bool CarlaEngine::clonePlugin(const uint id) | ||||
@@ -875,6 +877,10 @@ bool CarlaEngine::switchPlugins(const uint idA, const uint idB) noexcept | |||||
return true; | return true; | ||||
} | } | ||||
void CarlaEngine::touchPluginParameter(const uint, const uint32_t, const bool) noexcept | |||||
{ | |||||
} | |||||
#endif | #endif | ||||
CarlaPlugin* CarlaEngine::getPlugin(const uint id) const noexcept | CarlaPlugin* CarlaEngine::getPlugin(const uint id) const noexcept | ||||
@@ -1357,7 +1357,7 @@ public: | |||||
} | } | ||||
#ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
const char* renamePlugin(const uint id, const char* const newName) override | |||||
bool renamePlugin(const uint id, const char* const newName) override | |||||
{ | { | ||||
if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || | if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || | ||||
pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | ||||
@@ -1365,14 +1365,14 @@ public: | |||||
return CarlaEngine::renamePlugin(id, newName); | return CarlaEngine::renamePlugin(id, newName); | ||||
} | } | ||||
CARLA_SAFE_ASSERT_RETURN(pData->plugins != nullptr, nullptr); | |||||
CARLA_SAFE_ASSERT_RETURN(pData->curPluginCount != 0, nullptr); | |||||
CARLA_SAFE_ASSERT_RETURN(id < pData->curPluginCount, nullptr); | |||||
CARLA_SAFE_ASSERT_RETURN(newName != nullptr && newName[0] != '\0', nullptr); | |||||
CARLA_SAFE_ASSERT_RETURN(pData->plugins != nullptr, false); | |||||
CARLA_SAFE_ASSERT_RETURN(pData->curPluginCount != 0, false); | |||||
CARLA_SAFE_ASSERT_RETURN(id < pData->curPluginCount, false); | |||||
CARLA_SAFE_ASSERT_RETURN(newName != nullptr && newName[0] != '\0', false); | |||||
CarlaPlugin* const plugin(pData->plugins[id].plugin); | CarlaPlugin* const plugin(pData->plugins[id].plugin); | ||||
CARLA_SAFE_ASSERT_RETURN_ERRN(plugin != nullptr, "Could not find plugin to rename"); | |||||
CARLA_SAFE_ASSERT_RETURN_ERRN(plugin->getId() == id, "Invalid engine internal data"); | |||||
CARLA_SAFE_ASSERT_RETURN_ERR(plugin != nullptr, "Could not find plugin to rename"); | |||||
CARLA_SAFE_ASSERT_RETURN_ERR(plugin->getId() == id, "Invalid engine internal data"); | |||||
// before we stop the engine thread we might need to get the plugin data | // before we stop the engine thread we might need to get the plugin data | ||||
const bool needsReinit = (pData->options.processMode == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS); | const bool needsReinit = (pData->options.processMode == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS); | ||||
@@ -1395,7 +1395,7 @@ public: | |||||
if (uniqueName.isEmpty()) | if (uniqueName.isEmpty()) | ||||
{ | { | ||||
setLastError("Failed to request new unique plugin name"); | setLastError("Failed to request new unique plugin name"); | ||||
return nullptr; | |||||
return false; | |||||
} | } | ||||
const ScopedThreadStopper sts(this); | const ScopedThreadStopper sts(this); | ||||
@@ -1408,7 +1408,7 @@ public: | |||||
if (! client->renameInSingleClient(uniqueName)) | if (! client->renameInSingleClient(uniqueName)) | ||||
{ | { | ||||
setLastError("Failed to rename some JACK ports, does your JACK version support proper port renaming?"); | setLastError("Failed to rename some JACK ports, does your JACK version support proper port renaming?"); | ||||
return nullptr; | |||||
return false; | |||||
} | } | ||||
} | } | ||||
// rename in multiple client mode | // rename in multiple client mode | ||||
@@ -1493,7 +1493,7 @@ public: | |||||
else | else | ||||
{ | { | ||||
setLastError("Failed to create new JACK client"); | setLastError("Failed to create new JACK client"); | ||||
return nullptr; | |||||
return false; | |||||
} | } | ||||
} | } | ||||
@@ -1508,7 +1508,7 @@ public: | |||||
plugin->setEnabled(true); | plugin->setEnabled(true); | ||||
} | } | ||||
return plugin->getName(); | |||||
return true; | |||||
} | } | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
@@ -331,15 +331,10 @@ public: | |||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
const char* renamePlugin(const uint id, const char* const newName) override | |||||
void touchPluginParameter(const uint id, const uint32_t parameterId, const bool touch) noexcept override | |||||
{ | { | ||||
if (const char* const retName = CarlaEngine::renamePlugin(id, newName)) | |||||
{ | |||||
uiServerCallback(ENGINE_CALLBACK_PLUGIN_RENAMED, id, 0, 0, 0, 0.0f, retName); | |||||
return retName; | |||||
} | |||||
return nullptr; | |||||
carla_stdout("engineNative touchPluginParameter %u %u %s", id, parameterId, bool2str(touch)); | |||||
setParameterTouchFromUI(id, parameterId, touch); | |||||
} | } | ||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
@@ -353,6 +348,15 @@ public: | |||||
pHost->ui_parameter_changed(pHost->handle, index, value); | pHost->ui_parameter_changed(pHost->handle, index, value); | ||||
} | } | ||||
void setParameterTouchFromUI(const uint32_t pluginId, const uint32_t index, const bool touch) | |||||
{ | |||||
if (pluginId != 0) | |||||
return; | |||||
carla_stdout("engineNative setParameterTouchFromUI %u %u %s", pluginId,index, bool2str(touch)); | |||||
pHost->ui_parameter_touch(pHost->handle, index, touch); | |||||
} | |||||
void reloadFromUI() | void reloadFromUI() | ||||
{ | { | ||||
carla_zeroFloats(fParameters, kNumInParams+kNumOutParams); | carla_zeroFloats(fParameters, kNumInParams+kNumOutParams); | ||||
@@ -1927,8 +1931,7 @@ bool CarlaEngineNativeUI::msgReceived(const char*const msg) noexcept | |||||
CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true); | CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true); | ||||
CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(newName), true); | CARLA_SAFE_ASSERT_RETURN(readNextLineAsString(newName), true); | ||||
// TODO | |||||
/*const char* name =*/ fEngine->renamePlugin(pluginId, newName); | |||||
ok = fEngine->renamePlugin(pluginId, newName); | |||||
delete[] newName; | delete[] newName; | ||||
} | } | ||||
@@ -2119,6 +2122,18 @@ bool CarlaEngineNativeUI::msgReceived(const char*const msg) noexcept | |||||
if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId)) | if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId)) | ||||
plugin->setParameterMidiCC(parameterId, static_cast<int16_t>(cc), true, false); | plugin->setParameterMidiCC(parameterId, static_cast<int16_t>(cc), true, false); | ||||
} | } | ||||
else if (std::strcmp(msg, "set_parameter_touch") == 0) | |||||
{ | |||||
uint32_t pluginId, parameterId; | |||||
bool touching; | |||||
CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(pluginId), true); | |||||
CARLA_SAFE_ASSERT_RETURN(readNextLineAsUInt(parameterId), true); | |||||
CARLA_SAFE_ASSERT_RETURN(readNextLineAsBool(touching), true); | |||||
if (fEngine->getPlugin(pluginId) != nullptr) | |||||
fEngine->setParameterTouchFromUI(pluginId, parameterId, touching); | |||||
} | |||||
else if (std::strcmp(msg, "set_program") == 0) | else if (std::strcmp(msg, "set_program") == 0) | ||||
{ | { | ||||
uint32_t pluginId; | uint32_t pluginId; | ||||
@@ -1159,8 +1159,19 @@ protected: | |||||
pData->engine->callback(true, true, ENGINE_CALLBACK_UPDATE, pData->id, 0, 0, 0, 0.0f, nullptr); | pData->engine->callback(true, true, ENGINE_CALLBACK_UPDATE, pData->id, 0, 0, 0, 0.0f, nullptr); | ||||
} | } | ||||
void audioProcessorParameterChangeGestureBegin(juce::AudioProcessor*, int) override {} | |||||
void audioProcessorParameterChangeGestureEnd(juce::AudioProcessor*, int) override {} | |||||
void audioProcessorParameterChangeGestureBegin(juce::AudioProcessor*, int index) override | |||||
{ | |||||
CARLA_SAFE_ASSERT_RETURN(index >= 0,); | |||||
pData->engine->touchPluginParameter(pData->id, static_cast<uint32_t>(index), true); | |||||
} | |||||
void audioProcessorParameterChangeGestureEnd(juce::AudioProcessor*, int index) override | |||||
{ | |||||
CARLA_SAFE_ASSERT_RETURN(index >= 0,); | |||||
pData->engine->touchPluginParameter(pData->id, static_cast<uint32_t>(index), false); | |||||
} | |||||
bool getCurrentPosition(CurrentPositionInfo& result) override | bool getCurrentPosition(CurrentPositionInfo& result) override | ||||
{ | { | ||||
@@ -615,6 +615,9 @@ public: | |||||
if (fFeatures[kFeatureIdUiResize] != nullptr && fFeatures[kFeatureIdUiResize]->data != nullptr) | if (fFeatures[kFeatureIdUiResize] != nullptr && fFeatures[kFeatureIdUiResize]->data != nullptr) | ||||
delete (LV2UI_Resize*)fFeatures[kFeatureIdUiResize]->data; | delete (LV2UI_Resize*)fFeatures[kFeatureIdUiResize]->data; | ||||
if (fFeatures[kFeatureIdUiTouch] != nullptr && fFeatures[kFeatureIdUiTouch]->data != nullptr) | |||||
delete (LV2UI_Touch*)fFeatures[kFeatureIdUiTouch]->data; | |||||
if (fFeatures[kFeatureIdExternalUi] != nullptr && fFeatures[kFeatureIdExternalUi]->data != nullptr) | if (fFeatures[kFeatureIdExternalUi] != nullptr && fFeatures[kFeatureIdExternalUi]->data != nullptr) | ||||
delete (LV2_External_UI_Host*)fFeatures[kFeatureIdExternalUi]->data; | delete (LV2_External_UI_Host*)fFeatures[kFeatureIdExternalUi]->data; | ||||
@@ -5109,6 +5112,25 @@ public: | |||||
return 0; | return 0; | ||||
} | } | ||||
void handleUITouch(const uint32_t rindex, const bool touch) | |||||
{ | |||||
carla_stdout("CarlaPluginLV2::handleUITouch(%u, %s)", rindex, bool2str(touch)); | |||||
uint32_t index = LV2UI_INVALID_PORT_INDEX; | |||||
for (uint32_t i=0; i < pData->param.count; ++i) | |||||
{ | |||||
if (pData->param.data[i].rindex != static_cast<int32_t>(rindex)) | |||||
continue; | |||||
index = i; | |||||
break; | |||||
} | |||||
CARLA_SAFE_ASSERT_RETURN(index != LV2UI_INVALID_PORT_INDEX,); | |||||
pData->engine->touchPluginParameter(pData->id, index, touch); | |||||
} | |||||
void handleUIWrite(const uint32_t rindex, const uint32_t bufferSize, const uint32_t format, const void* const buffer) | void handleUIWrite(const uint32_t rindex, const uint32_t bufferSize, const uint32_t format, const void* const buffer) | ||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(buffer != nullptr,); | CARLA_SAFE_ASSERT_RETURN(buffer != nullptr,); | ||||
@@ -6048,6 +6070,10 @@ public: | |||||
uiResizeFt->handle = this; | uiResizeFt->handle = this; | ||||
uiResizeFt->ui_resize = carla_lv2_ui_resize; | uiResizeFt->ui_resize = carla_lv2_ui_resize; | ||||
LV2UI_Touch* const uiTouchFt = new LV2UI_Touch; | |||||
uiTouchFt->handle = this; | |||||
uiTouchFt->touch = carla_lv2_ui_touch; | |||||
LV2_External_UI_Host* const uiExternalHostFt = new LV2_External_UI_Host; | LV2_External_UI_Host* const uiExternalHostFt = new LV2_External_UI_Host; | ||||
uiExternalHostFt->ui_closed = carla_lv2_external_ui_closed; | uiExternalHostFt->ui_closed = carla_lv2_external_ui_closed; | ||||
uiExternalHostFt->plugin_human_id = fLv2Options.windowTitle; | uiExternalHostFt->plugin_human_id = fLv2Options.windowTitle; | ||||
@@ -6092,7 +6118,7 @@ public: | |||||
fFeatures[kFeatureIdUiResize]->data = uiResizeFt; | fFeatures[kFeatureIdUiResize]->data = uiResizeFt; | ||||
fFeatures[kFeatureIdUiTouch]->URI = LV2_UI__touch; | fFeatures[kFeatureIdUiTouch]->URI = LV2_UI__touch; | ||||
fFeatures[kFeatureIdUiTouch]->data = nullptr; | |||||
fFeatures[kFeatureIdUiTouch]->data = uiTouchFt; | |||||
fFeatures[kFeatureIdExternalUi]->URI = LV2_EXTERNAL_UI__Host; | fFeatures[kFeatureIdExternalUi]->URI = LV2_EXTERNAL_UI__Host; | ||||
fFeatures[kFeatureIdExternalUi]->data = uiExternalHostFt; | fFeatures[kFeatureIdExternalUi]->data = uiExternalHostFt; | ||||
@@ -6770,6 +6796,17 @@ private: | |||||
return ((CarlaPluginLV2*)handle)->handleUIResize(width, height); | return ((CarlaPluginLV2*)handle)->handleUIResize(width, height); | ||||
} | } | ||||
// ------------------------------------------------------------------- | |||||
// UI Touch Feature | |||||
static void carla_lv2_ui_touch(LV2UI_Feature_Handle handle, uint32_t port_index, bool touch) | |||||
{ | |||||
CARLA_SAFE_ASSERT_RETURN(handle != nullptr,); | |||||
carla_debug("carla_lv2_ui_touch(%p, %u, %s)", handle, port_index, bool2str(touch)); | |||||
((CarlaPluginLV2*)handle)->handleUITouch(port_index, touch); | |||||
} | |||||
// ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
// UI Extension | // UI Extension | ||||
@@ -279,6 +279,7 @@ public: | |||||
fHost.get_time_info = carla_host_get_time_info; | fHost.get_time_info = carla_host_get_time_info; | ||||
fHost.write_midi_event = carla_host_write_midi_event; | fHost.write_midi_event = carla_host_write_midi_event; | ||||
fHost.ui_parameter_changed = carla_host_ui_parameter_changed; | fHost.ui_parameter_changed = carla_host_ui_parameter_changed; | ||||
fHost.ui_parameter_touch = carla_host_ui_parameter_touch; | |||||
fHost.ui_custom_data_changed = carla_host_ui_custom_data_changed; | fHost.ui_custom_data_changed = carla_host_ui_custom_data_changed; | ||||
fHost.ui_closed = carla_host_ui_closed; | fHost.ui_closed = carla_host_ui_closed; | ||||
fHost.ui_open_file = carla_host_ui_open_file; | fHost.ui_open_file = carla_host_ui_open_file; | ||||
@@ -2393,6 +2394,12 @@ protected: | |||||
setParameterValue(index, value, false, true, true); | setParameterValue(index, value, false, true, true); | ||||
} | } | ||||
void handleUiParameterTouch(const uint32_t index, const bool touch) const | |||||
{ | |||||
carla_stdout("pluginNative handleUiParameterTouch %u %s", index, bool2str(touch)); | |||||
pData->engine->touchPluginParameter(pData->id, index, touch); | |||||
} | |||||
void handleUiCustomDataChanged(const char* const key, const char* const value) | void handleUiCustomDataChanged(const char* const key, const char* const value) | ||||
{ | { | ||||
setCustomData(CUSTOM_DATA_TYPE_STRING, key, value, false); | setCustomData(CUSTOM_DATA_TYPE_STRING, key, value, false); | ||||
@@ -2696,6 +2703,11 @@ private: | |||||
handlePtr->handleUiParameterChanged(index, value); | handlePtr->handleUiParameterChanged(index, value); | ||||
} | } | ||||
static void carla_host_ui_parameter_touch(NativeHostHandle handle, uint32_t index, bool touch) | |||||
{ | |||||
handlePtr->handleUiParameterTouch(index, touch); | |||||
} | |||||
static void carla_host_ui_custom_data_changed(NativeHostHandle handle, const char* key, const char* value) | static void carla_host_ui_custom_data_changed(NativeHostHandle handle, const char* key, const char* value) | ||||
{ | { | ||||
handlePtr->handleUiCustomDataChanged(key, value); | handlePtr->handleUiCustomDataChanged(key, value); | ||||
@@ -2197,8 +2197,15 @@ protected: | |||||
break; | break; | ||||
case audioMasterBeginEdit: | case audioMasterBeginEdit: | ||||
CARLA_SAFE_ASSERT_BREAK(index > 0); | |||||
carla_stdout("audioMasterBeginEdit %i", index); | |||||
pData->engine->touchPluginParameter(pData->id, static_cast<uint32_t>(index), true); | |||||
break; | |||||
case audioMasterEndEdit: | case audioMasterEndEdit: | ||||
// TODO | |||||
CARLA_SAFE_ASSERT_BREAK(index > 0); | |||||
carla_stdout("audioMasterEndEdit %i", index); | |||||
pData->engine->touchPluginParameter(pData->id, static_cast<uint32_t>(index), false); | |||||
break; | break; | ||||
case audioMasterOpenFileSelector: | case audioMasterOpenFileSelector: | ||||
@@ -1904,6 +1904,15 @@ class CarlaHostMeta(object): | |||||
def set_parameter_midi_cc(self, pluginId, parameterId, cc): | def set_parameter_midi_cc(self, pluginId, parameterId, cc): | ||||
raise NotImplementedError | raise NotImplementedError | ||||
# Change a plugin's parameter in drag/touch mode state. | |||||
# Usually happens from a UI when the user is moving a parameter with a mouse or similar input. | |||||
# @param pluginId Plugin | |||||
# @param parameterId Parameter index | |||||
# @param touch New state | |||||
@abstractmethod | |||||
def set_parameter_touch(self, pluginId, parameterId, touch): | |||||
raise NotImplementedError | |||||
# Change a plugin's current program. | # Change a plugin's current program. | ||||
# @param pluginId Plugin | # @param pluginId Plugin | ||||
# @param programId New program | # @param programId New program | ||||
@@ -2133,7 +2142,7 @@ class CarlaHostNull(CarlaHostMeta): | |||||
return False | return False | ||||
def rename_plugin(self, pluginId, newName): | def rename_plugin(self, pluginId, newName): | ||||
return "" | |||||
return False | |||||
def clone_plugin(self, pluginId): | def clone_plugin(self, pluginId): | ||||
return False | return False | ||||
@@ -2270,6 +2279,9 @@ class CarlaHostNull(CarlaHostMeta): | |||||
def set_parameter_midi_cc(self, pluginId, parameterId, cc): | def set_parameter_midi_cc(self, pluginId, parameterId, cc): | ||||
return | return | ||||
def set_parameter_touch(self, pluginId, parameterId, touch): | |||||
return | |||||
def set_program(self, pluginId, programId): | def set_program(self, pluginId, programId): | ||||
return | return | ||||
@@ -2430,7 +2442,7 @@ class CarlaHostDLL(CarlaHostMeta): | |||||
self.lib.carla_remove_all_plugins.restype = c_bool | self.lib.carla_remove_all_plugins.restype = c_bool | ||||
self.lib.carla_rename_plugin.argtypes = [c_uint, c_char_p] | self.lib.carla_rename_plugin.argtypes = [c_uint, c_char_p] | ||||
self.lib.carla_rename_plugin.restype = c_char_p | |||||
self.lib.carla_rename_plugin.restype = c_bool | |||||
self.lib.carla_clone_plugin.argtypes = [c_uint] | self.lib.carla_clone_plugin.argtypes = [c_uint] | ||||
self.lib.carla_clone_plugin.restype = c_bool | self.lib.carla_clone_plugin.restype = c_bool | ||||
@@ -2567,6 +2579,9 @@ class CarlaHostDLL(CarlaHostMeta): | |||||
self.lib.carla_set_parameter_midi_cc.argtypes = [c_uint, c_uint32, c_int16] | self.lib.carla_set_parameter_midi_cc.argtypes = [c_uint, c_uint32, c_int16] | ||||
self.lib.carla_set_parameter_midi_cc.restype = None | self.lib.carla_set_parameter_midi_cc.restype = None | ||||
self.lib.carla_set_parameter_touch.argtypes = [c_uint, c_uint32, c_bool] | |||||
self.lib.carla_set_parameter_touch.restype = None | |||||
self.lib.carla_set_program.argtypes = [c_uint, c_uint32] | self.lib.carla_set_program.argtypes = [c_uint, c_uint32] | ||||
self.lib.carla_set_program.restype = None | self.lib.carla_set_program.restype = None | ||||
@@ -2722,7 +2737,7 @@ class CarlaHostDLL(CarlaHostMeta): | |||||
return bool(self.lib.carla_remove_all_plugins()) | return bool(self.lib.carla_remove_all_plugins()) | ||||
def rename_plugin(self, pluginId, newName): | def rename_plugin(self, pluginId, newName): | ||||
return charPtrToString(self.lib.carla_rename_plugin(pluginId, newName.encode("utf-8"))) | |||||
return bool(self.lib.carla_rename_plugin(pluginId, newName.encode("utf-8"))) | |||||
def clone_plugin(self, pluginId): | def clone_plugin(self, pluginId): | ||||
return bool(self.lib.carla_clone_plugin(pluginId)) | return bool(self.lib.carla_clone_plugin(pluginId)) | ||||
@@ -2872,6 +2887,9 @@ class CarlaHostDLL(CarlaHostMeta): | |||||
def set_parameter_midi_cc(self, pluginId, parameterId, cc): | def set_parameter_midi_cc(self, pluginId, parameterId, cc): | ||||
self.lib.carla_set_parameter_midi_cc(pluginId, parameterId, cc) | self.lib.carla_set_parameter_midi_cc(pluginId, parameterId, cc) | ||||
def set_parameter_touch(self, pluginId, parameterId, touch): | |||||
self.lib.carla_set_parameter_touch(pluginId, parameterId, touch) | |||||
def set_program(self, pluginId, programId): | def set_program(self, pluginId, programId): | ||||
self.lib.carla_set_program(pluginId, programId) | self.lib.carla_set_program(pluginId, programId) | ||||
@@ -3097,11 +3115,7 @@ class CarlaHostPlugin(CarlaHostMeta): | |||||
return self.sendMsgAndSetError(["remove_all_plugins"]) | return self.sendMsgAndSetError(["remove_all_plugins"]) | ||||
def rename_plugin(self, pluginId, newName): | def rename_plugin(self, pluginId, newName): | ||||
if self.sendMsg(["rename_plugin", pluginId, newName]): | |||||
return newName | |||||
self.fLastError = "Communication error with backend" | |||||
return "" | |||||
return self.sendMsgAndSetError(["rename_plugin", pluginId, newName]) | |||||
def clone_plugin(self, pluginId): | def clone_plugin(self, pluginId): | ||||
return self.sendMsgAndSetError(["clone_plugin", pluginId]) | return self.sendMsgAndSetError(["clone_plugin", pluginId]) | ||||
@@ -3263,6 +3277,9 @@ class CarlaHostPlugin(CarlaHostMeta): | |||||
self.sendMsg(["set_parameter_midi_cc", pluginId, parameterId, cc]) | self.sendMsg(["set_parameter_midi_cc", pluginId, parameterId, cc]) | ||||
self.fPluginsInfo[pluginId].parameterData[parameterId]['midiCC'] = cc | self.fPluginsInfo[pluginId].parameterData[parameterId]['midiCC'] = cc | ||||
def set_parameter_touch(self, pluginId, parameterId, touch): | |||||
self.sendMsg(["set_parameter_touch", pluginId, parameterId, touch]) | |||||
def set_program(self, pluginId, programId): | def set_program(self, pluginId, programId): | ||||
self.sendMsg(["set_program", pluginId, programId]) | self.sendMsg(["set_program", pluginId, programId]) | ||||
self.fPluginsInfo[pluginId].programCurrent = programId | self.fPluginsInfo[pluginId].programCurrent = programId | ||||
@@ -624,6 +624,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||||
for paramIndex, paramWidget in self.fParameterList: | for paramIndex, paramWidget in self.fParameterList: | ||||
paramWidget.setContextMenuPolicy(Qt.CustomContextMenu) | paramWidget.setContextMenuPolicy(Qt.CustomContextMenu) | ||||
paramWidget.customContextMenuRequested.connect(self.slot_knobCustomMenu) | paramWidget.customContextMenuRequested.connect(self.slot_knobCustomMenu) | ||||
paramWidget.dragStateChanged.connect(self.slot_parameterDragStateChanged) | |||||
paramWidget.realValueChanged.connect(self.slot_parameterValueChanged) | paramWidget.realValueChanged.connect(self.slot_parameterValueChanged) | ||||
paramWidget.blockSignals(True) | paramWidget.blockSignals(True) | ||||
paramWidget.setValue(self.host.get_internal_parameter_value(self.fPluginId, paramIndex)) | paramWidget.setValue(self.host.get_internal_parameter_value(self.fPluginId, paramIndex)) | ||||
@@ -797,8 +798,6 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||||
self.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok) | self.host.get_last_error(), QMessageBox.Ok, QMessageBox.Ok) | ||||
return | return | ||||
self.setName(newName) | |||||
def showReplaceDialog(self): | def showReplaceDialog(self): | ||||
data = gCarla.gui.showAddPluginDialog() | data = gCarla.gui.showAddPluginDialog() | ||||
@@ -1360,6 +1359,13 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||||
#------------------------------------------------------------------ | #------------------------------------------------------------------ | ||||
@pyqtSlot(bool) | |||||
def slot_parameterDragStateChanged(self, touch): | |||||
index = self.sender().getIndex() | |||||
if index >= 0: | |||||
self.host.set_parameter_touch(self.fPluginId, index, touch) | |||||
@pyqtSlot(float) | @pyqtSlot(float) | ||||
def slot_parameterValueChanged(self, value): | def slot_parameterValueChanged(self, value): | ||||
index = self.sender().getIndex() | index = self.sender().getIndex() | ||||
@@ -293,6 +293,7 @@ class PluginParameter(QWidget): | |||||
self.ui.sb_channel.customContextMenuRequested.connect(self.slot_channelSpinboxCustomMenu) | self.ui.sb_channel.customContextMenuRequested.connect(self.slot_channelSpinboxCustomMenu) | ||||
self.ui.sb_control.valueChanged.connect(self.slot_controlSpinboxChanged) | self.ui.sb_control.valueChanged.connect(self.slot_controlSpinboxChanged) | ||||
self.ui.sb_channel.valueChanged.connect(self.slot_channelSpinboxChanged) | self.ui.sb_channel.valueChanged.connect(self.slot_channelSpinboxChanged) | ||||
self.ui.widget.dragStateChanged.connect(self.slot_parameterDragStateChanged) | |||||
# ------------------------------------------------------------- | # ------------------------------------------------------------- | ||||
@@ -383,6 +384,10 @@ class PluginParameter(QWidget): | |||||
self.fMidiChannel = channel | self.fMidiChannel = channel | ||||
self.midiChannelChanged.emit(self.fParameterId, channel) | self.midiChannelChanged.emit(self.fParameterId, channel) | ||||
@pyqtSlot(bool) | |||||
def slot_parameterDragStateChanged(self, touch): | |||||
self.host.set_parameter_touch(self.fPluginId, self.fParameterId, touch) | |||||
def _textCallBack(self): | def _textCallBack(self): | ||||
return self.host.get_parameter_text(self.fPluginId, self.fParameterId) | return self.host.get_parameter_text(self.fPluginId, self.fParameterId) | ||||
@@ -107,6 +107,7 @@ class CustomInputDialog(QDialog): | |||||
class ParamProgressBar(QProgressBar): | class ParamProgressBar(QProgressBar): | ||||
# signals | # signals | ||||
dragStateChanged = pyqtSignal(bool) | |||||
valueChanged = pyqtSignal(float) | valueChanged = pyqtSignal(float) | ||||
def __init__(self, parent): | def __init__(self, parent): | ||||
@@ -217,6 +218,7 @@ class ParamProgressBar(QProgressBar): | |||||
if event.button() == Qt.LeftButton: | if event.button() == Qt.LeftButton: | ||||
self.handleMouseEventPos(event.pos()) | self.handleMouseEventPos(event.pos()) | ||||
self.fLeftClickDown = True | self.fLeftClickDown = True | ||||
self.dragStateChanged.emit(True) | |||||
else: | else: | ||||
self.fLeftClickDown = False | self.fLeftClickDown = False | ||||
@@ -236,6 +238,7 @@ class ParamProgressBar(QProgressBar): | |||||
return | return | ||||
self.fLeftClickDown = False | self.fLeftClickDown = False | ||||
self.dragStateChanged.emit(False) | |||||
QProgressBar.mouseReleaseEvent(self, event) | QProgressBar.mouseReleaseEvent(self, event) | ||||
def paintEvent(self, event): | def paintEvent(self, event): | ||||
@@ -293,6 +296,8 @@ class ParamSpinBox(QAbstractSpinBox): | |||||
self.customContextMenuRequested.connect(self.slot_showCustomMenu) | self.customContextMenuRequested.connect(self.slot_showCustomMenu) | ||||
self.fBar.valueChanged.connect(self.slot_progressBarValueChanged) | self.fBar.valueChanged.connect(self.slot_progressBarValueChanged) | ||||
self.dragStateChanged = self.fBar.dragStateChanged | |||||
QTimer.singleShot(0, self.slot_updateProgressBarGeometry) | QTimer.singleShot(0, self.slot_updateProgressBarGeometry) | ||||
def setDefault(self, value): | def setDefault(self, value): | ||||
@@ -52,6 +52,7 @@ class PixmapDial(QDial): | |||||
MODE_LINEAR = 1 | MODE_LINEAR = 1 | ||||
# signals | # signals | ||||
dragStateChanged = pyqtSignal(bool) | |||||
realValueChanged = pyqtSignal(float) | realValueChanged = pyqtSignal(float) | ||||
def __init__(self, parent, index=0): | def __init__(self, parent, index=0): | ||||
@@ -305,6 +306,7 @@ class PixmapDial(QDial): | |||||
self.fIsPressed = True | self.fIsPressed = True | ||||
self.fLastDragPos = event.pos() | self.fLastDragPos = event.pos() | ||||
self.fLastDragValue = self.fRealValue | self.fLastDragValue = self.fRealValue | ||||
self.dragStateChanged.emit(True) | |||||
def mouseMoveEvent(self, event): | def mouseMoveEvent(self, event): | ||||
if self.fDialMode == self.MODE_DEFAULT: | if self.fDialMode == self.MODE_DEFAULT: | ||||
@@ -334,6 +336,7 @@ class PixmapDial(QDial): | |||||
if self.fIsPressed: | if self.fIsPressed: | ||||
self.fIsPressed = False | self.fIsPressed = False | ||||
self.dragStateChanged.emit(False) | |||||
def paintEvent(self, event): | def paintEvent(self, event): | ||||
painter = QPainter(self) | painter = QPainter(self) | ||||
@@ -192,6 +192,7 @@ typedef struct { | |||||
bool (*write_midi_event)(NativeHostHandle handle, const NativeMidiEvent* event); | bool (*write_midi_event)(NativeHostHandle handle, const NativeMidiEvent* event); | ||||
void (*ui_parameter_changed)(NativeHostHandle handle, uint32_t index, float value); | void (*ui_parameter_changed)(NativeHostHandle handle, uint32_t index, float value); | ||||
void (*ui_parameter_touch)(NativeHostHandle handle, uint32_t index, bool touch); | |||||
void (*ui_midi_program_changed)(NativeHostHandle handle, uint8_t channel, uint32_t bank, uint32_t program); | void (*ui_midi_program_changed)(NativeHostHandle handle, uint8_t channel, uint32_t bank, uint32_t program); | ||||
void (*ui_custom_data_changed)(NativeHostHandle handle, const char* key, const char* value); | void (*ui_custom_data_changed)(NativeHostHandle handle, const char* key, const char* value); | ||||
void (*ui_closed)(NativeHostHandle handle); | void (*ui_closed)(NativeHostHandle handle); | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* Carla Native Plugin API (C++) | * Carla Native Plugin API (C++) | ||||
* Copyright (C) 2012-2014 Filipe Coelho <falktx@falktx.com> | |||||
* Copyright (C) 2012-2019 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
* modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
@@ -113,6 +113,13 @@ protected: | |||||
pHost->ui_parameter_changed(pHost->handle, index, value); | pHost->ui_parameter_changed(pHost->handle, index, value); | ||||
} | } | ||||
void uiParameterTouch(const uint32_t index, const bool touch) const | |||||
{ | |||||
CARLA_SAFE_ASSERT_RETURN(pHost != nullptr,); | |||||
pHost->ui_parameter_touch(pHost->handle, index, touch); | |||||
} | |||||
void uiMidiProgramChanged(const uint8_t channel, const uint32_t bank, const uint32_t program) const | void uiMidiProgramChanged(const uint8_t channel, const uint32_t bank, const uint32_t program) const | ||||
{ | { | ||||
CARLA_SAFE_ASSERT_RETURN(pHost != nullptr,); | CARLA_SAFE_ASSERT_RETURN(pHost != nullptr,); | ||||
@@ -98,9 +98,9 @@ public: | |||||
// --------------------------------------------- | // --------------------------------------------- | ||||
protected: | protected: | ||||
void handleEditParameter(const uint32_t, const bool) | |||||
void handleEditParameter(const uint32_t index, const bool touch) | |||||
{ | { | ||||
// TODO | |||||
fHost->ui_parameter_touch(fHost->handle, rindex, touch); | |||||
} | } | ||||
void handleSetParameterValue(const uint32_t rindex, const float value) | void handleSetParameterValue(const uint32_t rindex, const float value) | ||||
@@ -198,6 +198,7 @@ static void writePluginFile(const NativePluginDescriptor* const pluginDesc) | |||||
hostDesc.get_time_info = nullptr; | hostDesc.get_time_info = nullptr; | ||||
hostDesc.write_midi_event = nullptr; | hostDesc.write_midi_event = nullptr; | ||||
hostDesc.ui_parameter_changed = nullptr; | hostDesc.ui_parameter_changed = nullptr; | ||||
hostDesc.ui_parameter_touch = nullptr; | |||||
hostDesc.ui_midi_program_changed = nullptr; | hostDesc.ui_midi_program_changed = nullptr; | ||||
hostDesc.ui_custom_data_changed = nullptr; | hostDesc.ui_custom_data_changed = nullptr; | ||||
hostDesc.ui_closed = nullptr; | hostDesc.ui_closed = nullptr; | ||||
@@ -94,6 +94,7 @@ public: | |||||
fHost.get_time_info = host_get_time_info; | fHost.get_time_info = host_get_time_info; | ||||
fHost.write_midi_event = host_write_midi_event; | fHost.write_midi_event = host_write_midi_event; | ||||
fHost.ui_parameter_changed = host_ui_parameter_changed; | fHost.ui_parameter_changed = host_ui_parameter_changed; | ||||
fHost.ui_parameter_touch = host_ui_parameter_touch; | |||||
fHost.ui_custom_data_changed = host_ui_custom_data_changed; | fHost.ui_custom_data_changed = host_ui_custom_data_changed; | ||||
fHost.ui_closed = host_ui_closed; | fHost.ui_closed = host_ui_closed; | ||||
fHost.ui_open_file = host_ui_open_file; | fHost.ui_open_file = host_ui_open_file; | ||||
@@ -492,6 +493,11 @@ public: | |||||
fUI.host = (const LV2_External_UI_Host*)features[i]->data; | fUI.host = (const LV2_External_UI_Host*)features[i]->data; | ||||
break; | break; | ||||
} | } | ||||
if (std::strcmp(features[i]->URI, LV2_UI__touch) == 0) | |||||
{ | |||||
fUI.touch = (const LV2UI_Touch*)features[i]->data; | |||||
break; | |||||
} | |||||
} | } | ||||
if (fUI.host != nullptr) | if (fUI.host != nullptr) | ||||
@@ -648,6 +654,12 @@ protected: | |||||
fUI.writeFunction(fUI.controller, index+fPorts.indexOffset, sizeof(float), 0, &value); | fUI.writeFunction(fUI.controller, index+fPorts.indexOffset, sizeof(float), 0, &value); | ||||
} | } | ||||
void handleUiParameterTouch(const uint32_t index, const bool touch) const | |||||
{ | |||||
if (fUI.touch != nullptr && fUI.touch->touch != nullptr) | |||||
fUI.touch->touch(fUI.touch->handle, index+fPorts.indexOffset, touch); | |||||
} | |||||
void handleUiCustomDataChanged(const char* const key, const char* const value) const | void handleUiCustomDataChanged(const char* const key, const char* const value) const | ||||
{ | { | ||||
carla_stdout("TODO: handleUiCustomDataChanged %s %s", key, value); | carla_stdout("TODO: handleUiCustomDataChanged %s %s", key, value); | ||||
@@ -668,6 +680,7 @@ protected: | |||||
fUI.host->ui_closed(fUI.controller); | fUI.host->ui_closed(fUI.controller); | ||||
fUI.host = nullptr; | fUI.host = nullptr; | ||||
fUI.touch = nullptr; | |||||
fUI.writeFunction = nullptr; | fUI.writeFunction = nullptr; | ||||
fUI.controller = nullptr; | fUI.controller = nullptr; | ||||
} | } | ||||
@@ -784,6 +797,11 @@ private: | |||||
handlePtr->handleUiParameterChanged(index, value); | handlePtr->handleUiParameterChanged(index, value); | ||||
} | } | ||||
static void host_ui_parameter_touch(NativeHostHandle handle, uint32_t index, bool touch) | |||||
{ | |||||
handlePtr->handleUiParameterTouch(index, touch); | |||||
} | |||||
static void host_ui_custom_data_changed(NativeHostHandle handle, const char* key, const char* value) | static void host_ui_custom_data_changed(NativeHostHandle handle, const char* key, const char* value) | ||||
{ | { | ||||
handlePtr->handleUiCustomDataChanged(key, value); | handlePtr->handleUiCustomDataChanged(key, value); | ||||
@@ -81,6 +81,7 @@ int main() | |||||
nullptr, // write_midi_event | nullptr, // write_midi_event | ||||
nullptr, // ui_parameter_changed | nullptr, // ui_parameter_changed | ||||
nullptr, // ui_parameter_touch | |||||
nullptr, // ui_midi_program_changed | nullptr, // ui_midi_program_changed | ||||
nullptr, // ui_custom_data_changed | nullptr, // ui_custom_data_changed | ||||
nullptr, // ui_closed | nullptr, // ui_closed | ||||
@@ -17,10 +17,8 @@ | |||||
#include "carla-vst.hpp" | #include "carla-vst.hpp" | ||||
#ifndef CARLA_OS_LINUX | |||||
# include "ui_launcher.cpp" | |||||
# include "ui_launcher_res.cpp" | |||||
#endif | |||||
#include "ui_launcher.cpp" | |||||
#include "ui_launcher_res.cpp" | |||||
#include <cstring> | #include <cstring> | ||||
@@ -131,14 +131,15 @@ public: | |||||
fHost.get_time_info = host_get_time_info; | fHost.get_time_info = host_get_time_info; | ||||
fHost.write_midi_event = host_write_midi_event; | fHost.write_midi_event = host_write_midi_event; | ||||
fHost.ui_parameter_changed = host_ui_parameter_changed; | fHost.ui_parameter_changed = host_ui_parameter_changed; | ||||
fHost.ui_parameter_touch = host_ui_parameter_touch; | |||||
fHost.ui_custom_data_changed = host_ui_custom_data_changed; | fHost.ui_custom_data_changed = host_ui_custom_data_changed; | ||||
fHost.ui_closed = host_ui_closed; | fHost.ui_closed = host_ui_closed; | ||||
fHost.ui_open_file = host_ui_open_file; | fHost.ui_open_file = host_ui_open_file; | ||||
fHost.ui_save_file = host_ui_save_file; | fHost.ui_save_file = host_ui_save_file; | ||||
fHost.dispatcher = host_dispatcher; | fHost.dispatcher = host_dispatcher; | ||||
fVstRect.top = 0; | |||||
fVstRect.left = 0; | |||||
fVstRect.top = 0; | |||||
fVstRect.left = 0; | |||||
if (kIsUsingUILauncher) | if (kIsUsingUILauncher) | ||||
{ | { | ||||
@@ -406,8 +407,12 @@ public: | |||||
case effEditOpen: | case effEditOpen: | ||||
if (fDescriptor->ui_show != nullptr) | if (fDescriptor->ui_show != nullptr) | ||||
{ | { | ||||
#ifdef HAVE_X11 | |||||
if (! kIsUsingUILauncher) | |||||
if (kIsUsingUILauncher) | |||||
{ | |||||
destoryUILauncher(fUiLauncher); | |||||
fUiLauncher = createUILauncher((intptr_t)ptr, fDescriptor, fHandle); | |||||
} | |||||
else | |||||
{ | { | ||||
char strBuf[0xff+1]; | char strBuf[0xff+1]; | ||||
std::snprintf(strBuf, 0xff, P_INTPTR, (intptr_t)ptr); | std::snprintf(strBuf, 0xff, P_INTPTR, (intptr_t)ptr); | ||||
@@ -422,12 +427,6 @@ public: | |||||
// reset CARLA_PLUGIN_EMBED_WINID just in case | // reset CARLA_PLUGIN_EMBED_WINID just in case | ||||
carla_setenv("CARLA_PLUGIN_EMBED_WINID", "0"); | carla_setenv("CARLA_PLUGIN_EMBED_WINID", "0"); | ||||
} | } | ||||
else | |||||
#endif | |||||
{ | |||||
destoryUILauncher(fUiLauncher); | |||||
fUiLauncher = createUILauncher((intptr_t)ptr, fDescriptor, fHandle); | |||||
} | |||||
ret = 1; | ret = 1; | ||||
} | } | ||||
break; | break; | ||||
@@ -435,16 +434,14 @@ public: | |||||
case effEditClose: | case effEditClose: | ||||
if (fDescriptor->ui_show != nullptr) | if (fDescriptor->ui_show != nullptr) | ||||
{ | { | ||||
#ifdef HAVE_X11 | |||||
if (! kIsUsingUILauncher) | |||||
if (kIsUsingUILauncher) | |||||
{ | { | ||||
fDescriptor->ui_show(fHandle, false); | |||||
destoryUILauncher(fUiLauncher); | |||||
fUiLauncher = nullptr; | |||||
} | } | ||||
else | else | ||||
#endif | |||||
{ | { | ||||
destoryUILauncher(fUiLauncher); | |||||
fUiLauncher = nullptr; | |||||
fDescriptor->ui_show(fHandle, false); | |||||
} | } | ||||
ret = 1; | ret = 1; | ||||
} | } | ||||
@@ -726,6 +723,12 @@ protected: | |||||
hostCallback(audioMasterAutomate, static_cast<int32_t>(index), 0, nullptr, normalizedValue); | hostCallback(audioMasterAutomate, static_cast<int32_t>(index), 0, nullptr, normalizedValue); | ||||
} | } | ||||
void handleUiParameterTouch(const uint32_t index, const bool touch) const | |||||
{ | |||||
carla_stdout("VST handleUiParameterTouch %u %s", index, bool2str(touch)); | |||||
hostCallback(touch ? audioMasterBeginEdit : audioMasterEndEdit, static_cast<int32_t>(index)); | |||||
} | |||||
void handleUiCustomDataChanged(const char* const /*key*/, const char* const /*value*/) const | void handleUiCustomDataChanged(const char* const /*key*/, const char* const /*value*/) const | ||||
{ | { | ||||
} | } | ||||
@@ -877,6 +880,11 @@ private: | |||||
handlePtr->handleUiParameterChanged(index, value); | handlePtr->handleUiParameterChanged(index, value); | ||||
} | } | ||||
static void host_ui_parameter_touch(NativeHostHandle handle, uint32_t index, bool touch) | |||||
{ | |||||
handlePtr->handleUiParameterTouch(index, touch); | |||||
} | |||||
static void host_ui_custom_data_changed(NativeHostHandle handle, const char* key, const char* value) | static void host_ui_custom_data_changed(NativeHostHandle handle, const char* key, const char* value) | ||||
{ | { | ||||
handlePtr->handleUiCustomDataChanged(key, value); | handlePtr->handleUiCustomDataChanged(key, value); | ||||
@@ -15,11 +15,14 @@ | |||||
* For a full copy of the GNU General Public License see the doc/GPL.txt file. | * For a full copy of the GNU General Public License see the doc/GPL.txt file. | ||||
*/ | */ | ||||
#ifndef CARLA_VST_HPP_INCLUDED | |||||
#define CARLA_VST_HPP_INCLUDED | |||||
#include "CarlaDefines.h" | #include "CarlaDefines.h" | ||||
#include "CarlaNative.h" | #include "CarlaNative.h" | ||||
#include "vestige/vestige.h" | #include "vestige/vestige.h" | ||||
# include "ui_launcher_res.hpp" | |||||
#include "ui_launcher_res.hpp" | |||||
struct CarlaUILauncher; | struct CarlaUILauncher; | ||||
class NativePlugin; | class NativePlugin; | ||||
@@ -44,3 +47,5 @@ float vst_getParameterCallback(AEffect* effect, int32_t index); | |||||
void vst_setParameterCallback(AEffect* effect, int32_t index, float value); | void vst_setParameterCallback(AEffect* effect, int32_t index, float value); | ||||
void vst_processCallback(AEffect* effect, float** inputs, float** outputs, int32_t sampleFrames); | void vst_processCallback(AEffect* effect, float** inputs, float** outputs, int32_t sampleFrames); | ||||
void vst_processReplacingCallback(AEffect* effect, float** inputs, float** outputs, int32_t sampleFrames); | void vst_processReplacingCallback(AEffect* effect, float** inputs, float** outputs, int32_t sampleFrames); | ||||
#endif // CARLA_VST_HPP_INCLUDED |
@@ -1137,6 +1137,7 @@ public: | |||||
handleUiHide(); | handleUiHide(); | ||||
fUI.host = nullptr; | fUI.host = nullptr; | ||||
fUI.touch = nullptr; | |||||
fUI.writeFunction = nullptr; | fUI.writeFunction = nullptr; | ||||
fUI.controller = nullptr; | fUI.controller = nullptr; | ||||
} | } | ||||
@@ -1535,12 +1536,14 @@ protected: | |||||
struct UI { | struct UI { | ||||
const LV2_External_UI_Host* host; | const LV2_External_UI_Host* host; | ||||
const LV2UI_Touch* touch; | |||||
LV2UI_Write_Function writeFunction; | LV2UI_Write_Function writeFunction; | ||||
LV2UI_Controller controller; | LV2UI_Controller controller; | ||||
bool isVisible; | bool isVisible; | ||||
UI() | UI() | ||||
: host(nullptr), | : host(nullptr), | ||||
touch(nullptr), | |||||
writeFunction(nullptr), | writeFunction(nullptr), | ||||
controller(nullptr), | controller(nullptr), | ||||
isVisible(false) {} | isVisible(false) {} | ||||