Browse Source

WIP drag/touch params callback to host; Fix plugin rename API

Signed-off-by: falkTX <falktx@falktx.com>
tags/v2.1-rc1
falkTX 5 years ago
parent
commit
dbf649d58d
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
25 changed files with 267 additions and 75 deletions
  1. +10
    -1
      source/backend/CarlaEngine.hpp
  2. +10
    -1
      source/backend/CarlaHost.h
  3. +11
    -3
      source/backend/CarlaStandalone.cpp
  4. +17
    -11
      source/backend/engine/CarlaEngine.cpp
  5. +11
    -11
      source/backend/engine/CarlaEngineJack.cpp
  6. +25
    -10
      source/backend/engine/CarlaEngineNative.cpp
  7. +13
    -2
      source/backend/plugin/CarlaPluginJuce.cpp
  8. +38
    -1
      source/backend/plugin/CarlaPluginLV2.cpp
  9. +12
    -0
      source/backend/plugin/CarlaPluginNative.cpp
  10. +8
    -1
      source/backend/plugin/CarlaPluginVST2.cpp
  11. +25
    -8
      source/frontend/carla_backend.py
  12. +8
    -2
      source/frontend/carla_skin.py
  13. +5
    -0
      source/frontend/carla_widgets.py
  14. +5
    -0
      source/frontend/widgets/paramspinbox.py
  15. +3
    -0
      source/frontend/widgets/pixmapdial.py
  16. +1
    -0
      source/includes/CarlaNative.h
  17. +8
    -1
      source/includes/CarlaNative.hpp
  18. +2
    -2
      source/modules/distrho/src/DistrhoPluginCarla.cpp
  19. +1
    -0
      source/plugin/carla-lv2-export.cpp
  20. +18
    -0
      source/plugin/carla-lv2.cpp
  21. +1
    -0
      source/plugin/carla-native-plugin.cpp
  22. +2
    -4
      source/plugin/carla-vst-export.cpp
  23. +24
    -16
      source/plugin/carla-vst.cpp
  24. +6
    -1
      source/plugin/carla-vst.hpp
  25. +3
    -0
      source/utils/CarlaLv2Utils.hpp

+ 10
- 1
source/backend/CarlaEngine.hpp View File

@@ -862,7 +862,7 @@ public:
* Returned variable must be deleted if non-null.
* @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.
@@ -880,6 +880,15 @@ public:
* Switch plugins with id @a idA and @a idB.
*/
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

/*!


+ 10
- 1
source/backend/CarlaHost.h View File

@@ -542,7 +542,7 @@ CARLA_EXPORT bool carla_remove_all_plugins();
* @param pluginId Plugin to rename
* @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.
@@ -879,6 +879,15 @@ CARLA_EXPORT void carla_set_parameter_midi_channel(uint pluginId, uint32_t param
* @param cc New MIDI 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

/*!


+ 11
- 3
source/backend/CarlaStandalone.cpp View File

@@ -954,10 +954,10 @@ bool carla_remove_all_plugins()
}

#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);

@@ -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);
}

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

// --------------------------------------------------------------------------------------------------------------------


+ 17
- 11
source/backend/engine/CarlaEngine.cpp View File

@@ -752,30 +752,32 @@ bool CarlaEngine::removeAllPlugins()
}

#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);

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));
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);

if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
pData->graph.renamePlugin(plugin, uniqueName);

callback(true, true, ENGINE_CALLBACK_PLUGIN_RENAMED, id, 0, 0, 0, 0.0f, uniqueName);

delete[] uniqueName;
return plugin->getName();
return true;
}

bool CarlaEngine::clonePlugin(const uint id)
@@ -875,6 +877,10 @@ bool CarlaEngine::switchPlugins(const uint idA, const uint idB) noexcept

return true;
}

void CarlaEngine::touchPluginParameter(const uint, const uint32_t, const bool) noexcept
{
}
#endif

CarlaPlugin* CarlaEngine::getPlugin(const uint id) const noexcept


+ 11
- 11
source/backend/engine/CarlaEngineJack.cpp View File

@@ -1357,7 +1357,7 @@ public:
}

#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 ||
pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
@@ -1365,14 +1365,14 @@ public:
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);
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
const bool needsReinit = (pData->options.processMode == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS);
@@ -1395,7 +1395,7 @@ public:
if (uniqueName.isEmpty())
{
setLastError("Failed to request new unique plugin name");
return nullptr;
return false;
}

const ScopedThreadStopper sts(this);
@@ -1408,7 +1408,7 @@ public:
if (! client->renameInSingleClient(uniqueName))
{
setLastError("Failed to rename some JACK ports, does your JACK version support proper port renaming?");
return nullptr;
return false;
}
}
// rename in multiple client mode
@@ -1493,7 +1493,7 @@ public:
else
{
setLastError("Failed to create new JACK client");
return nullptr;
return false;
}
}

@@ -1508,7 +1508,7 @@ public:
plugin->setEnabled(true);
}

return plugin->getName();
return true;
}

// -------------------------------------------------------------------


+ 25
- 10
source/backend/engine/CarlaEngineNative.cpp View File

@@ -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);
}

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()
{
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(readNextLineAsString(newName), true);

// TODO
/*const char* name =*/ fEngine->renamePlugin(pluginId, newName);
ok = fEngine->renamePlugin(pluginId, newName);

delete[] newName;
}
@@ -2119,6 +2122,18 @@ bool CarlaEngineNativeUI::msgReceived(const char*const msg) noexcept
if (CarlaPlugin* const plugin = fEngine->getPlugin(pluginId))
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)
{
uint32_t pluginId;


+ 13
- 2
source/backend/plugin/CarlaPluginJuce.cpp View File

@@ -1159,8 +1159,19 @@ protected:
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
{


+ 38
- 1
source/backend/plugin/CarlaPluginLV2.cpp View File

@@ -615,6 +615,9 @@ public:
if (fFeatures[kFeatureIdUiResize] != nullptr && fFeatures[kFeatureIdUiResize]->data != nullptr)
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)
delete (LV2_External_UI_Host*)fFeatures[kFeatureIdExternalUi]->data;

@@ -5109,6 +5112,25 @@ public:
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)
{
CARLA_SAFE_ASSERT_RETURN(buffer != nullptr,);
@@ -6048,6 +6070,10 @@ public:
uiResizeFt->handle = this;
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;
uiExternalHostFt->ui_closed = carla_lv2_external_ui_closed;
uiExternalHostFt->plugin_human_id = fLv2Options.windowTitle;
@@ -6092,7 +6118,7 @@ public:
fFeatures[kFeatureIdUiResize]->data = uiResizeFt;

fFeatures[kFeatureIdUiTouch]->URI = LV2_UI__touch;
fFeatures[kFeatureIdUiTouch]->data = nullptr;
fFeatures[kFeatureIdUiTouch]->data = uiTouchFt;

fFeatures[kFeatureIdExternalUi]->URI = LV2_EXTERNAL_UI__Host;
fFeatures[kFeatureIdExternalUi]->data = uiExternalHostFt;
@@ -6770,6 +6796,17 @@ private:
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



+ 12
- 0
source/backend/plugin/CarlaPluginNative.cpp View File

@@ -279,6 +279,7 @@ public:
fHost.get_time_info = carla_host_get_time_info;
fHost.write_midi_event = carla_host_write_midi_event;
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_closed = carla_host_ui_closed;
fHost.ui_open_file = carla_host_ui_open_file;
@@ -2393,6 +2394,12 @@ protected:
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)
{
setCustomData(CUSTOM_DATA_TYPE_STRING, key, value, false);
@@ -2696,6 +2703,11 @@ private:
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)
{
handlePtr->handleUiCustomDataChanged(key, value);


+ 8
- 1
source/backend/plugin/CarlaPluginVST2.cpp View File

@@ -2197,8 +2197,15 @@ protected:
break;

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:
// TODO
CARLA_SAFE_ASSERT_BREAK(index > 0);
carla_stdout("audioMasterEndEdit %i", index);
pData->engine->touchPluginParameter(pData->id, static_cast<uint32_t>(index), false);
break;

case audioMasterOpenFileSelector:


+ 25
- 8
source/frontend/carla_backend.py View File

@@ -1904,6 +1904,15 @@ class CarlaHostMeta(object):
def set_parameter_midi_cc(self, pluginId, parameterId, cc):
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.
# @param pluginId Plugin
# @param programId New program
@@ -2133,7 +2142,7 @@ class CarlaHostNull(CarlaHostMeta):
return False

def rename_plugin(self, pluginId, newName):
return ""
return False

def clone_plugin(self, pluginId):
return False
@@ -2270,6 +2279,9 @@ class CarlaHostNull(CarlaHostMeta):
def set_parameter_midi_cc(self, pluginId, parameterId, cc):
return

def set_parameter_touch(self, pluginId, parameterId, touch):
return

def set_program(self, pluginId, programId):
return

@@ -2430,7 +2442,7 @@ class CarlaHostDLL(CarlaHostMeta):
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.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.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.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.restype = None

@@ -2722,7 +2737,7 @@ class CarlaHostDLL(CarlaHostMeta):
return bool(self.lib.carla_remove_all_plugins())

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):
return bool(self.lib.carla_clone_plugin(pluginId))
@@ -2872,6 +2887,9 @@ class CarlaHostDLL(CarlaHostMeta):
def set_parameter_midi_cc(self, 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):
self.lib.carla_set_program(pluginId, programId)

@@ -3097,11 +3115,7 @@ class CarlaHostPlugin(CarlaHostMeta):
return self.sendMsgAndSetError(["remove_all_plugins"])

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):
return self.sendMsgAndSetError(["clone_plugin", pluginId])
@@ -3263,6 +3277,9 @@ class CarlaHostPlugin(CarlaHostMeta):
self.sendMsg(["set_parameter_midi_cc", pluginId, parameterId, 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):
self.sendMsg(["set_program", pluginId, programId])
self.fPluginsInfo[pluginId].programCurrent = programId


+ 8
- 2
source/frontend/carla_skin.py View File

@@ -624,6 +624,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta):
for paramIndex, paramWidget in self.fParameterList:
paramWidget.setContextMenuPolicy(Qt.CustomContextMenu)
paramWidget.customContextMenuRequested.connect(self.slot_knobCustomMenu)
paramWidget.dragStateChanged.connect(self.slot_parameterDragStateChanged)
paramWidget.realValueChanged.connect(self.slot_parameterValueChanged)
paramWidget.blockSignals(True)
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)
return

self.setName(newName)

def showReplaceDialog(self):
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)
def slot_parameterValueChanged(self, value):
index = self.sender().getIndex()


+ 5
- 0
source/frontend/carla_widgets.py View File

@@ -293,6 +293,7 @@ class PluginParameter(QWidget):
self.ui.sb_channel.customContextMenuRequested.connect(self.slot_channelSpinboxCustomMenu)
self.ui.sb_control.valueChanged.connect(self.slot_controlSpinboxChanged)
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.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):
return self.host.get_parameter_text(self.fPluginId, self.fParameterId)



+ 5
- 0
source/frontend/widgets/paramspinbox.py View File

@@ -107,6 +107,7 @@ class CustomInputDialog(QDialog):

class ParamProgressBar(QProgressBar):
# signals
dragStateChanged = pyqtSignal(bool)
valueChanged = pyqtSignal(float)

def __init__(self, parent):
@@ -217,6 +218,7 @@ class ParamProgressBar(QProgressBar):
if event.button() == Qt.LeftButton:
self.handleMouseEventPos(event.pos())
self.fLeftClickDown = True
self.dragStateChanged.emit(True)
else:
self.fLeftClickDown = False

@@ -236,6 +238,7 @@ class ParamProgressBar(QProgressBar):
return

self.fLeftClickDown = False
self.dragStateChanged.emit(False)
QProgressBar.mouseReleaseEvent(self, event)

def paintEvent(self, event):
@@ -293,6 +296,8 @@ class ParamSpinBox(QAbstractSpinBox):
self.customContextMenuRequested.connect(self.slot_showCustomMenu)
self.fBar.valueChanged.connect(self.slot_progressBarValueChanged)

self.dragStateChanged = self.fBar.dragStateChanged

QTimer.singleShot(0, self.slot_updateProgressBarGeometry)

def setDefault(self, value):


+ 3
- 0
source/frontend/widgets/pixmapdial.py View File

@@ -52,6 +52,7 @@ class PixmapDial(QDial):
MODE_LINEAR = 1

# signals
dragStateChanged = pyqtSignal(bool)
realValueChanged = pyqtSignal(float)

def __init__(self, parent, index=0):
@@ -305,6 +306,7 @@ class PixmapDial(QDial):
self.fIsPressed = True
self.fLastDragPos = event.pos()
self.fLastDragValue = self.fRealValue
self.dragStateChanged.emit(True)

def mouseMoveEvent(self, event):
if self.fDialMode == self.MODE_DEFAULT:
@@ -334,6 +336,7 @@ class PixmapDial(QDial):

if self.fIsPressed:
self.fIsPressed = False
self.dragStateChanged.emit(False)

def paintEvent(self, event):
painter = QPainter(self)


+ 1
- 0
source/includes/CarlaNative.h View File

@@ -192,6 +192,7 @@ typedef struct {
bool (*write_midi_event)(NativeHostHandle handle, const NativeMidiEvent* event);

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_custom_data_changed)(NativeHostHandle handle, const char* key, const char* value);
void (*ui_closed)(NativeHostHandle handle);


+ 8
- 1
source/includes/CarlaNative.hpp View File

@@ -1,6 +1,6 @@
/*
* 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
* 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);
}

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
{
CARLA_SAFE_ASSERT_RETURN(pHost != nullptr,);


+ 2
- 2
source/modules/distrho/src/DistrhoPluginCarla.cpp View File

@@ -98,9 +98,9 @@ public:
// ---------------------------------------------

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)


+ 1
- 0
source/plugin/carla-lv2-export.cpp View File

@@ -198,6 +198,7 @@ static void writePluginFile(const NativePluginDescriptor* const pluginDesc)
hostDesc.get_time_info = nullptr;
hostDesc.write_midi_event = nullptr;
hostDesc.ui_parameter_changed = nullptr;
hostDesc.ui_parameter_touch = nullptr;
hostDesc.ui_midi_program_changed = nullptr;
hostDesc.ui_custom_data_changed = nullptr;
hostDesc.ui_closed = nullptr;


+ 18
- 0
source/plugin/carla-lv2.cpp View File

@@ -94,6 +94,7 @@ public:
fHost.get_time_info = host_get_time_info;
fHost.write_midi_event = host_write_midi_event;
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_closed = host_ui_closed;
fHost.ui_open_file = host_ui_open_file;
@@ -492,6 +493,11 @@ public:
fUI.host = (const LV2_External_UI_Host*)features[i]->data;
break;
}
if (std::strcmp(features[i]->URI, LV2_UI__touch) == 0)
{
fUI.touch = (const LV2UI_Touch*)features[i]->data;
break;
}
}

if (fUI.host != nullptr)
@@ -648,6 +654,12 @@ protected:
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
{
carla_stdout("TODO: handleUiCustomDataChanged %s %s", key, value);
@@ -668,6 +680,7 @@ protected:
fUI.host->ui_closed(fUI.controller);

fUI.host = nullptr;
fUI.touch = nullptr;
fUI.writeFunction = nullptr;
fUI.controller = nullptr;
}
@@ -784,6 +797,11 @@ private:
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)
{
handlePtr->handleUiCustomDataChanged(key, value);


+ 1
- 0
source/plugin/carla-native-plugin.cpp View File

@@ -81,6 +81,7 @@ int main()
nullptr, // write_midi_event

nullptr, // ui_parameter_changed
nullptr, // ui_parameter_touch
nullptr, // ui_midi_program_changed
nullptr, // ui_custom_data_changed
nullptr, // ui_closed


+ 2
- 4
source/plugin/carla-vst-export.cpp View File

@@ -17,10 +17,8 @@

#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>



+ 24
- 16
source/plugin/carla-vst.cpp View File

@@ -131,14 +131,15 @@ public:
fHost.get_time_info = host_get_time_info;
fHost.write_midi_event = host_write_midi_event;
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_closed = host_ui_closed;
fHost.ui_open_file = host_ui_open_file;
fHost.ui_save_file = host_ui_save_file;
fHost.dispatcher = host_dispatcher;

fVstRect.top = 0;
fVstRect.left = 0;
fVstRect.top = 0;
fVstRect.left = 0;

if (kIsUsingUILauncher)
{
@@ -406,8 +407,12 @@ public:
case effEditOpen:
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];
std::snprintf(strBuf, 0xff, P_INTPTR, (intptr_t)ptr);
@@ -422,12 +427,6 @@ public:
// reset CARLA_PLUGIN_EMBED_WINID just in case
carla_setenv("CARLA_PLUGIN_EMBED_WINID", "0");
}
else
#endif
{
destoryUILauncher(fUiLauncher);
fUiLauncher = createUILauncher((intptr_t)ptr, fDescriptor, fHandle);
}
ret = 1;
}
break;
@@ -435,16 +434,14 @@ public:
case effEditClose:
if (fDescriptor->ui_show != nullptr)
{
#ifdef HAVE_X11
if (! kIsUsingUILauncher)
if (kIsUsingUILauncher)
{
fDescriptor->ui_show(fHandle, false);
destoryUILauncher(fUiLauncher);
fUiLauncher = nullptr;
}
else
#endif
{
destoryUILauncher(fUiLauncher);
fUiLauncher = nullptr;
fDescriptor->ui_show(fHandle, false);
}
ret = 1;
}
@@ -726,6 +723,12 @@ protected:
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
{
}
@@ -877,6 +880,11 @@ private:
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)
{
handlePtr->handleUiCustomDataChanged(key, value);


+ 6
- 1
source/plugin/carla-vst.hpp View File

@@ -15,11 +15,14 @@
* 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 "CarlaNative.h"
#include "vestige/vestige.h"

# include "ui_launcher_res.hpp"
#include "ui_launcher_res.hpp"
struct CarlaUILauncher;

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_processCallback(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

+ 3
- 0
source/utils/CarlaLv2Utils.hpp View File

@@ -1137,6 +1137,7 @@ public:
handleUiHide();

fUI.host = nullptr;
fUI.touch = nullptr;
fUI.writeFunction = nullptr;
fUI.controller = nullptr;
}
@@ -1535,12 +1536,14 @@ protected:

struct UI {
const LV2_External_UI_Host* host;
const LV2UI_Touch* touch;
LV2UI_Write_Function writeFunction;
LV2UI_Controller controller;
bool isVisible;

UI()
: host(nullptr),
touch(nullptr),
writeFunction(nullptr),
controller(nullptr),
isVisible(false) {}


Loading…
Cancel
Save