Browse Source

Favorite instruments

master
Nils 2 years ago
parent
commit
6d2acbe95f
  1. 7
      engine/config.py
  2. 4
      qtgui/chooseDownloadDirectory.py
  3. 65
      qtgui/designer/mainwindow.py
  4. 165
      qtgui/designer/mainwindow.ui
  5. 73
      qtgui/favorites.py
  6. 4
      qtgui/instrument.py
  7. 21
      qtgui/mainwindow.py

7
engine/config.py

@ -58,11 +58,8 @@ numbering system, midi controls etc.
Only "soft" settings, such as filters, can be changed dynamically and will be saved in your project. Only "soft" settings, such as filters, can be changed dynamically and will be saved in your project.
At the moment this software is in its ALPHA phase. You need to manually download instrument At the moment this software is in its ALPHA phase which means that samples libraries will still
files from https://laborejo.org/downloads/tembro-instruments/ . Do not unpack the .tar files! change.""",
Download them to a location of your choice set the sample file location from within Tembros Edit
menu. Then restart the program.
""",
"dependencies" : "\n".join("* "+dep for dep in ()), "dependencies" : "\n".join("* "+dep for dep in ()),
} }

4
qtgui/chooseDownloadDirectory.py

@ -222,8 +222,9 @@ class ChooseDownloadDirectory(QtWidgets.QDialog):
self.parentMainWindow.qtApp.processEvents() self.parentMainWindow.qtApp.processEvents()
indexUrl = "https://www.laborejo.org/downloads/tembro-instruments/downloadindex.json" indexUrl = "https://www.laborejo.org/downloads/tembro-instruments/downloadindex.json"
indexUrl = "http://0.0.0.0:8000/downloadindex.json" #indexUrl = "https://download.linuxaudio.org/musical-instrument-libraries/tembro/"
indexDL = SmartDL(indexUrl, progress_bar=False) # Because we didn't pass a destination path to the constructor, temporary path was chosen. indexDL = SmartDL(indexUrl, progress_bar=False) # Because we didn't pass a destination path to the constructor, temporary path was chosen.
try: try:
@ -280,7 +281,6 @@ class ChooseDownloadDirectory(QtWidgets.QDialog):
logger.info(f"Downloading {entry['name']}") logger.info(f"Downloading {entry['name']}")
obj = SmartDL(urlMirrorList, self.ui.pathComboBox.currentText(), progress_bar=False) obj = SmartDL(urlMirrorList, self.ui.pathComboBox.currentText(), progress_bar=False)
self.currentSmartDL = obj self.currentSmartDL = obj
#With Hash Verification it will not only test the download but also don't double-download an existing file. #With Hash Verification it will not only test the download but also don't double-download an existing file.

65
qtgui/designer/mainwindow.py

@ -35,6 +35,36 @@ class Ui_MainWindow(object):
self.verticalLayout = QtWidgets.QVBoxLayout(self.rightFrame) self.verticalLayout = QtWidgets.QVBoxLayout(self.rightFrame)
self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout") self.verticalLayout.setObjectName("verticalLayout")
self.auditionerWidget = QtWidgets.QWidget(self.rightFrame)
self.auditionerWidget.setObjectName("auditionerWidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.auditionerWidget)
self.horizontalLayout.setContentsMargins(9, 9, -1, 9)
self.horizontalLayout.setObjectName("horizontalLayout")
self.auditionerVolumeDial = QtWidgets.QDial(self.auditionerWidget)
self.auditionerVolumeDial.setMaximumSize(QtCore.QSize(32, 32))
self.auditionerVolumeDial.setSizeIncrement(QtCore.QSize(3, 0))
self.auditionerVolumeDial.setMinimum(-40)
self.auditionerVolumeDial.setMaximum(0)
self.auditionerVolumeDial.setPageStep(3)
self.auditionerVolumeDial.setProperty("value", -3)
self.auditionerVolumeDial.setWrapping(False)
self.auditionerVolumeDial.setNotchTarget(3.0)
self.auditionerVolumeDial.setNotchesVisible(True)
self.auditionerVolumeDial.setObjectName("auditionerVolumeDial")
self.horizontalLayout.addWidget(self.auditionerVolumeDial)
self.label = QtWidgets.QLabel(self.auditionerWidget)
self.label.setObjectName("label")
self.horizontalLayout.addWidget(self.label)
self.auditionerMidiInputComboBox = QtWidgets.QComboBox(self.auditionerWidget)
self.auditionerMidiInputComboBox.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToContents)
self.auditionerMidiInputComboBox.setObjectName("auditionerMidiInputComboBox")
self.horizontalLayout.addWidget(self.auditionerMidiInputComboBox)
self.auditionerCurrentInstrument_label = QtWidgets.QLabel(self.auditionerWidget)
self.auditionerCurrentInstrument_label.setObjectName("auditionerCurrentInstrument_label")
self.horizontalLayout.addWidget(self.auditionerCurrentInstrument_label)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem)
self.verticalLayout.addWidget(self.auditionerWidget)
self.splitter = QtWidgets.QSplitter(self.rightFrame) self.splitter = QtWidgets.QSplitter(self.rightFrame)
self.splitter.setOrientation(QtCore.Qt.Vertical) self.splitter.setOrientation(QtCore.Qt.Vertical)
self.splitter.setObjectName("splitter") self.splitter.setObjectName("splitter")
@ -77,7 +107,7 @@ class Ui_MainWindow(object):
self.details_scrollArea.setWidgetResizable(True) self.details_scrollArea.setWidgetResizable(True)
self.details_scrollArea.setObjectName("details_scrollArea") self.details_scrollArea.setObjectName("details_scrollArea")
self.scrollAreaWidgetContents = QtWidgets.QWidget() self.scrollAreaWidgetContents = QtWidgets.QWidget()
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 993, 106)) self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 993, 125))
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents") self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
self.formLayout = QtWidgets.QFormLayout(self.scrollAreaWidgetContents) self.formLayout = QtWidgets.QFormLayout(self.scrollAreaWidgetContents)
self.formLayout.setObjectName("formLayout") self.formLayout.setObjectName("formLayout")
@ -101,35 +131,6 @@ class Ui_MainWindow(object):
self.details_scrollArea.setWidget(self.scrollAreaWidgetContents) self.details_scrollArea.setWidget(self.scrollAreaWidgetContents)
self.verticalLayout_3.addWidget(self.details_scrollArea) self.verticalLayout_3.addWidget(self.details_scrollArea)
self.verticalLayout.addWidget(self.splitter) self.verticalLayout.addWidget(self.splitter)
self.auditionerWidget = QtWidgets.QWidget(self.rightFrame)
self.auditionerWidget.setObjectName("auditionerWidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.auditionerWidget)
self.horizontalLayout.setObjectName("horizontalLayout")
self.auditionerVolumeDial = QtWidgets.QDial(self.auditionerWidget)
self.auditionerVolumeDial.setMaximumSize(QtCore.QSize(32, 32))
self.auditionerVolumeDial.setSizeIncrement(QtCore.QSize(3, 0))
self.auditionerVolumeDial.setMinimum(-40)
self.auditionerVolumeDial.setMaximum(0)
self.auditionerVolumeDial.setPageStep(3)
self.auditionerVolumeDial.setProperty("value", -3)
self.auditionerVolumeDial.setWrapping(False)
self.auditionerVolumeDial.setNotchTarget(3.0)
self.auditionerVolumeDial.setNotchesVisible(True)
self.auditionerVolumeDial.setObjectName("auditionerVolumeDial")
self.horizontalLayout.addWidget(self.auditionerVolumeDial)
self.label = QtWidgets.QLabel(self.auditionerWidget)
self.label.setObjectName("label")
self.horizontalLayout.addWidget(self.label)
self.auditionerMidiInputComboBox = QtWidgets.QComboBox(self.auditionerWidget)
self.auditionerMidiInputComboBox.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToContents)
self.auditionerMidiInputComboBox.setObjectName("auditionerMidiInputComboBox")
self.horizontalLayout.addWidget(self.auditionerMidiInputComboBox)
self.auditionerCurrentInstrument_label = QtWidgets.QLabel(self.auditionerWidget)
self.auditionerCurrentInstrument_label.setObjectName("auditionerCurrentInstrument_label")
self.horizontalLayout.addWidget(self.auditionerCurrentInstrument_label)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem)
self.verticalLayout.addWidget(self.auditionerWidget)
self.horizontalPianoFrame = QtWidgets.QFrame(self.rightFrame) self.horizontalPianoFrame = QtWidgets.QFrame(self.rightFrame)
self.horizontalPianoFrame.setMinimumSize(QtCore.QSize(0, 100)) self.horizontalPianoFrame.setMinimumSize(QtCore.QSize(0, 100))
self.horizontalPianoFrame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.horizontalPianoFrame.setFrameShape(QtWidgets.QFrame.StyledPanel)
@ -155,6 +156,8 @@ class Ui_MainWindow(object):
def retranslateUi(self, MainWindow): def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate _translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label.setText(_translate("MainWindow", "Auditioner MIDI Input"))
self.auditionerCurrentInstrument_label.setText(_translate("MainWindow", "TextLabel"))
self.instruments_treeWidget.headerItem().setText(1, _translate("MainWindow", "ID")) self.instruments_treeWidget.headerItem().setText(1, _translate("MainWindow", "ID"))
self.instruments_treeWidget.headerItem().setText(2, _translate("MainWindow", "Volume")) self.instruments_treeWidget.headerItem().setText(2, _translate("MainWindow", "Volume"))
self.instruments_treeWidget.headerItem().setText(3, _translate("MainWindow", "Name")) self.instruments_treeWidget.headerItem().setText(3, _translate("MainWindow", "Name"))
@ -171,5 +174,3 @@ class Ui_MainWindow(object):
self.variant_label.setText(_translate("MainWindow", "Variants")) self.variant_label.setText(_translate("MainWindow", "Variants"))
self.info_label.setText(_translate("MainWindow", "TextLabel")) self.info_label.setText(_translate("MainWindow", "TextLabel"))
self.keySwitch_label.setText(_translate("MainWindow", "KeySwitch")) self.keySwitch_label.setText(_translate("MainWindow", "KeySwitch"))
self.label.setText(_translate("MainWindow", "Auditioner MIDI Input"))
self.auditionerCurrentInstrument_label.setText(_translate("MainWindow", "TextLabel"))

165
qtgui/designer/mainwindow.ui

@ -69,6 +69,92 @@
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item>
<widget class="QWidget" name="auditionerWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<item>
<widget class="QDial" name="auditionerVolumeDial">
<property name="maximumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>3</width>
<height>0</height>
</size>
</property>
<property name="minimum">
<number>-40</number>
</property>
<property name="maximum">
<number>0</number>
</property>
<property name="pageStep">
<number>3</number>
</property>
<property name="value">
<number>-3</number>
</property>
<property name="wrapping">
<bool>false</bool>
</property>
<property name="notchTarget">
<double>3.000000000000000</double>
</property>
<property name="notchesVisible">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Auditioner MIDI Input</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="auditionerMidiInputComboBox">
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="auditionerCurrentInstrument_label">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item> <item>
<widget class="QSplitter" name="splitter"> <widget class="QSplitter" name="splitter">
<property name="orientation"> <property name="orientation">
@ -243,7 +329,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>993</width> <width>993</width>
<height>106</height> <height>125</height>
</rect> </rect>
</property> </property>
<layout class="QFormLayout" name="formLayout"> <layout class="QFormLayout" name="formLayout">
@ -288,83 +374,6 @@
</widget> </widget>
</widget> </widget>
</item> </item>
<item>
<widget class="QWidget" name="auditionerWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QDial" name="auditionerVolumeDial">
<property name="maximumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="sizeIncrement">
<size>
<width>3</width>
<height>0</height>
</size>
</property>
<property name="minimum">
<number>-40</number>
</property>
<property name="maximum">
<number>0</number>
</property>
<property name="pageStep">
<number>3</number>
</property>
<property name="value">
<number>-3</number>
</property>
<property name="wrapping">
<bool>false</bool>
</property>
<property name="notchTarget">
<double>3.000000000000000</double>
</property>
<property name="notchesVisible">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Auditioner MIDI Input</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="auditionerMidiInputComboBox">
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="auditionerCurrentInstrument_label">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item> <item>
<widget class="QFrame" name="horizontalPianoFrame"> <widget class="QFrame" name="horizontalPianoFrame">
<property name="minimumSize"> <property name="minimumSize">

73
qtgui/favorites.py

@ -22,26 +22,81 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging; logger = logging.getLogger(__name__); logger.info("import") import logging; logger = logging.getLogger(__name__); logger.info("import")
#Standard Library #Standard Library
from collections import Counter
#Third Party #Third Party
from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5 import QtCore, QtGui, QtWidgets
#Our Qt #Our Qt
from .instrument import InstrumentTreeController from .instrument import InstrumentTreeController, GuiLibrary, GuiInstrument
#Engine #Engine
from engine.config import * #imports METADATA
import engine.api as api import engine.api as api
class FavoritesTreeController(InstrumentTreeController):
pass
fakeLibMostUsed = {}
fakeLibMostUsed["tarFilePath"] = ""
fakeLibMostUsed["id"] = 0 #If this is selected in the GUI it will select the default lib in the main instrument view, which is wrong but safe.
fakeLibMostUsed["name"] = QtCore.QCoreApplication.translate("Favorites", "Top 10 - Most Used")
fakeLibMostUsed["description"] = ""
fakeLibMostUsed["license"] = ""
fakeLibMostUsed["vendor"] = ""
fakeLibMostUsed["version"] = "1"
#Most Loaded
#Most Recent
#Manuelle Favoriten?
class FavoritesTreeController(InstrumentTreeController):
#Selection an den anderen weitergeben.+++++ def buildTree(self, data:dict):
"""
Only shows some of the instruments,
depending on the current filter-mode
"""
#Reset everything except our cached data.
self.treeWidget.clear() #will delete the C++ objects. We need to delete the PyQt objects ourselves, like so:
self.guiLibraries = {} # idKey : GuiLibrary idKey is a tuple with second value -1, which would be the instrument.
self.guiInstruments = {} # idKey : GuiInstrument
if data:
self._cachedData = data
else:
assert self._cachedData
data = self._cachedData
#Add all available instruments to the database, but don't use them yet
for libraryId, libraryDict in data.items():
for instrumentdId, instrumentDict in libraryDict.items():
if instrumentdId == "library":
continue
gi = GuiInstrument(parentTreeController=self, instrumentDict=instrumentDict)
self.guiInstruments[instrumentDict["idKey"]] = gi
if instrumentDict["idKey"] in self._cachedLastInstrumentStatus:
gi.updateStatus(self._cachedLastInstrumentStatus[instrumentDict["idKey"]])
mostUsed = GuiLibrary(parentTreeController=self, libraryDict=fakeLibMostUsed)
self.treeWidget.addTopLevelItem(mostUsed)
mostUsed.setExpanded(True)
#mostRecent = GuiLibrary(parentTreeController=self, libraryDict=libraryDict["library"])
top10 = self.getTop10FavoriteInstruments() # Return an ordered list of double tuple ((libid, instid), counter)
for placement, ((libId, instId), counter) in enumerate(top10):
gi = self.guiInstruments[(libId, instId)]
mostUsed.addChild(gi)
gi.injectWidgets() #only possible after gi.init() was done and item inserted.
#Misuse the id as top 10-Counter
gi.setData(gi.columns.index("idKey"), 0, str(placement+1).zfill(2)) #0 is the data role, just standard display text. We combine both IDs to a float number for sorting. If used with setData instead of setText Qt will know how to sort 11 before 1000
self._adjustColumnSize()
def getTop10FavoriteInstruments(self)->list:
"""Return an ordered list of double tuple ((libid, instid), counter)"""
settings = QtCore.QSettings("LaborejoSoftwareSuite", METADATA["shortName"])
if settings.contains("favoriteInstruments"):
database = settings.value("favoriteInstruments", type=dict)
return Counter(database).most_common(10) #python already knows how to create that
else:
return []

4
qtgui/instrument.py

@ -417,11 +417,7 @@ class GuiInstrument(QtWidgets.QTreeWidgetItem):
for the details view. for the details view.
""" """
allItems = {} # instrId : GuiInstrument
def __init__(self, parentTreeController, instrumentDict): def __init__(self, parentTreeController, instrumentDict):
GuiInstrument.allItems[instrumentDict["idKey"]] = self
self.parentTreeController = parentTreeController self.parentTreeController = parentTreeController
self.idKey = instrumentDict["idKey"] self.idKey = instrumentDict["idKey"]

21
qtgui/mainwindow.py

@ -23,7 +23,7 @@ import logging; logging.info("import {}".format(__file__))
#Standard Library Modules #Standard Library Modules
import pathlib import pathlib
import os import os
from collections import Counter
#Third Party Modules #Third Party Modules
from PyQt5 import QtWidgets, QtCore, QtGui from PyQt5 import QtWidgets, QtCore, QtGui
@ -180,6 +180,10 @@ class MainWindow(TemplateMainWindow):
self.menu.addMenuEntry("menuEdit", "actionSampleDirPathDialog", "Sample Files Location", lambda: ChooseDownloadDirectory(parentMainWindow=self)) self.menu.addMenuEntry("menuEdit", "actionSampleDirPathDialog", "Sample Files Location", lambda: ChooseDownloadDirectory(parentMainWindow=self))
self.menu.addMenuEntry("menuEdit", "actionLoadSamples", QtCore.QCoreApplication.translate("Menu", "Load all Instrument Samples (slow!)"), api.loadAllInstrumentSamples) self.menu.addMenuEntry("menuEdit", "actionLoadSamples", QtCore.QCoreApplication.translate("Menu", "Load all Instrument Samples (slow!)"), api.loadAllInstrumentSamples)
self.menu.addMenuEntry("menuEdit", "actionUnloadSamples", QtCore.QCoreApplication.translate("Menu", "Unload all Instrument Samples (also slow.)"), api.unloadAllInstrumentSamples) self.menu.addMenuEntry("menuEdit", "actionUnloadSamples", QtCore.QCoreApplication.translate("Menu", "Unload all Instrument Samples (also slow.)"), api.unloadAllInstrumentSamples)
self.menu.addSeparator("menuEdit")
self.menu.addMenuEntry("menuEdit", "actionResetFavoriteInstrumentDatabase", QtCore.QCoreApplication.translate("Menu", "Reset favorite instrument list"), self.resetFavoriteInstrumentDatabase)
#self.menu.connectMenuEntry("actionNils", lambda: print("Override")) #self.menu.connectMenuEntry("actionNils", lambda: print("Override"))
self.menu.addSubmenu("menuView", QtCore.QCoreApplication.translate("Menu", "View")) self.menu.addSubmenu("menuView", QtCore.QCoreApplication.translate("Menu", "View"))
@ -287,7 +291,7 @@ class MainWindow(TemplateMainWindow):
def favoriteInstrument(self, idKey:tuple): def favoriteInstrument(self, idKey:tuple):
"""Count the user-instructed, explicit loading of an instrument in the permanent database. """Count the user-instructed, explicit loading of an instrument in the permanent database.
We work directly with the qt settings without local data. A crash or sigkill will not We work directly with the qt settings without local data. A crash or sigkill will not
prevent the counting.""" reset the counting."""
settings = QtCore.QSettings("LaborejoSoftwareSuite", METADATA["shortName"]) settings = QtCore.QSettings("LaborejoSoftwareSuite", METADATA["shortName"])
if settings.contains("favoriteInstruments"): if settings.contains("favoriteInstruments"):
database = settings.value("favoriteInstruments", type=dict) database = settings.value("favoriteInstruments", type=dict)
@ -302,17 +306,12 @@ class MainWindow(TemplateMainWindow):
settings.setValue("favoriteInstruments", database) settings.setValue("favoriteInstruments", database)
self.favoritesTreeController.buildTree(data=None) #rebuild from cache
def resetFavoriteInstrumentDatabase(self): def resetFavoriteInstrumentDatabase(self):
settings = QtCore.QSettings("LaborejoSoftwareSuite", METADATA["shortName"]) settings = QtCore.QSettings("LaborejoSoftwareSuite", METADATA["shortName"])
if settings.contains("favoriteInstruments"): if settings.contains("favoriteInstruments"):
settings.remove("favoriteInstruments") settings.remove("favoriteInstruments")
self.favoriteInstrumentsThisRun = set() self.favoriteInstrumentsThisRun = set()
self.favoritesTreeController.buildTree(data=None) #rebuild from cache
def getTop10FavoriteInstruments(self)->list:
"""Return an ordered list of double tuple ((libid, instid), counter) """
settings = QtCore.QSettings("LaborejoSoftwareSuite", METADATA["shortName"])
if settings.contains("favoriteInstruments"):
database = settings.value("favoriteInstruments", type=dict)
return Counter(database).most_common(10) #python already knows how to create that
else:
return []

Loading…
Cancel
Save