diff --git a/source/backend/CarlaBackend.hpp b/source/backend/CarlaBackend.hpp index 8667441c4..f5584505a 100644 --- a/source/backend/CarlaBackend.hpp +++ b/source/backend/CarlaBackend.hpp @@ -614,35 +614,46 @@ enum CallbackType : int { */ CALLBACK_PROCESS_MODE_CHANGED = 29, + /*! + * Engine started. + * \param valuestr Engine driver + */ + CALLBACK_ENGINE_STARTED = 30, + + /*! + * Engine stopped. + */ + CALLBACK_ENGINE_STOPPED = 31, + /*! * Non-Session-Manager Announce message. */ - CALLBACK_NSM_ANNOUNCE = 30, + CALLBACK_NSM_ANNOUNCE = 32, /*! * Non-Session-Manager Open message. */ - CALLBACK_NSM_OPEN = 31, + CALLBACK_NSM_OPEN = 33, /*! * Non-Session-Manager Save message. */ - CALLBACK_NSM_SAVE = 32, + CALLBACK_NSM_SAVE = 34, /*! * An error occurred, show \a valueStr as an error to user. */ - CALLBACK_ERROR = 33, + CALLBACK_ERROR = 35, /*! * Show \a valueStr as info to user. */ - CALLBACK_INFO = 34, + CALLBACK_INFO = 36, /*! * The engine has crashed or malfunctioned and will no longer work. */ - CALLBACK_QUIT = 35 + CALLBACK_QUIT = 37 }; /*! diff --git a/source/carla.py b/source/carla.py index cbe7bf83f..9f82bf1f6 100755 --- a/source/carla.py +++ b/source/carla.py @@ -72,13 +72,6 @@ class CarlaMainW(QMainWindow): self.fFirstEngineInit = True - self.fProjectFilename = None - - # ------------------------------------------------------------- - # Load Settings - - self.loadSettings(True) - # ------------------------------------------------------------- # Set-up GUI stuff @@ -123,44 +116,6 @@ class CarlaMainW(QMainWindow): self.ui.miniCanvasPreview.init(self.scene, DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT, self.fSavedSettings["UseCustomMiniCanvasPaint"]) QTimer.singleShot(100, self, SLOT("slot_miniCanvasInit()")) - # ------------------------------------------------------------- - # Connect actions to functions - - self.setProperWindowTitle() - - if NSM_URL: - Carla.host.nsm_ready() - else: - QTimer.singleShot(0, self, SLOT("slot_engineStart()")) - - def loadProject(self, filename): - self.fProjectFilename = filename - self.setProperWindowTitle() - - self.fProjectLoading = True - Carla.host.load_project(filename) - self.fProjectLoading = False - - def loadProjectLater(self, filename): - self.fProjectFilename = filename - self.setProperWindowTitle() - QTimer.singleShot(0, self, SLOT("slot_loadProjectLater()")) - - def saveProject(self, filename): - self.fProjectFilename = filename - self.setProperWindowTitle() - Carla.host.save_project(filename) - - def setProperWindowTitle(self): - title = LADISH_APP_NAME if LADISH_APP_NAME else "Carla" - - if self.fProjectFilename: - title += " - %s" % os.path.basename(self.fProjectFilename) - if self.fSessionManagerName: - title += " (%s)" % self.fSessionManagerName - - self.setWindowTitle(title) - def updateInfoLabelPos(self): tabBar = self.ui.tabMain.tabBar() y = tabBar.mapFromParent(self.ui.centralwidget.pos()).y()+tabBar.height()/4 @@ -174,43 +129,6 @@ class CarlaMainW(QMainWindow): tabBar = self.ui.tabMain.tabBar() self.fInfoLabel.resize(self.ui.tabMain.width()-tabBar.width()-20, self.fInfoLabel.height()) - @pyqtSlot() - def slot_fileNew(self): - self.removeAllPlugins() - self.fProjectFilename = None - self.fProjectLoading = False - self.setProperWindowTitle() - - @pyqtSlot() - def slot_fileOpen(self): - fileFilter = self.tr("Carla Project File (*.carxp)") - filenameTry = QFileDialog.getOpenFileName(self, self.tr("Open Carla Project File"), self.fSavedSettings["Main/DefaultProjectFolder"], filter=fileFilter) - - if filenameTry: - # FIXME - show dialog to user (remove all plugins?) - self.removeAllPlugins() - self.loadProject(filenameTry) - - @pyqtSlot() - def slot_fileSave(self, saveAs=False): - if self.fProjectFilename and not saveAs: - return self.saveProject(self.fProjectFilename) - - fileFilter = self.tr("Carla Project File (*.carxp)") - filenameTry = QFileDialog.getSaveFileName(self, self.tr("Save Carla Project File"), self.fSavedSettings["Main/DefaultProjectFolder"], filter=fileFilter) - - if not filenameTry: - return - - if not filenameTry.endswith(".carxp"): - filenameTry += ".carxp" - - self.saveProject(filenameTry) - - @pyqtSlot() - def slot_fileSaveAs(self): - self.slot_fileSave(True) - @pyqtSlot() def slot_fileExportLv2Preset(self): fileFilter = self.tr("LV2 Preset (*.lv2)") @@ -263,12 +181,6 @@ class CarlaMainW(QMainWindow): """ % (manifestPath, os.path.basename(filenameTry), presetContents)) manifestFd.close() - @pyqtSlot() - def slot_loadProjectLater(self): - self.fProjectLoading = True - Carla.host.load_project(self.fProjectFilename) - self.fProjectLoading = False - @pyqtSlot() def slot_toolbarShown(self): self.updateInfoLabelPos() @@ -416,92 +328,6 @@ class CarlaMainW(QMainWindow): self.tr("Engine has been stopped or crashed.\nPlease restart Carla"), self.tr("You may want to save your session now..."), QMessageBox.Ok, QMessageBox.Ok) - def loadSettings(self, geometry): - settings = QSettings() - - if geometry: - self.restoreGeometry(settings.value("Geometry", "")) - - showToolbar = settings.value("ShowToolbar", True, type=bool) - self.ui.act_settings_show_toolbar.setChecked(showToolbar) - self.ui.toolBar.setVisible(showToolbar) - - if settings.contains("SplitterState"): - self.ui.splitter.restoreState(settings.value("SplitterState", "")) - else: - self.ui.splitter.setSizes([99999, 210]) - - diskFolders = toList(settings.value("DiskFolders", [HOME])) - - self.ui.cb_disk.setItemData(0, HOME) - - for i in range(len(diskFolders)): - if i == 0: continue - folder = diskFolders[i] - self.ui.cb_disk.addItem(os.path.basename(folder), folder) - - if MACOS and not settings.value("Main/UseProTheme", True, type=bool): - self.setUnifiedTitleAndToolBarOnMac(True) - - useCustomMiniCanvasPaint = bool(settings.value("Main/UseProTheme", True, type=bool) and - settings.value("Main/ProThemeColor", "Black", type=str) == "Black") - - self.fSavedSettings = { - "Main/DefaultProjectFolder": settings.value("Main/DefaultProjectFolder", HOME, type=str), - "Main/RefreshInterval": settings.value("Main/RefreshInterval", 50, type=int), - "Canvas/Theme": settings.value("Canvas/Theme", patchcanvas.getDefaultThemeName(), type=str), - "Canvas/AutoHideGroups": settings.value("Canvas/AutoHideGroups", False, type=bool), - "Canvas/UseBezierLines": settings.value("Canvas/UseBezierLines", True, type=bool), - "Canvas/EyeCandy": settings.value("Canvas/EyeCandy", patchcanvas.EYECANDY_SMALL, type=int), - "Canvas/UseOpenGL": settings.value("Canvas/UseOpenGL", False, type=bool), - "Canvas/Antialiasing": settings.value("Canvas/Antialiasing", patchcanvas.ANTIALIASING_SMALL, type=int), - "Canvas/HighQualityAntialiasing": settings.value("Canvas/HighQualityAntialiasing", False, type=bool), - "UseCustomMiniCanvasPaint": useCustomMiniCanvasPaint - } - - # --------------------------------------------- - # plugin checks - - if settings.value("Engine/DisableChecks", False, type=bool): - os.environ["CARLA_DISCOVERY_NO_PROCESSING_CHECKS"] = "true" - - elif os.getenv("CARLA_DISCOVERY_NO_PROCESSING_CHECKS"): - os.environ.pop("CARLA_DISCOVERY_NO_PROCESSING_CHECKS") - - # --------------------------------------------- - # plugin paths - - Carla.LADSPA_PATH = toList(settings.value("Paths/LADSPA", Carla.LADSPA_PATH)) - Carla.DSSI_PATH = toList(settings.value("Paths/DSSI", Carla.DSSI_PATH)) - Carla.LV2_PATH = toList(settings.value("Paths/LV2", Carla.LV2_PATH)) - Carla.VST_PATH = toList(settings.value("Paths/VST", Carla.VST_PATH)) - Carla.GIG_PATH = toList(settings.value("Paths/GIG", Carla.GIG_PATH)) - Carla.SF2_PATH = toList(settings.value("Paths/SF2", Carla.SF2_PATH)) - Carla.SFZ_PATH = toList(settings.value("Paths/SFZ", Carla.SFZ_PATH)) - - os.environ["LADSPA_PATH"] = splitter.join(Carla.LADSPA_PATH) - os.environ["DSSI_PATH"] = splitter.join(Carla.DSSI_PATH) - os.environ["LV2_PATH"] = splitter.join(Carla.LV2_PATH) - os.environ["VST_PATH"] = splitter.join(Carla.VST_PATH) - os.environ["GIG_PATH"] = splitter.join(Carla.GIG_PATH) - os.environ["SF2_PATH"] = splitter.join(Carla.SF2_PATH) - os.environ["SFZ_PATH"] = splitter.join(Carla.SFZ_PATH) - - def saveSettings(self): - settings = QSettings() - settings.setValue("Geometry", self.saveGeometry()) - settings.setValue("SplitterState", self.ui.splitter.saveState()) - settings.setValue("ShowToolbar", self.ui.toolBar.isVisible()) - settings.setValue("HorizontalScrollBarValue", self.ui.graphicsView.horizontalScrollBar().value()) - settings.setValue("VerticalScrollBarValue", self.ui.graphicsView.verticalScrollBar().value()) - - diskFolders = [] - - for i in range(self.ui.cb_disk.count()): - diskFolders.append(self.ui.cb_disk.itemData(i)) - - settings.setValue("DiskFolders", diskFolders) - def dragEnterEvent(self, event): if event.source() == self.ui.fileTreeView: event.accept() diff --git a/source/carla_backend.py b/source/carla_backend.py index b686ded96..e02247df8 100644 --- a/source/carla_backend.py +++ b/source/carla_backend.py @@ -261,12 +261,14 @@ CALLBACK_PATCHBAY_ICON_CHANGED = 26 CALLBACK_BUFFER_SIZE_CHANGED = 27 CALLBACK_SAMPLE_RATE_CHANGED = 28 CALLBACK_PROCESS_MODE_CHANGED = 29 -CALLBACK_NSM_ANNOUNCE = 30 -CALLBACK_NSM_OPEN = 31 -CALLBACK_NSM_SAVE = 32 -CALLBACK_ERROR = 33 -CALLBACK_INFO = 34 -CALLBACK_QUIT = 35 +CALLBACK_ENGINE_STARTED = 30 +CALLBACK_ENGINE_STOPPED = 31 +CALLBACK_NSM_ANNOUNCE = 32 +CALLBACK_NSM_OPEN = 33 +CALLBACK_NSM_SAVE = 34 +CALLBACK_ERROR = 35 +CALLBACK_INFO = 36 +CALLBACK_QUIT = 37 # Process Mode PROCESS_MODE_SINGLE_CLIENT = 0 diff --git a/source/carla_host.py b/source/carla_host.py index c6ebab5c3..f56297ac9 100644 --- a/source/carla_host.py +++ b/source/carla_host.py @@ -20,8 +20,10 @@ # Imports (Global) try: + from PyQt5.QtCore import QTimer from PyQt5.QtWidgets import QApplication, QMainWindow except: + from PyQt4.QtCore import QTimer from PyQt4.QtGui import QApplication, QMainWindow # ------------------------------------------------------------------------------------------------------------ @@ -33,6 +35,13 @@ from carla_database import * from carla_settings import * from carla_widgets import * +# ------------------------------------------------------------------------------------------------------------ +# PatchCanvas defines + +CANVAS_ANTIALIASING_SMALL = 1 +CANVAS_EYECANDY_SMALL = 1 +CANVAS_DEFAULT_THEME_NAME = "Modern Dark" + # ------------------------------------------------------------------------------------------------------------ # Session Management support @@ -81,6 +90,11 @@ class CarlaDummyW(object): def idleSlow(self): pass + # ----------------------------------------------------------------- + + def saveSettings(self, settings): + pass + # ------------------------------------------------------------------------------------------------------------ # Host Window @@ -115,6 +129,9 @@ class HostWindow(QMainWindow): PatchbayIconChangedCallback = pyqtSignal(int, int) BufferSizeChangedCallback = pyqtSignal(int) SampleRateChangedCallback = pyqtSignal(float) + ProcessModeChangedCallback = pyqtSignal(int) + EngineStartedCallback = pyqtSignal(str) + EngineStoppedChangedCallback = pyqtSignal() NSM_AnnounceCallback = pyqtSignal(str) NSM_OpenCallback = pyqtSignal(str) NSM_SaveCallback = pyqtSignal() @@ -145,7 +162,9 @@ class HostWindow(QMainWindow): self.fIdleTimerFast = 0 self.fIdleTimerSlow = 0 + self.fIsProjectLoading = False + self.fProjectFilename = "" self.fLadspaRdfNeedsUpdate = True self.fLadspaRdfList = [] @@ -153,6 +172,8 @@ class HostWindow(QMainWindow): self.fLastTransportFrame = 0 self.fLastTransportState = False + self.fSavedSettings = {} + if LADISH_APP_NAME: self.fClientName = LADISH_APP_NAME self.fSessionManagerName = "LADISH" @@ -163,6 +184,11 @@ class HostWindow(QMainWindow): self.fClientName = "Carla" self.fSessionManagerName = "" + # ------------------------------------------------------------- + # Load Settings + + self.loadSettings(True) + # ------------------------------------------------------------- # Set up GUI (engine stopped) @@ -176,13 +202,15 @@ class HostWindow(QMainWindow): self.setTransportMenuEnabled(False) + self.setProperWindowTitle() + # ------------------------------------------------------------- # Connect actions to functions - #self.ui.act_file_new.triggered.connect(self.slot_fileNew) - #self.ui.act_file_open.triggered.connect(self.slot_fileOpen) - #self.ui.act_file_save.triggered.connect(self.slot_fileSave) - #self.ui.act_file_save_as.triggered.connect(self.slot_fileSaveAs) + self.ui.act_file_new.triggered.connect(self.slot_fileNew) + self.ui.act_file_open.triggered.connect(self.slot_fileOpen) + self.ui.act_file_save.triggered.connect(self.slot_fileSave) + self.ui.act_file_save_as.triggered.connect(self.slot_fileSaveAs) self.ui.act_engine_start.triggered.connect(self.slot_engineStart) self.ui.act_engine_stop.triggered.connect(self.slot_engineStop) @@ -212,6 +240,8 @@ class HostWindow(QMainWindow): self.PluginRenamedCallback.connect(self.slot_handlePluginRenamedCallback) self.BufferSizeChangedCallback.connect(self.slot_handleBufferSizeChangedCallback) self.SampleRateChangedCallback.connect(self.slot_handleSampleRateChangedCallback) + self.EngineStartedCallback.connect(self.slot_handleEngineStartedCallback) + self.EngineStoppedChangedCallback.connect(self.slot_handleEngineStoppedCallback) #self.NSM_AnnounceCallback.connect(self.slot_handleNSM_AnnounceCallback) #self.NSM_OpenCallback.connect(self.slot_handleNSM_OpenCallback) #self.NSM_SaveCallback.connect(self.slot_handleNSM_SaveCallback) @@ -221,22 +251,167 @@ class HostWindow(QMainWindow): self.SIGUSR1.connect(self.slot_handleSIGUSR1) self.SIGTERM.connect(self.slot_handleSIGTERM) + # ------------------------------------------------------------- + # Final setup + + if NSM_URL: + Carla.host.nsm_ready() + #else: + #QTimer.singleShot(0, self.slot_engineStart) + # ----------------------------------------------------------------- # Called by containers - def openSettings(self, hasCanvas, hasCanvasGL): + def openSettingsWindow(self, hasCanvas, hasCanvasGL): dialog = CarlaSettingsW(self, hasCanvas, hasCanvasGL) return dialog.exec_() - # ----------------------------------------------------------------- - # Internal stuff + def loadSettings(self, doGeometry): + settings = QSettings() + + if doGeometry: + self.restoreGeometry(settings.value("Geometry", "")) + + showToolbar = settings.value("ShowToolbar", True, type=bool) + self.ui.act_settings_show_toolbar.setChecked(showToolbar) + self.ui.toolBar.setVisible(showToolbar) + + #if settings.contains("SplitterState"): + #self.ui.splitter.restoreState(settings.value("SplitterState", "")) + #else: + #self.ui.splitter.setSizes([99999, 210]) + + #diskFolders = toList(settings.value("DiskFolders", [HOME])) + + #self.ui.cb_disk.setItemData(0, HOME) + + #for i in range(len(diskFolders)): + #if i == 0: continue + #folder = diskFolders[i] + #self.ui.cb_disk.addItem(os.path.basename(folder), folder) + + if MACOS and not settings.value("Main/UseProTheme", True, type=bool): + self.setUnifiedTitleAndToolBarOnMac(True) + + useCustomMiniCanvasPaint = bool(settings.value("Main/UseProTheme", True, type=bool) and + settings.value("Main/ProThemeColor", "Black", type=str) == "Black") + + # --------------------------------------------- + # engine + + self.setEngineSettings(settings) + + # --------------------------------------------- + # plugin checks + + if settings.value("Engine/DisableChecks", False, type=bool): + os.environ["CARLA_DISCOVERY_NO_PROCESSING_CHECKS"] = "true" + + elif os.getenv("CARLA_DISCOVERY_NO_PROCESSING_CHECKS"): + os.environ.pop("CARLA_DISCOVERY_NO_PROCESSING_CHECKS") + + # --------------------------------------------- + # plugin paths + + LADSPA_PATH = toList(settings.value("Paths/LADSPA", Carla.DEFAULT_LADSPA_PATH)) + DSSI_PATH = toList(settings.value("Paths/DSSI", Carla.DEFAULT_DSSI_PATH)) + LV2_PATH = toList(settings.value("Paths/LV2", Carla.DEFAULT_LV2_PATH)) + VST_PATH = toList(settings.value("Paths/VST", Carla.DEFAULT_VST_PATH)) + AU_PATH = toList(settings.value("Paths/AU", Carla.DEFAULT_AU_PATH)) + CSOUND_PATH = toList(settings.value("Paths/CSOUND", Carla.DEFAULT_CSOUND_PATH)) + GIG_PATH = toList(settings.value("Paths/GIG", Carla.DEFAULT_GIG_PATH)) + SF2_PATH = toList(settings.value("Paths/SF2", Carla.DEFAULT_SF2_PATH)) + SFZ_PATH = toList(settings.value("Paths/SFZ", Carla.DEFAULT_SFZ_PATH)) + + os.environ["LADSPA_PATH"] = splitter.join(LADSPA_PATH) + os.environ["DSSI_PATH"] = splitter.join(DSSI_PATH) + os.environ["LV2_PATH"] = splitter.join(LV2_PATH) + os.environ["VST_PATH"] = splitter.join(VST_PATH) + os.environ["AU_PATH"] = splitter.join(AU_PATH) + os.environ["CSOUND_PATH"] = splitter.join(CSOUND_PATH) + os.environ["GIG_PATH"] = splitter.join(GIG_PATH) + os.environ["SF2_PATH"] = splitter.join(SF2_PATH) + os.environ["SFZ_PATH"] = splitter.join(SFZ_PATH) - def startEngine(self): # --------------------------------------------- - # Engine settings + self.fSavedSettings = { + "Main/DefaultProjectFolder": settings.value("Main/DefaultProjectFolder", HOME, type=str), + "Main/RefreshInterval": settings.value("Main/RefreshInterval", 50, type=int), + "Canvas/Theme": settings.value("Canvas/Theme", CANVAS_DEFAULT_THEME_NAME, type=str), + "Canvas/AutoHideGroups": settings.value("Canvas/AutoHideGroups", False, type=bool), + "Canvas/UseBezierLines": settings.value("Canvas/UseBezierLines", True, type=bool), + "Canvas/EyeCandy": settings.value("Canvas/EyeCandy", CANVAS_EYECANDY_SMALL, type=int), + "Canvas/UseOpenGL": settings.value("Canvas/UseOpenGL", False, type=bool), + "Canvas/Antialiasing": settings.value("Canvas/Antialiasing", CANVAS_ANTIALIASING_SMALL, type=int), + "Canvas/HighQualityAntialiasing": settings.value("Canvas/HighQualityAntialiasing", False, type=bool), + "UseCustomMiniCanvasPaint": useCustomMiniCanvasPaint + } + + # --------------------------------------------- + + if self.fIdleTimerFast != 0: + self.killTimer(self.fIdleTimerFast) + self.fIdleTimerFast = self.startTimer(self.fSavedSettings["Main/RefreshInterval"]) + + if self.fIdleTimerSlow != 0: + self.killTimer(self.fIdleTimerSlow) + self.fIdleTimerSlow = self.startTimer(self.fSavedSettings["Main/RefreshInterval"]*2) + + def saveSettings(self): settings = QSettings() + settings.setValue("Geometry", self.saveGeometry()) + #settings.setValue("SplitterState", self.ui.splitter.saveState()) + settings.setValue("ShowToolbar", self.ui.toolBar.isVisible()) + #settings.setValue("HorizontalScrollBarValue", self.ui.graphicsView.horizontalScrollBar().value()) + #settings.setValue("VerticalScrollBarValue", self.ui.graphicsView.verticalScrollBar().value()) + + #diskFolders = [] + + #for i in range(self.ui.cb_disk.count()): + #diskFolders.append(self.ui.cb_disk.itemData(i)) + + #settings.setValue("DiskFolders", diskFolders) + + self.fContainer.saveSettings(settings) + + # ----------------------------------------------------------------- + # Internal stuff (files) + + def loadProjectNow(self): + if not self.fProjectFilename: + return qCritical("ERROR: loading project without filename set") + + # TESTING + if not Carla.host.is_engine_running(): + self.slot_engineStart() + + self.fIsProjectLoading = True + Carla.host.load_project(self.fProjectFilename) + self.fIsProjectLoading = False + + @pyqtSlot() + def slot_loadProjectNow(self): + self.loadProjectNow() + + def loadProjectLater(self, filename): + self.fProjectFilename = filename + self.setProperWindowTitle() + QTimer.singleShot(0, self.slot_loadProjectNow) + + def saveProjectNow(self): + if not self.fProjectFilename: + return qCritical("ERROR: saving project without filename set") + + Carla.host.save_project(self.fProjectFilename) + + # ----------------------------------------------------------------- + # Internal stuff (engine) + + def setEngineSettings(self, settings = None): + if settings is None: settings = QSettings() + forceStereo = settings.value("Engine/ForceStereo", CARLA_DEFAULT_FORCE_STEREO, type=bool) preferPluginBridges = settings.value("Engine/PreferPluginBridges", CARLA_DEFAULT_PREFER_PLUGIN_BRIDGES, type=bool) preferUiBridges = settings.value("Engine/PreferUiBridges", CARLA_DEFAULT_PREFER_UI_BRIDGES, type=bool) @@ -278,8 +453,10 @@ class HostWindow(QMainWindow): Carla.host.set_engine_option(OPTION_MAX_PARAMETERS, Carla.maxParameters, "") Carla.host.set_engine_option(OPTION_TRANSPORT_MODE, transportMode, "") - # --------------------------------------------- - # Start + return audioDriver + + def startEngine(self): + audioDriver = self.setEngineSettings() if not Carla.host.engine_init(audioDriver, self.fClientName): #if self.fFirstEngineInit: @@ -300,11 +477,9 @@ class HostWindow(QMainWindow): #self.fFirstEngineInit = False # Peaks and TimeInfo - #self.fIdleTimerFast = self.startTimer(self.fSavedSettings["Main/RefreshInterval"]) + self.fIdleTimerFast = self.startTimer(self.fSavedSettings["Main/RefreshInterval"]) # LEDs and edit dialog parameters - #self.fIdleTimerSlow = self.startTimer(self.fSavedSettings["Main/RefreshInterval"]*2) - self.fIdleTimerFast = self.startTimer(50) - self.fIdleTimerSlow = self.startTimer(50*2) + self.fIdleTimerSlow = self.startTimer(self.fSavedSettings["Main/RefreshInterval"]*2) def stopEngine(self): if self.fContainer.getPluginCount() > 0: @@ -331,6 +506,9 @@ class HostWindow(QMainWindow): self.killTimer(self.fIdleTimerSlow) self.fIdleTimerSlow = 0 + # ----------------------------------------------------------------- + # Internal stuff (plugins) + def getExtraStuff(self, plugin): ptype = plugin['type'] @@ -379,6 +557,9 @@ class HostWindow(QMainWindow): def setLoadRDFsNeeded(self): self.fLadspaRdfNeedsUpdate = True + # ----------------------------------------------------------------- + # Internal stuff (transport) + def refreshTransport(self, forced = False): if not Carla.host.is_engine_running(): return @@ -422,10 +603,82 @@ class HostWindow(QMainWindow): self.ui.menu_Transport.setEnabled(enabled) # ----------------------------------------------------------------- + # Internal stuff (gui) + + def setProperWindowTitle(self): + title = self.fClientName + + if self.fProjectFilename: + title += " - %s" % os.path.basename(self.fProjectFilename) + if self.fSessionManagerName: + title += " (%s)" % self.fSessionManagerName + + self.setWindowTitle(title) + + # ----------------------------------------------------------------- + + @pyqtSlot() + def slot_fileNew(self): + self.fContainer.removeAllPlugins() + self.fProjectFilename = "" + self.setProperWindowTitle() @pyqtSlot() - def slot_engineStart(self): - self.startEngine() + def slot_fileOpen(self): + fileFilter = self.tr("Carla Project File (*.carxp)") + filenameTry = QFileDialog.getOpenFileName(self, self.tr("Open Carla Project File"), self.fSavedSettings["Main/DefaultProjectFolder"], filter=fileFilter)[0] + + if not filenameTry: + return + + newFile = True + + if self.fContainer.getPluginCount() > 0: + ask = QMessageBox.question(self, self.tr("Question"), self.tr("There are some plugins loaded, do you want to remove them now?"), + QMessageBox.Yes | QMessageBox.No, QMessageBox.No) + newFile = ask == QMessageBox.Yes + + if newFile: + self.fContainer.removeAllPlugins() + self.fProjectFilename = filenameTry + self.setProperWindowTitle() + self.loadProjectNow() + else: + filenameOld = self.fProjectFilename + self.fProjectFilename = filenameTry + self.loadProjectNow() + self.fProjectFilename = filenameOld + + @pyqtSlot() + def slot_fileSave(self, saveAs=False): + if self.fProjectFilename and not saveAs: + return self.saveProjectNow() + + fileFilter = self.tr("Carla Project File (*.carxp)") + filenameTry = QFileDialog.getSaveFileName(self, self.tr("Save Carla Project File"), self.fSavedSettings["Main/DefaultProjectFolder"], filter=fileFilter)[0] + + if not filenameTry: + return + + if not filenameTry.endswith(".carxp"): + filenameTry += ".carxp" + + if self.fProjectFilename != filenameTry: + self.fProjectFilename = filenameTry + self.setProperWindowTitle() + + self.saveProjectNow() + + @pyqtSlot() + def slot_fileSaveAs(self): + self.slot_fileSave(True) + + # ----------------------------------------------------------------- + + @pyqtSlot() + def slot_engineStart(self, doStart = True): + if doStart: self.startEngine() + check = Carla.host.is_engine_running() self.ui.act_file_save.setEnabled(check) self.ui.act_engine_start.setEnabled(not check) @@ -444,8 +697,9 @@ class HostWindow(QMainWindow): self.setTransportMenuEnabled(check) @pyqtSlot() - def slot_engineStop(self): - self.stopEngine() + def slot_engineStop(self, doStop = True): + if doStop: self.stopEngine() + check = Carla.host.is_engine_running() self.ui.act_file_save.setEnabled(check) self.ui.act_engine_start.setEnabled(not check) @@ -583,6 +837,39 @@ class HostWindow(QMainWindow): # ----------------------------------------------------------------- + @pyqtSlot(str) + def slot_handleEngineStartedCallback(self, driverName): + self.fBufferSize = Carla.host.get_buffer_size() + self.fSampleRate = Carla.host.get_sample_rate() + + if self.fIdleTimerFast == 0: + self.fIdleTimerFast = self.startTimer(self.fSavedSettings["Main/RefreshInterval"]) + if self.fIdleTimerSlow == 0: + self.fIdleTimerSlow = self.startTimer(self.fSavedSettings["Main/RefreshInterval"]*2) + + self.slot_engineStart(False) + + @pyqtSlot() + def slot_handleEngineStoppedCallback(self): + self.fBufferSize = 0 + self.fSampleRate = 0.0 + + if self.fIdleTimerFast != 0: + self.killTimer(self.fIdleTimerFast) + self.fIdleTimerFast = 0 + + if self.fIdleTimerSlow != 0: + self.killTimer(self.fIdleTimerSlow) + self.fIdleTimerSlow = 0 + + if self.fContainer.getPluginCount() > 0: + self.ui.act_plugin_remove_all.setEnabled(False) + self.fContainer.removeAllPlugins() # FIXME? + + self.slot_engineStop(False) + + # ----------------------------------------------------------------- + @pyqtSlot() def slot_handleSIGUSR1(self): print("Got SIGUSR1 -> Saving project now") @@ -615,7 +902,7 @@ class HostWindow(QMainWindow): self.killTimer(self.fIdleTimerSlow) self.fIdleTimerSlow = 0 - #self.saveSettings() + self.saveSettings() if Carla.host.is_engine_running(): Carla.host.set_engine_about_to_close() @@ -690,6 +977,12 @@ def EngineCallback(ptr, action, pluginId, value1, value2, value3, valueStr): Carla.gui.BufferSizeChangedCallback.emit(value1) elif action == CALLBACK_SAMPLE_RATE_CHANGED: Carla.gui.SampleRateChangedCallback.emit(value3) + elif action == CALLBACK_PROCESS_MODE_CHANGED: + Carla.gui.ProcessModeChangedCallback.emit(value1) + elif action == CALLBACK_ENGINE_STARTED: + Carla.gui.EngineStartedCallback.emit(cString(valueStr)) + elif action == CALLBACK_ENGINE_STOPPED: + Carla.gui.EngineStoppedChangedCallback.emit() elif action == CALLBACK_NSM_ANNOUNCE: Carla.gui.NSM_AnnounceCallback.emit(cString(valueStr)) elif action == CALLBACK_NSM_OPEN: diff --git a/source/carla_patchbay.py b/source/carla_patchbay.py index 014635897..b2061b613 100644 --- a/source/carla_patchbay.py +++ b/source/carla_patchbay.py @@ -228,6 +228,11 @@ class CarlaPatchbayW(QGraphicsView): # ----------------------------------------------------------------- + def saveSettings(self, settings): + pass + + # ----------------------------------------------------------------- + def recheckPluginHints(self, hints): pass diff --git a/source/carla_rack.py b/source/carla_rack.py index be545feb4..558442ca9 100644 --- a/source/carla_rack.py +++ b/source/carla_rack.py @@ -220,6 +220,11 @@ class CarlaRackW(QListWidget): # ----------------------------------------------------------------- + def saveSettings(self, settings): + pass + + # ----------------------------------------------------------------- + @pyqtSlot() def slot_pluginsEnable(self): if not Carla.host.is_engine_running(): diff --git a/source/carla_settings.py b/source/carla_settings.py index ed6d1a5a1..281e05c05 100644 --- a/source/carla_settings.py +++ b/source/carla_settings.py @@ -66,15 +66,18 @@ else: if LINUX: CARLA_DEFAULT_PROCESS_MODE = PROCESS_MODE_MULTIPLE_CLIENTS CARLA_DEFAULT_TRANSPORT_MODE = TRANSPORT_MODE_JACK + CARLA_DEFAULT_DISABLE_CHECKS = False else: CARLA_DEFAULT_PROCESS_MODE = PROCESS_MODE_CONTINUOUS_RACK CARLA_DEFAULT_TRANSPORT_MODE = TRANSPORT_MODE_INTERNAL + CARLA_DEFAULT_DISABLE_CHECKS = False # ------------------------------------------------------------------------------------------------------------ # PatchCanvas defines CANVAS_ANTIALIASING_SMALL = 1 CANVAS_EYECANDY_SMALL = 1 +CANVAS_DEFAULT_THEME_NAME = "Modern Dark" # ------------------------------------------------------------------------------------------------------------ # ... @@ -305,7 +308,7 @@ class CarlaSettingsW(QDialog): self.ui.ch_engine_uis_always_on_top.setChecked(settings.value("Engine/UIsAlwaysOnTop", CARLA_DEFAULT_UIS_ALWAYS_ON_TOP, type=bool)) self.ui.ch_engine_prefer_ui_bridges.setChecked(settings.value("Engine/PreferUiBridges", CARLA_DEFAULT_PREFER_UI_BRIDGES, type=bool)) #self.ui.sb_engine_oscgui_timeout.setValue(settings.value("Engine/OscUiTimeout", CARLA_DEFAULT_OSC_UI_TIMEOUT, type=int)) - #self.ui.ch_engine_disable_checks.setChecked(settings.value("Engine/DisableChecks", CARLA_DEFAULT_DISABLE_CHECKS, type=bool)) + self.ui.ch_engine_disable_checks.setChecked(settings.value("Engine/DisableChecks", CARLA_DEFAULT_DISABLE_CHECKS, type=bool)) self.ui.ch_engine_prefer_plugin_bridges.setChecked(settings.value("Engine/PreferPluginBridges", CARLA_DEFAULT_PREFER_PLUGIN_BRIDGES, type=bool)) self.ui.ch_engine_force_stereo.setChecked(settings.value("Engine/ForceStereo", CARLA_DEFAULT_FORCE_STEREO, type=bool)) @@ -660,7 +663,7 @@ if __name__ == '__main__': app.setOrganizationName("falkTX") app.setWindowIcon(QIcon(":/scalable/carla.svg")) - initHost(False) + initHost("Settings", None, False) gui = CarlaSettingsW(None, True, True) gui.show()