| @@ -801,18 +801,18 @@ | |||
| </action> | |||
| </widget> | |||
| <customwidgets> | |||
| <customwidget> | |||
| <class>CanvasPreviewFrame</class> | |||
| <extends>QFrame</extends> | |||
| <header>canvaspreviewframe.h</header> | |||
| <container>1</container> | |||
| </customwidget> | |||
| <customwidget> | |||
| <class>DigitalPeakMeter</class> | |||
| <extends>QWidget</extends> | |||
| <header>digitalpeakmeter.h</header> | |||
| <container>1</container> | |||
| </customwidget> | |||
| <customwidget> | |||
| <class>CanvasPreviewFrame</class> | |||
| <extends>QFrame</extends> | |||
| <header>canvaspreviewframe.h</header> | |||
| <container>1</container> | |||
| </customwidget> | |||
| <customwidget> | |||
| <class>RackListWidget</class> | |||
| <extends>QListWidget</extends> | |||
| @@ -839,21 +839,5 @@ | |||
| </hint> | |||
| </hints> | |||
| </connection> | |||
| <connection> | |||
| <sender>act_settings_show_toolbar</sender> | |||
| <signal>triggered(bool)</signal> | |||
| <receiver>toolBar</receiver> | |||
| <slot>setVisible(bool)</slot> | |||
| <hints> | |||
| <hint type="sourcelabel"> | |||
| <x>-1</x> | |||
| <y>-1</y> | |||
| </hint> | |||
| <hint type="destinationlabel"> | |||
| <x>354</x> | |||
| <y>35</y> | |||
| </hint> | |||
| </hints> | |||
| </connection> | |||
| </connections> | |||
| </ui> | |||
| @@ -1205,11 +1205,9 @@ void CarlaEngine::setOption(const EngineOption option, const int value, const ch | |||
| if (isRunning() && (option == ENGINE_OPTION_PROCESS_MODE || option == ENGINE_OPTION_AUDIO_NUM_PERIODS || option == ENGINE_OPTION_AUDIO_DEVICE)) | |||
| return carla_stderr("CarlaEngine::setOption(%i:%s, %i, \"%s\") - Cannot set this option while engine is running!", option, EngineOption2Str(option), value, valueStr); | |||
| if (option == ENGINE_OPTION_FORCE_STEREO && pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK) | |||
| { | |||
| // do not un-force stereo for rack mode | |||
| CARLA_SAFE_ASSERT_RETURN(value == 1,); | |||
| } | |||
| // do not un-force stereo for rack mode | |||
| if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK && option == ENGINE_OPTION_FORCE_STEREO && value != 0) | |||
| return; | |||
| switch (option) | |||
| { | |||
| @@ -516,6 +516,8 @@ const CarlaStateSave& CarlaPlugin::getStateSave(const bool callPrepareForSave) | |||
| pData->stateSave.ctrlChannel = pData->ctrlChannel; | |||
| #endif | |||
| bool usingChunk = false; | |||
| // --------------------------------------------------------------- | |||
| // Chunk | |||
| @@ -526,10 +528,8 @@ const CarlaStateSave& CarlaPlugin::getStateSave(const bool callPrepareForSave) | |||
| if (data != nullptr && dataSize > 0) | |||
| { | |||
| usingChunk = true; | |||
| pData->stateSave.chunk = CarlaString::asBase64(data, dataSize).dup(); | |||
| // Don't save anything else if using chunks | |||
| return pData->stateSave; | |||
| } | |||
| } | |||
| @@ -565,10 +565,15 @@ const CarlaStateSave& CarlaPlugin::getStateSave(const bool callPrepareForSave) | |||
| if ((paramData.hints & PARAMETER_IS_ENABLED) == 0) | |||
| continue; | |||
| const bool dummy = paramData.type != PARAMETER_INPUT || usingChunk; | |||
| if (dummy && paramData.midiCC <= -1) | |||
| continue; | |||
| CarlaStateSave::Parameter* const stateParameter(new CarlaStateSave::Parameter()); | |||
| stateParameter->isInput = (paramData.type == PARAMETER_INPUT); | |||
| stateParameter->index = paramData.index; | |||
| stateParameter->dummy = dummy; | |||
| stateParameter->index = paramData.index; | |||
| #ifndef BUILD_BRIDGE | |||
| stateParameter->midiCC = paramData.midiCC; | |||
| stateParameter->midiChannel = paramData.midiChannel; | |||
| @@ -580,10 +585,13 @@ const CarlaStateSave& CarlaPlugin::getStateSave(const bool callPrepareForSave) | |||
| getParameterSymbol(i, strBuf); | |||
| stateParameter->symbol = carla_strdup(strBuf);; | |||
| stateParameter->value = getParameterValue(i); | |||
| if (! dummy) | |||
| { | |||
| stateParameter->value = getParameterValue(i); | |||
| if (paramData.hints & PARAMETER_USES_SAMPLERATE) | |||
| stateParameter->value /= sampleRate; | |||
| if (paramData.hints & PARAMETER_USES_SAMPLERATE) | |||
| stateParameter->value /= sampleRate; | |||
| } | |||
| pData->stateSave.parameters.append(stateParameter); | |||
| } | |||
| @@ -614,7 +622,7 @@ void CarlaPlugin::loadStateSave(const CarlaStateSave& stateSave) | |||
| const bool usesMultiProgs(pData->extraHints & PLUGIN_EXTRA_HINT_USES_MULTI_PROGS); | |||
| // --------------------------------------------------------------- | |||
| // Part 1 - PRE-set custom data (only that which reload programs) | |||
| // Part 1 - PRE-set custom data (only those which reload programs) | |||
| for (CarlaStateSave::CustomDataItenerator it = stateSave.customData.begin(); it.valid(); it.next()) | |||
| { | |||
| @@ -761,7 +769,7 @@ void CarlaPlugin::loadStateSave(const CarlaStateSave& stateSave) | |||
| { | |||
| //CARLA_SAFE_ASSERT(stateParameter->isInput == (pData | |||
| if (stateParameter->isInput) | |||
| if (! stateParameter->dummy) | |||
| { | |||
| if (pData->param.data[index].hints & PARAMETER_USES_SAMPLERATE) | |||
| stateParameter->value *= sampleRate; | |||
| @@ -836,7 +844,6 @@ void CarlaPlugin::loadStateSave(const CarlaStateSave& stateSave) | |||
| if (availOptions & option) | |||
| setOption(option, (stateSave.options & option) != 0, true); | |||
| } | |||
| setDryWet(stateSave.dryWet, true, true); | |||
| @@ -345,6 +345,7 @@ class HostWindow(QMainWindow): | |||
| self.ui.act_canvas_arrange.setEnabled(False) # TODO, later | |||
| self.ui.act_settings_show_time_panel.toggled.connect(self.slot_showTimePanel) | |||
| self.ui.act_settings_show_toolbar.toggled.connect(self.slot_showToolbar) | |||
| self.ui.act_settings_show_meters.toggled.connect(self.slot_showCanvasMeters) | |||
| self.ui.act_settings_show_keyboard.toggled.connect(self.slot_showCanvasKeyboard) | |||
| self.ui.act_settings_configure.triggered.connect(self.slot_configureCarla) | |||
| @@ -1246,7 +1247,7 @@ class HostWindow(QMainWindow): | |||
| if not self.host.isPlugin: | |||
| settings.setValue("ShowTimePanel", self.ui.panelTime.isVisible()) | |||
| settings.setValue("ShowToolbar", self.ui.toolBar.isVisible()) | |||
| settings.setValue("ShowToolbar", self.ui.toolBar.isEnabled()) | |||
| diskFolders = [] | |||
| @@ -1279,6 +1280,7 @@ class HostWindow(QMainWindow): | |||
| showToolbar = settings.value("ShowToolbar", True, type=bool) | |||
| self.ui.act_settings_show_toolbar.setChecked(showToolbar) | |||
| self.ui.toolBar.setEnabled(showToolbar) | |||
| self.ui.toolBar.setVisible(showToolbar) | |||
| #if settings.contains("SplitterState"): | |||
| @@ -1349,6 +1351,11 @@ class HostWindow(QMainWindow): | |||
| def slot_showTimePanel(self, yesNo): | |||
| self.ui.panelTime.setVisible(yesNo) | |||
| @pyqtSlot(bool) | |||
| def slot_showToolbar(self, yesNo): | |||
| self.ui.toolBar.setEnabled(yesNo) | |||
| self.ui.toolBar.setVisible(yesNo) | |||
| @pyqtSlot(bool) | |||
| def slot_showCanvasMeters(self, yesNo): | |||
| self.ui.peak_in.setVisible(yesNo) | |||
| @@ -1378,6 +1385,12 @@ class HostWindow(QMainWindow): | |||
| elif self.host.is_engine_running(): | |||
| self.host.patchbay_refresh(self.fExternalPatchbay) | |||
| for pitem in self.fPluginList: | |||
| if pitem is None: | |||
| break | |||
| pitem.setUsingSkins(self.fSavedSettings[CARLA_KEY_MAIN_USE_CUSTOM_SKINS]) | |||
| pitem.recreateWidget() | |||
| # -------------------------------------------------------------------------------------------------------- | |||
| # About (menu actions) | |||
| @@ -1955,6 +1968,12 @@ def canvasCallback(action, value1, value2, valueStr): | |||
| host.show_custom_ui(pluginId, True) | |||
| # FIXME | |||
| pwidget = gCarla.gui.getPluginSlotWidget(pluginId) | |||
| if pwidget is not None and pwidget.b_gui is not None: | |||
| pwidget.b_gui.setChecked(True) | |||
| # ------------------------------------------------------------------------------------------------------------ | |||
| # Engine callback | |||
| @@ -245,6 +245,9 @@ class CarlaSettingsW(QDialog): | |||
| self.ui.cb_engine_process_mode_jack.setEnabled(False) | |||
| self.ui.cb_engine_process_mode_other.setEnabled(False) | |||
| if self.host.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK: | |||
| self.ui.ch_engine_force_stereo.setEnabled(False) | |||
| # FIXME, not implemented yet | |||
| self.ui.ch_engine_uis_always_on_top.hide() | |||
| @@ -352,7 +355,7 @@ class CarlaSettingsW(QDialog): | |||
| self.ui.ch_engine_uis_always_on_top.setChecked(self.host.uisAlwaysOnTop) | |||
| self.ui.ch_engine_prefer_ui_bridges.setChecked(self.host.preferUIBridges) | |||
| self.ui.sb_engine_ui_bridges_timeout.setValue(self.host.uiBridgesTimeout) | |||
| self.ui.ch_engine_force_stereo.setChecked(self.host.forceStereo) | |||
| self.ui.ch_engine_force_stereo.setChecked(self.host.forceStereo or not self.ui.ch_engine_force_stereo.isEnabled()) | |||
| self.ui.ch_engine_prefer_plugin_bridges.setChecked(self.host.preferPluginBridges) | |||
| # ---------------------------------------------------------------------------------------------------- | |||
| @@ -459,14 +462,18 @@ class CarlaSettingsW(QDialog): | |||
| self.host.maxParameters = self.ui.sb_engine_max_params.value() | |||
| self.host.uiBridgesTimeout = self.ui.sb_engine_ui_bridges_timeout.value() | |||
| self.host.set_engine_option(ENGINE_OPTION_FORCE_STEREO, self.host.forceStereo, "") | |||
| if self.ui.ch_engine_force_stereo.isEnabled(): | |||
| self.host.set_engine_option(ENGINE_OPTION_FORCE_STEREO, self.host.forceStereo, "") | |||
| self.host.set_engine_option(ENGINE_OPTION_PREFER_PLUGIN_BRIDGES, self.host.preferPluginBridges, "") | |||
| self.host.set_engine_option(ENGINE_OPTION_PREFER_UI_BRIDGES, self.host.preferUIBridges, "") | |||
| self.host.set_engine_option(ENGINE_OPTION_UIS_ALWAYS_ON_TOP, self.host.uisAlwaysOnTop, "") | |||
| self.host.set_engine_option(ENGINE_OPTION_MAX_PARAMETERS, self.host.maxParameters, "") | |||
| self.host.set_engine_option(ENGINE_OPTION_UI_BRIDGES_TIMEOUT, self.host.uiBridgesTimeout, "") | |||
| settings.setValue(CARLA_KEY_ENGINE_FORCE_STEREO, self.host.forceStereo) | |||
| if self.ui.ch_engine_force_stereo.isEnabled(): | |||
| settings.setValue(CARLA_KEY_ENGINE_FORCE_STEREO, self.host.forceStereo) | |||
| settings.setValue(CARLA_KEY_ENGINE_PREFER_PLUGIN_BRIDGES, self.host.preferPluginBridges) | |||
| settings.setValue(CARLA_KEY_ENGINE_PREFER_UI_BRIDGES, self.host.preferUIBridges) | |||
| settings.setValue(CARLA_KEY_ENGINE_UIS_ALWAYS_ON_TOP, self.host.uisAlwaysOnTop) | |||
| @@ -1166,6 +1166,12 @@ class AbstractPluginSlot(QFrame, PluginEditParentMeta): | |||
| #------------------------------------------------------------------ | |||
| def mouseDoubleClickEvent(self, event): | |||
| QFrame.mouseDoubleClickEvent(self, event) | |||
| # FIXME | |||
| gCarla.gui.compactPlugin(self.fPluginId) | |||
| def closeEvent(self, event): | |||
| if self.fIdleTimerId != 0: | |||
| self.killTimer(self.fIdleTimerId) | |||
| @@ -113,6 +113,10 @@ class CarlaMiniW(ExternalUI, HostWindow): | |||
| def uiQuit(self): | |||
| self.closeExternalUI() | |||
| self.close() | |||
| if self != gui: | |||
| gui.close() | |||
| app.quit() | |||
| def uiTitleChanged(self, uiTitle): | |||
| @@ -123,6 +127,10 @@ class CarlaMiniW(ExternalUI, HostWindow): | |||
| def closeEvent(self, event): | |||
| self.closeExternalUI() | |||
| if self != gui: | |||
| gui.close() | |||
| HostWindow.closeEvent(self, event) | |||
| # ------------------------------------------------------------------- | |||
| @@ -116,7 +116,7 @@ static const char* xmlSafeStringCharDup(const String& string, const bool toXml) | |||
| // StateParameter | |||
| CarlaStateSave::Parameter::Parameter() noexcept | |||
| : isInput(true), | |||
| : dummy(true), | |||
| index(-1), | |||
| name(nullptr), | |||
| symbol(nullptr), | |||
| @@ -426,9 +426,9 @@ bool CarlaStateSave::fillFromXmlElement(const XmlElement* const xmlElement) | |||
| } | |||
| else if (pTag.equalsIgnoreCase("value")) | |||
| { | |||
| stateParameter->dummy = false; | |||
| stateParameter->value = pText.getFloatValue(); | |||
| } | |||
| #ifndef BUILD_BRIDGE | |||
| else if (pTag.equalsIgnoreCase("midichannel") || pTag.equalsIgnoreCase("midi-channel")) | |||
| { | |||
| @@ -590,9 +590,6 @@ String CarlaStateSave::toString() const | |||
| if (stateParameter->symbol != nullptr && stateParameter->symbol[0] != '\0') | |||
| parameterXml << " <Symbol>" << xmlSafeString(stateParameter->symbol, true) << "</Symbol>\n"; | |||
| if (stateParameter->isInput) | |||
| parameterXml << " <Value>" << String(stateParameter->value, 15) << "</Value>\n"; | |||
| #ifndef BUILD_BRIDGE | |||
| if (stateParameter->midiCC > 0) | |||
| { | |||
| @@ -601,6 +598,9 @@ String CarlaStateSave::toString() const | |||
| } | |||
| #endif | |||
| if (! stateParameter->dummy) | |||
| parameterXml << " <Value>" << String(stateParameter->value, 15) << "</Value>\n"; | |||
| parameterXml << " </Parameter>\n"; | |||
| content << parameterXml; | |||
| @@ -29,7 +29,7 @@ CARLA_BACKEND_START_NAMESPACE | |||
| struct CarlaStateSave { | |||
| struct Parameter { | |||
| bool isInput; | |||
| bool dummy; // if true only midiChannel/CC are used | |||
| int32_t index; | |||
| const char* name; | |||
| const char* symbol; | |||
| @@ -103,9 +103,6 @@ class RackListItem(QListWidgetItem): | |||
| widget.deleteLater() | |||
| del widget | |||
| def isCompacted(self): | |||
| return self.fOptions['compact'] | |||
| def getEditDialog(self): | |||
| if self.fWidget is None: | |||
| return None | |||
| @@ -118,6 +115,12 @@ class RackListItem(QListWidgetItem): | |||
| def getWidget(self): | |||
| return self.fWidget | |||
| def isCompacted(self): | |||
| return self.fOptions['compact'] | |||
| def isUsingSkins(self): | |||
| return self.fOptions['useSkins'] | |||
| # -------------------------------------------------------------------------------------------------------- | |||
| def setPluginId(self, pluginId): | |||
| @@ -134,15 +137,31 @@ class RackListItem(QListWidgetItem): | |||
| # -------------------------------------------------------------------------------------------------------- | |||
| def setCompacted(self, compact): | |||
| self.fOptions['compact'] = compact | |||
| def setUsingSkins(self, useSkins): | |||
| self.fOptions['useSkins'] = useSkins | |||
| # -------------------------------------------------------------------------------------------------------- | |||
| def recreateWidget(self, invertCompactOption = False, firstInit = False): | |||
| if invertCompactOption: | |||
| self.fOptions['compact'] = not self.fOptions['compact'] | |||
| wasGuiShown = None | |||
| if self.fWidget is not None and self.fWidget.b_gui is not None: | |||
| wasGuiShown = self.fWidget.b_gui.isChecked() | |||
| self.close() | |||
| 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: | |||
| self.fWidget.b_gui.setChecked(True) | |||
| self.setSizeHint(QSize(self.kMinimumWidth, self.fWidget.getFixedHeight())) | |||
| self.fParent.setItemWidget(self, self.fWidget) | |||
| @@ -167,12 +186,12 @@ class RackListWidget(QListWidget): | |||
| exts = gCarla.utils.get_supported_file_extensions().split(";") | |||
| exts.append(".dll") | |||
| #exts.append(".dll") | |||
| if MACOS: | |||
| exts.append(".dylib") | |||
| if not WINDOWS: | |||
| exts.append(".so") | |||
| #if MACOS: | |||
| #exts.append(".dylib") | |||
| #if not WINDOWS: | |||
| #exts.append(".so") | |||
| self.fSupportedExtensions = tuple(i.replace("*","").lower() for i in exts) | |||
| self.fLastSelectedItem = None | |||
| @@ -212,13 +231,13 @@ class RackListWidget(QListWidget): | |||
| def isDragUrlValid(self, url): | |||
| filename = url.toLocalFile() | |||
| if os.path.isdir(filename): | |||
| if os.path.exists(os.path.join(filename, "manifest.ttl")): | |||
| return True | |||
| if MACOS and filename.lower().endswith((".vst", ".vst3")): | |||
| return True | |||
| #if os.path.isdir(filename): | |||
| #if os.path.exists(os.path.join(filename, "manifest.ttl")): | |||
| #return True | |||
| #if MACOS and filename.lower().endswith((".vst", ".vst3")): | |||
| #return True | |||
| elif os.path.isfile(filename): | |||
| if os.path.isfile(filename): | |||
| if filename.lower().endswith(self.fSupportedExtensions): | |||
| return True | |||