From d32eee00f559a0276c7b9f4738f0ac6eb56b7e4b Mon Sep 17 00:00:00 2001 From: falkTX Date: Sun, 20 May 2018 13:22:45 +0200 Subject: [PATCH] Implement up/down plugins in rack (right-click menu) Closes #152 --- source/backend/engine/CarlaEngineInternal.cpp | 19 +++++----- source/carla_host.py | 33 ++++++++++++++++- source/carla_skin.py | 34 ++++++++++++------ source/widgets/racklistwidget.py | 35 ++++++++++++++++--- 4 files changed, 96 insertions(+), 25 deletions(-) diff --git a/source/backend/engine/CarlaEngineInternal.cpp b/source/backend/engine/CarlaEngineInternal.cpp index 270aab500..29ff73149 100644 --- a/source/backend/engine/CarlaEngineInternal.cpp +++ b/source/backend/engine/CarlaEngineInternal.cpp @@ -633,17 +633,18 @@ void CarlaEngine::ProtectedData::doPluginsSwitch(const uint idA, const uint idB) CARLA_SAFE_ASSERT_RETURN(idA < curPluginCount,); CARLA_SAFE_ASSERT_RETURN(idB < curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(plugins[idA].plugin != nullptr,); - CARLA_SAFE_ASSERT_RETURN(plugins[idB].plugin != nullptr,); -#if 0 - std::swap(plugins[idA].plugin, plugins[idB].plugin); -#else - CarlaPlugin* const tmp(plugins[idA].plugin); + CarlaPlugin* const pluginA(plugins[idA].plugin); + CARLA_SAFE_ASSERT_RETURN(pluginA != nullptr,); - plugins[idA].plugin = plugins[idB].plugin; - plugins[idB].plugin = tmp; -#endif + CarlaPlugin* const pluginB(plugins[idB].plugin); + CARLA_SAFE_ASSERT_RETURN(pluginB != nullptr,); + + pluginA->setId(idB); + plugins[idA].plugin = pluginB; + + pluginB->setId(idA); + plugins[idB].plugin = pluginA; } #endif diff --git a/source/carla_host.py b/source/carla_host.py index d3f75520c..a68587e65 100644 --- a/source/carla_host.py +++ b/source/carla_host.py @@ -325,7 +325,7 @@ class HostWindow(QMainWindow): # ---------------------------------------------------------------------------------------------------- # Set up GUI (rack) - self.ui.listWidget.setHost(self.host) + self.ui.listWidget.setHostAndParent(self.host, self) sb = self.ui.listWidget.verticalScrollBar() self.ui.rackScrollBar.setMinimum(sb.minimum()) @@ -568,6 +568,34 @@ class HostWindow(QMainWindow): pitem.recreateWidget(True) + def switchPlugins(self, pluginIdA, pluginIdB): + if pluginIdA == pluginIdB: + return + if pluginIdA < 0 or pluginIdB < 0: + return + if pluginIdA >= self.fPluginCount or pluginIdB >= self.fPluginCount: + return + + useCustomSkins = self.fSavedSettings[CARLA_KEY_MAIN_USE_CUSTOM_SKINS] + + self.host.switch_plugins(pluginIdA, pluginIdB) + + itemA = self.fPluginList[pluginIdA] + compactA = itemA.isCompacted() + guiShownA = itemA.isGuiShown() + + itemB = self.fPluginList[pluginIdB] + compactB = itemB.isCompacted() + guiShownB = itemB.isGuiShown() + + itemA.setPluginId(pluginIdA) + itemA.recreateWidget2(compactB, guiShownB) + + itemB.setPluginId(pluginIdB) + itemB.recreateWidget2(compactA, guiShownA) + + self.slot_canvasRefresh() + def setLoadRDFsNeeded(self): self.fLadspaRdfNeedsUpdate = True @@ -2097,6 +2125,9 @@ class HostWindow(QMainWindow): # -------------------------------------------------------------------------------------------------------- + def getPluginCount(self): + return self.fPluginCount + def getPluginItem(self, pluginId): if pluginId >= self.fPluginCount: return None diff --git a/source/carla_skin.py b/source/carla_skin.py index f21c38da4..b4c28a721 100755 --- a/source/carla_skin.py +++ b/source/carla_skin.py @@ -225,6 +225,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): def __init__(self, parent, host, pluginId, skinStyle): QFrame.__init__(self, parent) self.host = host + self.fParent = parent if False: # kdevelop likes this :) @@ -297,6 +298,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): # ------------------------------------------------------------- # Set-up connections + self.customContextMenuRequested.connect(self.slot_showCustomMenu) host.PluginRenamedCallback.connect(self.slot_handlePluginRenamedCallback) host.PluginUnavailableCallback.connect(self.slot_handlePluginUnavailableCallback) host.ParameterValueChangedCallback.connect(self.slot_handleParameterValueChangedCallback) @@ -987,7 +989,7 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): self.setActive(yesNo, False, True) @pyqtSlot() - def slot_showDefaultCustomMenu(self): + def slot_showCustomMenu(self): menu = QMenu(self) # ------------------------------------------------------------- @@ -996,6 +998,17 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): actCompact = menu.addAction(self.tr("Expand") if isinstance(self, PluginSlot_Compact) else self.tr("Minimize")) menu.addSeparator() + # ------------------------------------------------------------- + # Move up and down + + actMoveUp = menu.addAction(self.tr("Move Up")) + actMoveDown = menu.addAction(self.tr("Move Down")) + + if self.fPluginId == 0: + actMoveUp.setEnabled(False) + if self.fPluginId >= self.fParent.getPluginCount(): + actMoveDown.setEnabled(False) + # ------------------------------------------------------------- # Bypass and Enable/Disable @@ -1069,6 +1082,15 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): # FIXME gCarla.gui.compactPlugin(self.fPluginId) + # ------------------------------------------------------------- + # Move up and down + + elif actSel == actMoveUp: + gCarla.gui.switchPlugins(self.fPluginId, self.fPluginId-1) + + elif actSel == actMoveDown: + gCarla.gui.switchPlugins(self.fPluginId, self.fPluginId+1) + # ------------------------------------------------------------- # Bypass and Enable/Disable @@ -1369,8 +1391,6 @@ class PluginSlot_Calf(AbstractPluginSlot): self.ui.led_midi.setColor(self.ui.led_midi.CALF) - self.customContextMenuRequested.connect(self.slot_showDefaultCustomMenu) - #------------------------------------------------------------------ def getFixedHeight(self): @@ -1434,8 +1454,6 @@ class PluginSlot_Classic(AbstractPluginSlot): self.ready() - self.customContextMenuRequested.connect(self.slot_showDefaultCustomMenu) - #------------------------------------------------------------------ def getFixedHeight(self): @@ -1516,8 +1534,6 @@ class PluginSlot_Compact(AbstractPluginSlot): self.ready() - self.customContextMenuRequested.connect(self.slot_showDefaultCustomMenu) - #------------------------------------------------------------------ def getFixedHeight(self): @@ -1554,8 +1570,6 @@ class PluginSlot_Default(AbstractPluginSlot): self.ready() - self.customContextMenuRequested.connect(self.slot_showDefaultCustomMenu) - #------------------------------------------------------------------ def getFixedHeight(self): @@ -1645,8 +1659,6 @@ class PluginSlot_Presets(AbstractPluginSlot): self.ready() - self.customContextMenuRequested.connect(self.slot_showDefaultCustomMenu) - if usingMidiPrograms: self.ui.cb_presets.currentIndexChanged.connect(self.slot_midiProgramChanged) else: diff --git a/source/widgets/racklistwidget.py b/source/widgets/racklistwidget.py index 942b0bfb3..5bb8703a1 100644 --- a/source/widgets/racklistwidget.py +++ b/source/widgets/racklistwidget.py @@ -121,6 +121,11 @@ class RackListItem(QListWidgetItem): def isUsingSkins(self): return self.fOptions['useSkins'] + def isGuiShown(self): + if self.fWidget is None or self.fWidget.b_gui is not None: + return None + return self.fWidget.b_gui.isChecked() + # -------------------------------------------------------------------------------------------------------- def setPluginId(self, pluginId): @@ -169,7 +174,7 @@ class RackListItem(QListWidgetItem): self.fWidget = createPluginSlot(self.fParent, self.host, self.fPluginId, self.fOptions) self.fWidget.setFixedHeight(self.fWidget.getFixedHeight()) - if wasGuiShown == True and self.fWidget.b_gui is not None: + if wasGuiShown and self.fWidget.b_gui is not None: self.fWidget.b_gui.setChecked(True) self.setSizeHint(QSize(self.kMinimumWidth, self.fWidget.getFixedHeight())) @@ -180,6 +185,24 @@ class RackListItem(QListWidgetItem): self.host.set_custom_data(self.fPluginId, CUSTOM_DATA_TYPE_PROPERTY, "CarlaSkinIsCompacted", "true" if self.fOptions['compact'] else "false") + def recreateWidget2(self, wasCompacted, wasGuiShown): + self.fOptions['compact'] = wasCompacted + + self.close() + + self.fWidget = createPluginSlot(self.fParent, self.host, self.fPluginId, self.fOptions) + self.fWidget.setFixedHeight(self.fWidget.getFixedHeight()) + + if wasGuiShown and self.fWidget.b_gui is not None: + self.fWidget.b_gui.setChecked(True) + + self.setSizeHint(QSize(self.kMinimumWidth, self.fWidget.getFixedHeight())) + + self.fParent.setItemWidget(self, self.fWidget) + + self.host.set_custom_data(self.fPluginId, CUSTOM_DATA_TYPE_PROPERTY, + "CarlaSkinIsCompacted", "true" if wasCompacted else "false") + # ------------------------------------------------------------------------------------------------------------ # Rack Widget @@ -187,12 +210,12 @@ class RackListWidget(QListWidget): def __init__(self, parent): QListWidget.__init__(self, parent) self.host = None + self.fParent = None if False: # kdevelop likes this :) from carla_backend import CarlaHostMeta - host = CarlaHostNull() - self.host = host + self.host = host = CarlaHostNull() exts = gCarla.utils.get_supported_file_extensions() @@ -221,8 +244,12 @@ class RackListWidget(QListWidget): def createItem(self, pluginId, useSkins): return RackListItem(self, pluginId, useSkins) - def setHost(self, host): + def getPluginCount(self): + return self.fParent.getPluginCount() + + def setHostAndParent(self, host, parent): self.host = host + self.fParent = parent # --------------------------------------------------------------------------------------------------------