@@ -243,6 +243,9 @@ | |||
<addaction name="act_canvas_zoom_out"/> | |||
<addaction name="act_canvas_zoom_100"/> | |||
</widget> | |||
<addaction name="act_canvas_show_internal"/> | |||
<addaction name="act_canvas_show_external"/> | |||
<addaction name="separator"/> | |||
<addaction name="act_canvas_arrange"/> | |||
<addaction name="act_canvas_refresh"/> | |||
<addaction name="menu_Canvas_Zoom"/> | |||
@@ -652,6 +655,22 @@ | |||
<string>About &JUCE</string> | |||
</property> | |||
</action> | |||
<action name="act_canvas_show_internal"> | |||
<property name="checkable"> | |||
<bool>true</bool> | |||
</property> | |||
<property name="text"> | |||
<string>Show Internal</string> | |||
</property> | |||
</action> | |||
<action name="act_canvas_show_external"> | |||
<property name="checkable"> | |||
<bool>true</bool> | |||
</property> | |||
<property name="text"> | |||
<string>Show External</string> | |||
</property> | |||
</action> | |||
</widget> | |||
<customwidgets> | |||
<customwidget> | |||
@@ -936,7 +936,7 @@ public: | |||
/*! | |||
* Force the engine to resend all patchbay clients, ports and connections again. | |||
*/ | |||
virtual bool patchbayRefresh(); | |||
virtual bool patchbayRefresh(const bool external); | |||
#endif | |||
// ------------------------------------------------------------------- | |||
@@ -514,8 +514,10 @@ CARLA_EXPORT bool carla_patchbay_disconnect(uint connectionId); | |||
/*! | |||
* Force the engine to resend all patchbay clients, ports and connections again. | |||
* @param external Wherever to show external/hardware ports instead of internal ones. | |||
* Only valid in patchbay engine mode, other modes will ignore this. | |||
*/ | |||
CARLA_EXPORT bool carla_patchbay_refresh(); | |||
CARLA_EXPORT bool carla_patchbay_refresh(bool external); | |||
/*! | |||
* Start playback of the engine transport. | |||
@@ -1102,12 +1102,12 @@ bool carla_patchbay_disconnect(uint connectionId) | |||
return false; | |||
} | |||
bool carla_patchbay_refresh() | |||
bool carla_patchbay_refresh(bool external) | |||
{ | |||
carla_debug("carla_patchbay_refresh()"); | |||
carla_debug("carla_patchbay_refresh(%s)", bool2str(external)); | |||
if (gStandalone.engine != nullptr) | |||
return gStandalone.engine->patchbayRefresh(); | |||
return gStandalone.engine->patchbayRefresh(external); | |||
carla_stderr2("Engine is not running"); | |||
gStandalone.lastError = "Engine is not running"; | |||
@@ -1752,8 +1752,11 @@ bool CarlaEngine::patchbayDisconnect(const uint connectionId) | |||
return false; | |||
} | |||
bool CarlaEngine::patchbayRefresh() | |||
bool CarlaEngine::patchbayRefresh(const bool external) | |||
{ | |||
// subclasses should handle this | |||
CARLA_SAFE_ASSERT_RETURN(! external, false); | |||
if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK) | |||
{ | |||
// This is implemented in engine subclasses for MIDI support | |||
@@ -636,6 +636,7 @@ public: | |||
fClient(nullptr), | |||
fTransportPos(), | |||
fTransportState(JackTransportStopped), | |||
fExternalPatchbay(true), | |||
fFreewheel(false), | |||
#ifdef BUILD_BRIDGE | |||
fIsRunning(false), | |||
@@ -712,8 +713,9 @@ public: | |||
CARLA_SAFE_ASSERT_RETURN(jackbridge_is_ok(), false); | |||
carla_debug("CarlaEngineJack::init(\"%s\")", clientName); | |||
fFreewheel = false; | |||
fTransportState = JackTransportStopped; | |||
fFreewheel = false; | |||
fTransportState = JackTransportStopped; | |||
fExternalPatchbay = true; | |||
carla_zeroStruct<jack_position_t>(fTransportPos); | |||
@@ -761,13 +763,12 @@ public: | |||
const char* const jackClientName(jackbridge_get_client_name(fClient)); | |||
if (pData->options.processMode != ENGINE_PROCESS_MODE_PATCHBAY) | |||
{ | |||
initJackPatchbay(jackClientName); | |||
jackbridge_set_client_registration_callback(fClient, carla_jack_client_registration_callback, this); | |||
jackbridge_set_port_registration_callback(fClient, carla_jack_port_registration_callback, this); | |||
jackbridge_set_port_connect_callback(fClient, carla_jack_port_connect_callback, this); | |||
jackbridge_set_port_rename_callback(fClient, carla_jack_port_rename_callback, this); | |||
} | |||
jackbridge_set_client_registration_callback(fClient, carla_jack_client_registration_callback, this); | |||
jackbridge_set_port_registration_callback(fClient, carla_jack_port_registration_callback, this); | |||
jackbridge_set_port_connect_callback(fClient, carla_jack_port_connect_callback, this); | |||
jackbridge_set_port_rename_callback(fClient, carla_jack_port_rename_callback, this); | |||
if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || | |||
pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | |||
@@ -786,7 +787,7 @@ public: | |||
else | |||
{ | |||
pData->graph.create(false, pData->sampleRate, pData->bufferSize, 2, 2); | |||
CarlaEngine::patchbayRefresh(); | |||
patchbayRefresh(false); | |||
} | |||
} | |||
@@ -1051,7 +1052,7 @@ public: | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, false); | |||
if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | |||
if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY && ! fExternalPatchbay) | |||
return CarlaEngine::patchbayConnect(groupA, portA, groupB, portB); | |||
const char* const fullPortNameA = fUsedPorts.getFullPortName(groupA, portA); | |||
@@ -1075,7 +1076,7 @@ public: | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, false); | |||
if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | |||
if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY && ! fExternalPatchbay) | |||
return CarlaEngine::patchbayDisconnect(connectionId); | |||
for (LinkedList<ConnectionToId>::Itenerator it = fUsedConnections.list.begin(); it.valid(); it.next()) | |||
@@ -1104,12 +1105,17 @@ public: | |||
return false; | |||
} | |||
bool patchbayRefresh() override | |||
bool patchbayRefresh(const bool external) override | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, false); | |||
if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY) | |||
return CarlaEngine::patchbayRefresh(); | |||
{ | |||
fExternalPatchbay = external; | |||
if (! external) | |||
return CarlaEngine::patchbayRefresh(false); | |||
} | |||
fUsedGroups.clear(); | |||
fUsedPorts.clear(); | |||
@@ -1185,7 +1191,7 @@ public: | |||
CARLA_SAFE_ASSERT_CONTINUE(jackPort != nullptr); | |||
if (const char** connections = jackbridge_port_get_all_connections(fClient, jackPort)) | |||
if (const char** const connections = jackbridge_port_get_all_connections(fClient, jackPort)) | |||
{ | |||
for (int j=0; connections[j] != nullptr; ++j) | |||
{ | |||
@@ -1456,6 +1462,9 @@ protected: | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',); | |||
// ignore this if on internal patchbay mode | |||
if (! fExternalPatchbay) return; | |||
// do nothing on client registration, wait for first port | |||
if (reg) return; | |||
@@ -1473,6 +1482,9 @@ protected: | |||
void handleJackPortRegistrationCallback(const jack_port_id_t port, const bool reg) | |||
{ | |||
// ignore this if on internal patchbay mode | |||
if (! fExternalPatchbay) return; | |||
const jack_port_t* const jackPort(jackbridge_port_by_id(fClient, port)); | |||
CARLA_SAFE_ASSERT_RETURN(jackPort != nullptr,); | |||
@@ -1522,6 +1534,9 @@ protected: | |||
void handleJackPortConnectCallback(const jack_port_id_t a, const jack_port_id_t b, const bool connect) | |||
{ | |||
// ignore this if on internal patchbay mode | |||
if (! fExternalPatchbay) return; | |||
const jack_port_t* const jackPortA(jackbridge_port_by_id(fClient, a)); | |||
CARLA_SAFE_ASSERT_RETURN(jackPortA != nullptr,); | |||
@@ -1574,6 +1589,9 @@ protected: | |||
CARLA_SAFE_ASSERT_RETURN(oldName != nullptr && oldName[0] != '\0',); | |||
CARLA_SAFE_ASSERT_RETURN(newName != nullptr && newName[0] != '\0',); | |||
// ignore this if on internal patchbay mode | |||
if (! fExternalPatchbay) return; | |||
for (LinkedList<GroupNameToId>::Itenerator it = fUsedGroups.list.begin(); it.valid(); it.next()) | |||
{ | |||
GroupNameToId& groupNameToId(it.getValue()); | |||
@@ -1592,6 +1610,9 @@ protected: | |||
CARLA_SAFE_ASSERT_RETURN(oldFullName != nullptr && oldFullName[0] != '\0',); | |||
CARLA_SAFE_ASSERT_RETURN(newFullName != nullptr && newFullName[0] != '\0',); | |||
// ignore this if on internal patchbay mode | |||
if (! fExternalPatchbay) return; | |||
const jack_port_t* const jackPort(jackbridge_port_by_id(fClient, port)); | |||
CARLA_SAFE_ASSERT_RETURN(jackPort != nullptr,); | |||
@@ -1670,6 +1691,7 @@ private: | |||
jack_client_t* fClient; | |||
jack_position_t fTransportPos; | |||
jack_transport_state_t fTransportState; | |||
bool fExternalPatchbay; | |||
bool fFreewheel; | |||
// ------------------------------------------------------------------- | |||
@@ -1749,7 +1771,7 @@ private: | |||
void initJackPatchbay(const char* const ourName) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(pData->options.processMode != ENGINE_PROCESS_MODE_PATCHBAY,); | |||
CARLA_SAFE_ASSERT_RETURN(pData->options.processMode != ENGINE_PROCESS_MODE_PATCHBAY || fExternalPatchbay,); | |||
CARLA_SAFE_ASSERT_RETURN(ourName != nullptr && ourName[0] != '\0',); | |||
StringArray parsedGroups; | |||
@@ -173,8 +173,7 @@ public: | |||
fDevice->start(this); | |||
CarlaEngine::init(clientName); | |||
patchbayRefresh(); | |||
patchbayRefresh(false); | |||
return true; | |||
} | |||
@@ -250,7 +249,7 @@ public: | |||
// ------------------------------------------------------------------- | |||
// Patchbay | |||
bool patchbayRefresh() override | |||
bool patchbayRefresh(const bool /*external*/) override | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(pData->graph.isReady(), false); | |||
@@ -471,6 +470,8 @@ public: | |||
{ | |||
PatchbayGraph* const graph(pData->graph.getPatchbayGraph()); | |||
CARLA_SAFE_ASSERT_RETURN(graph != nullptr,); | |||
graph->refreshConnections(this); | |||
} | |||
// ------------------------------------------------------------------- | |||
@@ -156,7 +156,7 @@ protected: | |||
else if (std::strcmp(msg, "patchbay_refresh") == 0) | |||
{ | |||
try { | |||
ok = fEngine->patchbayRefresh(); | |||
ok = fEngine->patchbayRefresh(false); | |||
} CARLA_SAFE_EXCEPTION("patchbayRefresh"); | |||
} | |||
else if (std::strcmp(msg, "transport_play") == 0) | |||
@@ -1236,7 +1236,7 @@ protected: | |||
} | |||
if (fIsPatchbay) | |||
patchbayRefresh(); | |||
patchbayRefresh(false); | |||
} | |||
else | |||
{ | |||
@@ -287,8 +287,7 @@ public: | |||
} | |||
CarlaEngine::init(clientName); | |||
patchbayRefresh(); | |||
patchbayRefresh(false); | |||
return true; | |||
} | |||
@@ -380,7 +379,7 @@ public: | |||
// ------------------------------------------------------------------- | |||
// Patchbay | |||
bool patchbayRefresh() override | |||
bool patchbayRefresh(const bool /*external*/) override | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(pData->graph.isReady(), false); | |||
@@ -594,8 +593,10 @@ public: | |||
void patchbayRefreshPatchbay() noexcept | |||
{ | |||
// handled internally? | |||
CarlaEngine::patchbayRefresh(); | |||
PatchbayGraph* const graph(pData->graph.getPatchbayGraph()); | |||
CARLA_SAFE_ASSERT_RETURN(graph != nullptr,); | |||
graph->refreshConnections(this); | |||
} | |||
// ------------------------------------------------------------------- | |||
@@ -68,6 +68,8 @@ class CarlaMultiW(QTabWidget): | |||
parent.ui.act_plugins_center.triggered.connect(self.fRack.slot_pluginsCenter) | |||
parent.ui.act_plugins_panic.triggered.connect(self.fRack.slot_pluginsDisable) | |||
parent.ui.act_canvas_show_internal.triggered.connect(self.fPatchbay.slot_canvasShowInternal) | |||
parent.ui.act_canvas_show_external.triggered.connect(self.fPatchbay.slot_canvasShowExternal) | |||
parent.ui.act_canvas_arrange.setEnabled(False) # TODO, later | |||
parent.ui.act_canvas_arrange.triggered.connect(self.fPatchbay.slot_canvasArrange) | |||
parent.ui.act_canvas_refresh.triggered.connect(self.fPatchbay.slot_canvasRefresh) | |||
@@ -1344,8 +1344,10 @@ class Host(object): | |||
return bool(self.lib.carla_patchbay_disconnect(connectionId)) | |||
# Force the engine to resend all patchbay clients, ports and connections again. | |||
def patchbay_refresh(self): | |||
return bool(self.lib.carla_patchbay_refresh()) | |||
# @param external Wherever to show external/hardware ports instead of internal ones. | |||
# Only valid in patchbay engine mode, other modes will ignore this. | |||
def patchbay_refresh(self, external): | |||
return bool(self.lib.carla_patchbay_refresh(external)) | |||
# Start playback of the engine transport. | |||
def transport_play(self): | |||
@@ -1809,7 +1811,7 @@ class Host(object): | |||
self.lib.carla_patchbay_disconnect.argtypes = [c_uint] | |||
self.lib.carla_patchbay_disconnect.restype = c_bool | |||
self.lib.carla_patchbay_refresh.argtypes = None | |||
self.lib.carla_patchbay_refresh.argtypes = [c_bool] | |||
self.lib.carla_patchbay_refresh.restype = c_bool | |||
self.lib.carla_transport_play.argtypes = None | |||
@@ -251,6 +251,13 @@ class HostWindow(QMainWindow): | |||
self.ui.act_engine_stop.setEnabled(False) | |||
self.ui.act_plugin_remove_all.setEnabled(False) | |||
if gCarla.externalPatchbay: | |||
self.ui.act_canvas_show_internal.setChecked(False) | |||
self.ui.act_canvas_show_external.setChecked(True) | |||
else: | |||
self.ui.act_canvas_show_internal.setChecked(True) | |||
self.ui.act_canvas_show_external.setChecked(False) | |||
self.ui.menu_PluginMacros.setEnabled(False) | |||
self.ui.menu_Canvas.setEnabled(False) | |||
@@ -207,6 +207,8 @@ class CarlaPatchbayW(QFrame): | |||
parent.ui.act_plugins_center.triggered.connect(self.slot_pluginsCenter) | |||
parent.ui.act_plugins_panic.triggered.connect(self.slot_pluginsDisable) | |||
parent.ui.act_canvas_show_internal.triggered.connect(self.slot_canvasShowInternal) | |||
parent.ui.act_canvas_show_external.triggered.connect(self.slot_canvasShowExternal) | |||
parent.ui.act_canvas_arrange.setEnabled(False) # TODO, later | |||
parent.ui.act_canvas_arrange.triggered.connect(self.slot_canvasArrange) | |||
parent.ui.act_canvas_refresh.triggered.connect(self.slot_canvasRefresh) | |||
@@ -655,7 +657,7 @@ class CarlaPatchbayW(QFrame): | |||
self.slot_miniCanvasCheckAll() | |||
if gCarla.host.is_engine_running(): | |||
gCarla.host.patchbay_refresh() | |||
gCarla.host.patchbay_refresh(gCarla.externalPatchbay) | |||
# ----------------------------------------------------------------- | |||
@@ -948,12 +950,34 @@ class CarlaPatchbayW(QFrame): | |||
def slot_canvasArrange(self): | |||
patchcanvas.arrange() | |||
@pyqtSlot() | |||
def slot_canvasShowInternal(self): | |||
gCarla.externalPatchbay = False | |||
self.fParent.ui.act_canvas_show_internal.blockSignals(True) | |||
self.fParent.ui.act_canvas_show_external.blockSignals(True) | |||
self.fParent.ui.act_canvas_show_internal.setChecked(True) | |||
self.fParent.ui.act_canvas_show_external.setChecked(False) | |||
self.fParent.ui.act_canvas_show_internal.blockSignals(False) | |||
self.fParent.ui.act_canvas_show_external.blockSignals(False) | |||
self.slot_canvasRefresh() | |||
@pyqtSlot() | |||
def slot_canvasShowExternal(self): | |||
gCarla.externalPatchbay = True | |||
self.fParent.ui.act_canvas_show_internal.blockSignals(True) | |||
self.fParent.ui.act_canvas_show_external.blockSignals(True) | |||
self.fParent.ui.act_canvas_show_internal.setChecked(False) | |||
self.fParent.ui.act_canvas_show_external.setChecked(True) | |||
self.fParent.ui.act_canvas_show_internal.blockSignals(False) | |||
self.fParent.ui.act_canvas_show_external.blockSignals(False) | |||
self.slot_canvasRefresh() | |||
@pyqtSlot() | |||
def slot_canvasRefresh(self): | |||
patchcanvas.clear() | |||
if gCarla.host is not None and gCarla.host.is_engine_running(): | |||
gCarla.host.patchbay_refresh() | |||
gCarla.host.patchbay_refresh(gCarla.externalPatchbay) | |||
for pitem in self.fPluginList: | |||
if pitem is None: | |||
@@ -246,6 +246,8 @@ class CarlaObject(object): | |||
'transportMode', | |||
# current max parameters | |||
'maxParameters', | |||
# wherever to use external patchbay mode | |||
'externalPatchbay', | |||
# wherever to use custom skins | |||
'useCustomSkins', | |||
# binary dir | |||
@@ -276,6 +278,7 @@ gCarla.processMode = ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS if LINUX else EN | |||
gCarla.processModeForced = False | |||
gCarla.transportMode = ENGINE_TRANSPORT_MODE_JACK if LINUX else ENGINE_TRANSPORT_MODE_INTERNAL | |||
gCarla.maxParameters = MAX_DEFAULT_PARAMETERS | |||
gCarla.externalPatchbay = False | |||
gCarla.useCustomSkins = True | |||
gCarla.pathBinaries = "" | |||
gCarla.pathResources = "" | |||
@@ -275,7 +275,8 @@ class PluginHost(object): | |||
gCarla.gui.send(["patchbay_disconnect", connectionId]) | |||
return True | |||
def patchbay_refresh(self): | |||
def patchbay_refresh(self, external): | |||
# don't send external param, never used in plugins | |||
gCarla.gui.send(["patchbay_refresh"]) | |||
return True | |||